l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem cylinder_eq_empty_iff [h_nonempty : Nonempty (∀ i, α i)] (s : Finset ι)
    (S : Set (∀ i : s, α i)) :
    cylinder s S = ∅ ↔ S = ∅ := by
  refine ⟨fun h ↦ ?_, fun h ↦ by (rw [h]; exact cylinder_empty _)⟩
  by_contra hS
  rw [← Ne.def, ← nonempty_iff_ne_empty] at hS
  let f := hS.some
  have hf : f ∈ S := hS.choose_spec
  classical
  let f' : ∀ i, α i := fun i ↦ if hi : i ∈ s then f ⟨i, hi⟩ else h_nonempty.some i
  have hf' : f' ∈ cylinder s S := by
    

Proof state:
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
s : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
h : cylinder s S = ∅
hS : Set.Nonempty S
f : (i : { x // x ∈ s }) → α ↑i := Set.Nonempty.some hS
hf : f ∈ S
f' : (i : ι) → α i := fun i => if hi : i ∈ s then f { val := i, property := hi } else Nonempty.some h_nonempty i
⊢ f' ∈ cylinder s S

Next tactic:
rw [mem_cylinder]
@[simp]
theorem cylinder_eq_empty_iff [h_nonempty : Nonempty (∀ i, α i)] (s : Finset ι)
    (S : Set (∀ i : s, α i)) :
    cylinder s S = ∅ ↔ S = ∅ := by
  refine ⟨fun h ↦ ?_, fun h ↦ by (rw [h]; exact cylinder_empty _)⟩
  by_contra hS
  rw [← Ne.def, ← nonempty_iff_ne_empty] at hS
  let f := hS.some
  have hf : f ∈ S := hS.choose_spec
  classical
  let f' : ∀ i, α i := fun i ↦ if hi : i ∈ s then f ⟨i, hi⟩ else h_nonempty.some i
  have hf' : f' ∈ cylinder s S := by
    rw [mem_cylinder]
    

Proof state:
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
s : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
h : cylinder s S = ∅
hS : Set.Nonempty S
f : (i : { x // x ∈ s }) → α ↑i := Set.Nonempty.some hS
hf : f ∈ S
f' : (i : ι) → α i := fun i => if hi : i ∈ s then f { val := i, property := hi } else Nonempty.some h_nonempty i
⊢ (fun i => f' ↑i) ∈ S

Next tactic:
simpa only [Finset.coe_mem, dif_pos]
@[simp]
theorem cylinder_eq_empty_iff [h_nonempty : Nonempty (∀ i, α i)] (s : Finset ι)
    (S : Set (∀ i : s, α i)) :
    cylinder s S = ∅ ↔ S = ∅ := by
  refine ⟨fun h ↦ ?_, fun h ↦ by (rw [h]; exact cylinder_empty _)⟩
  by_contra hS
  rw [← Ne.def, ← nonempty_iff_ne_empty] at hS
  let f := hS.some
  have hf : f ∈ S := hS.choose_spec
  classical
  let f' : ∀ i, α i := fun i ↦ if hi : i ∈ s then f ⟨i, hi⟩ else h_nonempty.some i
  have hf' : f' ∈ cylinder s S := by
    rw [mem_cylinder]
    simpa only [Finset.coe_mem, dif_pos]
  

Proof state:
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
s : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
h : cylinder s S = ∅
hS : Set.Nonempty S
f : (i : { x // x ∈ s }) → α ↑i := Set.Nonempty.some hS
hf : f ∈ S
f' : (i : ι) → α i := fun i => if hi : i ∈ s then f { val := i, property := hi } else Nonempty.some h_nonempty i
hf' : f' ∈ cylinder s S
⊢ False

Next tactic:
rw [h] at hf'
@[simp]
theorem cylinder_eq_empty_iff [h_nonempty : Nonempty (∀ i, α i)] (s : Finset ι)
    (S : Set (∀ i : s, α i)) :
    cylinder s S = ∅ ↔ S = ∅ := by
  refine ⟨fun h ↦ ?_, fun h ↦ by (rw [h]; exact cylinder_empty _)⟩
  by_contra hS
  rw [← Ne.def, ← nonempty_iff_ne_empty] at hS
  let f := hS.some
  have hf : f ∈ S := hS.choose_spec
  classical
  let f' : ∀ i, α i := fun i ↦ if hi : i ∈ s then f ⟨i, hi⟩ else h_nonempty.some i
  have hf' : f' ∈ cylinder s S := by
    rw [mem_cylinder]
    simpa only [Finset.coe_mem, dif_pos]
  rw [h] at hf'
  

Proof state:
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
s : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
h : cylinder s S = ∅
hS : Set.Nonempty S
f : (i : { x // x ∈ s }) → α ↑i := Set.Nonempty.some hS
hf : f ∈ S
f' : (i : ι) → α i := fun i => if hi : i ∈ s then f { val := i, property := hi } else Nonempty.some h_nonempty i
hf' : f' ∈ ∅
⊢ False

Next tactic:
exact not_mem_empty _ hf'
theorem inter_cylinder (s₁ s₂ : Finset ι) (S₁ : Set (∀ i : s₁, α i)) (S₂ : Set (∀ i : s₂, α i))
    [DecidableEq ι] :
    cylinder s₁ S₁ ∩ cylinder s₂ S₂ =
      cylinder (s₁ ∪ s₂)
        ((fun f ↦ fun j : s₁ ↦ f ⟨j, Finset.mem_union_left s₂ j.prop⟩) ⁻¹' S₁ ∩
          (fun f ↦ fun j : s₂ ↦ f ⟨j, Finset.mem_union_right s₁ j.prop⟩) ⁻¹' S₂) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
s₁ s₂ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
inst✝ : DecidableEq ι
⊢ cylinder s₁ S₁ ∩ cylinder s₂ S₂ =
    cylinder (s₁ ∪ s₂)
      ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₁ ∩
        (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₂)

Next tactic:
ext1 f
theorem inter_cylinder (s₁ s₂ : Finset ι) (S₁ : Set (∀ i : s₁, α i)) (S₂ : Set (∀ i : s₂, α i))
    [DecidableEq ι] :
    cylinder s₁ S₁ ∩ cylinder s₂ S₂ =
      cylinder (s₁ ∪ s₂)
        ((fun f ↦ fun j : s₁ ↦ f ⟨j, Finset.mem_union_left s₂ j.prop⟩) ⁻¹' S₁ ∩
          (fun f ↦ fun j : s₂ ↦ f ⟨j, Finset.mem_union_right s₁ j.prop⟩) ⁻¹' S₂) := by
  ext1 f; 

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
s₁ s₂ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
inst✝ : DecidableEq ι
f : (i : ι) → α i
⊢ f ∈ cylinder s₁ S₁ ∩ cylinder s₂ S₂ ↔
    f ∈
      cylinder (s₁ ∪ s₂)
        ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₁ ∩
          (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₂)

Next tactic:
simp only [mem_inter_iff, mem_cylinder, mem_setOf_eq]
theorem inter_cylinder (s₁ s₂ : Finset ι) (S₁ : Set (∀ i : s₁, α i)) (S₂ : Set (∀ i : s₂, α i))
    [DecidableEq ι] :
    cylinder s₁ S₁ ∩ cylinder s₂ S₂ =
      cylinder (s₁ ∪ s₂)
        ((fun f ↦ fun j : s₁ ↦ f ⟨j, Finset.mem_union_left s₂ j.prop⟩) ⁻¹' S₁ ∩
          (fun f ↦ fun j : s₂ ↦ f ⟨j, Finset.mem_union_right s₁ j.prop⟩) ⁻¹' S₂) := by
  ext1 f; simp only [mem_inter_iff, mem_cylinder, mem_setOf_eq]; 

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
s₁ s₂ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
inst✝ : DecidableEq ι
f : (i : ι) → α i
⊢ (fun i => f ↑i) ∈ S₁ ∧ (fun i => f ↑i) ∈ S₂ ↔
    (fun i => f ↑i) ∈ (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₁ ∧
      (fun i => f ↑i) ∈ (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₂

Next tactic:
rfl
theorem inter_cylinder_same (s : Finset ι) (S₁ : Set (∀ i : s, α i)) (S₂ : Set (∀ i : s, α i))
    [DecidableEq ι] :
    cylinder s S₁ ∩ cylinder s S₂ = cylinder s (S₁ ∩ S₂) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
s : Finset ι
S₁ S₂ : Set ((i : { x // x ∈ s }) → α ↑i)
inst✝ : DecidableEq ι
⊢ cylinder s S₁ ∩ cylinder s S₂ = cylinder s (S₁ ∩ S₂)

Next tactic:
rw [inter_cylinder]
theorem inter_cylinder_same (s : Finset ι) (S₁ : Set (∀ i : s, α i)) (S₂ : Set (∀ i : s, α i))
    [DecidableEq ι] :
    cylinder s S₁ ∩ cylinder s S₂ = cylinder s (S₁ ∩ S₂) := by
  rw [inter_cylinder]; 

Proof state:
ι : Type u_1
α : ι → Type u_2
s : Finset ι
S₁ S₂ : Set ((i : { x // x ∈ s }) → α ↑i)
inst✝ : DecidableEq ι
⊢ cylinder (s ∪ s)
      ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ s ∪ s) }) ⁻¹' S₁ ∩
        (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s ∪ s) }) ⁻¹' S₂) =
    cylinder s (S₁ ∩ S₂)

Next tactic:
rfl
theorem union_cylinder (s₁ s₂ : Finset ι) (S₁ : Set (∀ i : s₁, α i)) (S₂ : Set (∀ i : s₂, α i))
    [DecidableEq ι] :
    cylinder s₁ S₁ ∪ cylinder s₂ S₂ =
      cylinder (s₁ ∪ s₂)
        ((fun f ↦ fun j : s₁ ↦ f ⟨j, Finset.mem_union_left s₂ j.prop⟩) ⁻¹' S₁ ∪
          (fun f ↦ fun j : s₂ ↦ f ⟨j, Finset.mem_union_right s₁ j.prop⟩) ⁻¹' S₂) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
s₁ s₂ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
inst✝ : DecidableEq ι
⊢ cylinder s₁ S₁ ∪ cylinder s₂ S₂ =
    cylinder (s₁ ∪ s₂)
      ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₁ ∪
        (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₂)

Next tactic:
ext1 f
theorem union_cylinder (s₁ s₂ : Finset ι) (S₁ : Set (∀ i : s₁, α i)) (S₂ : Set (∀ i : s₂, α i))
    [DecidableEq ι] :
    cylinder s₁ S₁ ∪ cylinder s₂ S₂ =
      cylinder (s₁ ∪ s₂)
        ((fun f ↦ fun j : s₁ ↦ f ⟨j, Finset.mem_union_left s₂ j.prop⟩) ⁻¹' S₁ ∪
          (fun f ↦ fun j : s₂ ↦ f ⟨j, Finset.mem_union_right s₁ j.prop⟩) ⁻¹' S₂) := by
  ext1 f; 

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
s₁ s₂ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
inst✝ : DecidableEq ι
f : (i : ι) → α i
⊢ f ∈ cylinder s₁ S₁ ∪ cylinder s₂ S₂ ↔
    f ∈
      cylinder (s₁ ∪ s₂)
        ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₁ ∪
          (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₂)

Next tactic:
simp only [mem_union, mem_cylinder, mem_setOf_eq]
theorem union_cylinder (s₁ s₂ : Finset ι) (S₁ : Set (∀ i : s₁, α i)) (S₂ : Set (∀ i : s₂, α i))
    [DecidableEq ι] :
    cylinder s₁ S₁ ∪ cylinder s₂ S₂ =
      cylinder (s₁ ∪ s₂)
        ((fun f ↦ fun j : s₁ ↦ f ⟨j, Finset.mem_union_left s₂ j.prop⟩) ⁻¹' S₁ ∪
          (fun f ↦ fun j : s₂ ↦ f ⟨j, Finset.mem_union_right s₁ j.prop⟩) ⁻¹' S₂) := by
  ext1 f; simp only [mem_union, mem_cylinder, mem_setOf_eq]; 

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
s₁ s₂ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
inst✝ : DecidableEq ι
f : (i : ι) → α i
⊢ (fun i => f ↑i) ∈ S₁ ∨ (fun i => f ↑i) ∈ S₂ ↔
    (fun i => f ↑i) ∈ (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₁ ∨
      (fun i => f ↑i) ∈ (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s₁ ∪ s₂) }) ⁻¹' S₂

Next tactic:
rfl
theorem union_cylinder_same (s : Finset ι) (S₁ : Set (∀ i : s, α i)) (S₂ : Set (∀ i : s, α i))
    [DecidableEq ι] :
    cylinder s S₁ ∪ cylinder s S₂ = cylinder s (S₁ ∪ S₂) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
s : Finset ι
S₁ S₂ : Set ((i : { x // x ∈ s }) → α ↑i)
inst✝ : DecidableEq ι
⊢ cylinder s S₁ ∪ cylinder s S₂ = cylinder s (S₁ ∪ S₂)

Next tactic:
rw [union_cylinder]
theorem union_cylinder_same (s : Finset ι) (S₁ : Set (∀ i : s, α i)) (S₂ : Set (∀ i : s, α i))
    [DecidableEq ι] :
    cylinder s S₁ ∪ cylinder s S₂ = cylinder s (S₁ ∪ S₂) := by
  rw [union_cylinder]; 

Proof state:
ι : Type u_1
α : ι → Type u_2
s : Finset ι
S₁ S₂ : Set ((i : { x // x ∈ s }) → α ↑i)
inst✝ : DecidableEq ι
⊢ cylinder (s ∪ s)
      ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ s ∪ s) }) ⁻¹' S₁ ∪
        (fun f j => f { val := ↑j, property := (_ : ↑j ∈ s ∪ s) }) ⁻¹' S₂) =
    cylinder s (S₁ ∪ S₂)

Next tactic:
rfl
theorem compl_cylinder (s : Finset ι) (S : Set (∀ i : s, α i)) :
    (cylinder s S)ᶜ = cylinder s (Sᶜ) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
s : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
⊢ (cylinder s S)ᶜ = cylinder s Sᶜ

Next tactic:
ext1 f
theorem compl_cylinder (s : Finset ι) (S : Set (∀ i : s, α i)) :
    (cylinder s S)ᶜ = cylinder s (Sᶜ) := by
  ext1 f; 

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
s : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
f : (i : ι) → α i
⊢ f ∈ (cylinder s S)ᶜ ↔ f ∈ cylinder s Sᶜ

Next tactic:
simp only [mem_compl_iff, mem_cylinder]
theorem diff_cylinder_same (s : Finset ι) (S T : Set (∀ i : s, α i)) :
    cylinder s S \ cylinder s T = cylinder s (S \ T) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
s : Finset ι
S T : Set ((i : { x // x ∈ s }) → α ↑i)
⊢ cylinder s S \ cylinder s T = cylinder s (S \ T)

Next tactic:
ext1 f
theorem diff_cylinder_same (s : Finset ι) (S T : Set (∀ i : s, α i)) :
    cylinder s S \ cylinder s T = cylinder s (S \ T) := by
  ext1 f; 

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
s : Finset ι
S T : Set ((i : { x // x ∈ s }) → α ↑i)
f : (i : ι) → α i
⊢ f ∈ cylinder s S \ cylinder s T ↔ f ∈ cylinder s (S \ T)

Next tactic:
simp only [mem_diff, mem_cylinder]
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
h_eq : cylinder I S = cylinder J T
hJI : J ⊆ I
⊢ S = (fun f j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ⁻¹' T

Next tactic:
rw [Set.ext_iff] at h_eq
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  rw [Set.ext_iff] at h_eq
  

Proof state:
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
h_eq : ∀ (x : (i : ι) → α i), x ∈ cylinder I S ↔ x ∈ cylinder J T
hJI : J ⊆ I
⊢ S = (fun f j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ⁻¹' T

Next tactic:
simp only [mem_cylinder] at h_eq
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  rw [Set.ext_iff] at h_eq
  simp only [mem_cylinder] at h_eq
  

Proof state:
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
hJI : J ⊆ I
h_eq : ∀ (x : (i : ι) → α i), (fun i => x ↑i) ∈ S ↔ (fun i => x ↑i) ∈ T
⊢ S = (fun f j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ⁻¹' T

Next tactic:
ext1 f
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  rw [Set.ext_iff] at h_eq
  simp only [mem_cylinder] at h_eq
  ext1 f
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
hJI : J ⊆ I
h_eq : ∀ (x : (i : ι) → α i), (fun i => x ↑i) ∈ S ↔ (fun i => x ↑i) ∈ T
f : (i : { x // x ∈ I }) → α ↑i
⊢ f ∈ S ↔ f ∈ (fun f j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ⁻¹' T

Next tactic:
simp only [mem_preimage]
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  rw [Set.ext_iff] at h_eq
  simp only [mem_cylinder] at h_eq
  ext1 f
  simp only [mem_preimage]
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
hJI : J ⊆ I
h_eq : ∀ (x : (i : ι) → α i), (fun i => x ↑i) ∈ S ↔ (fun i => x ↑i) ∈ T
f : (i : { x // x ∈ I }) → α ↑i
⊢ f ∈ S ↔ (fun j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ∈ T

Next tactic:
classical
  specialize h_eq fun i ↦ if hi : i ∈ I then f ⟨i, hi⟩ else h_nonempty.some i
  have h_mem : ∀ j : J, ↑j ∈ I := fun j ↦ hJI j.prop
  simp only [Finset.coe_mem, dite_true, h_mem] at h_eq
  exact h_eq
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  rw [Set.ext_iff] at h_eq
  simp only [mem_cylinder] at h_eq
  ext1 f
  simp only [mem_preimage]
  classical
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
hJI : J ⊆ I
h_eq : ∀ (x : (i : ι) → α i), (fun i => x ↑i) ∈ S ↔ (fun i => x ↑i) ∈ T
f : (i : { x // x ∈ I }) → α ↑i
⊢ f ∈ S ↔ (fun j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ∈ T

Next tactic:
specialize h_eq fun i ↦ if hi : i ∈ I then f ⟨i, hi⟩ else h_nonempty.some i
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  rw [Set.ext_iff] at h_eq
  simp only [mem_cylinder] at h_eq
  ext1 f
  simp only [mem_preimage]
  classical
  specialize h_eq fun i ↦ if hi : i ∈ I then f ⟨i, hi⟩ else h_nonempty.some i
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
hJI : J ⊆ I
f : (i : { x // x ∈ I }) → α ↑i
h_eq :
  (fun i => if hi : ↑i ∈ I then f { val := ↑i, property := hi } else Nonempty.some h_nonempty ↑i) ∈ S ↔
    (fun i => if hi : ↑i ∈ I then f { val := ↑i, property := hi } else Nonempty.some h_nonempty ↑i) ∈ T
⊢ f ∈ S ↔ (fun j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ∈ T

Next tactic:
have h_mem : ∀ j : J, ↑j ∈ I := fun j ↦ hJI j.prop
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  rw [Set.ext_iff] at h_eq
  simp only [mem_cylinder] at h_eq
  ext1 f
  simp only [mem_preimage]
  classical
  specialize h_eq fun i ↦ if hi : i ∈ I then f ⟨i, hi⟩ else h_nonempty.some i
  have h_mem : ∀ j : J, ↑j ∈ I := fun j ↦ hJI j.prop
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
hJI : J ⊆ I
f : (i : { x // x ∈ I }) → α ↑i
h_eq :
  (fun i => if hi : ↑i ∈ I then f { val := ↑i, property := hi } else Nonempty.some h_nonempty ↑i) ∈ S ↔
    (fun i => if hi : ↑i ∈ I then f { val := ↑i, property := hi } else Nonempty.some h_nonempty ↑i) ∈ T
h_mem : ∀ (j : { x // x ∈ J }), ↑j ∈ I
⊢ f ∈ S ↔ (fun j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ∈ T

Next tactic:
simp only [Finset.coe_mem, dite_true, h_mem] at h_eq
theorem eq_of_cylinder_eq_of_subset [h_nonempty : Nonempty (∀ i, α i)] {I J : Finset ι}
    {S : Set (∀ i : I, α i)} {T : Set (∀ i : J, α i)} (h_eq : cylinder I S = cylinder J T)
    (hJI : J ⊆ I) :
    S = (fun f : ∀ i : I, α i ↦ fun j : J ↦ f ⟨j, hJI j.prop⟩) ⁻¹' T := by
  rw [Set.ext_iff] at h_eq
  simp only [mem_cylinder] at h_eq
  ext1 f
  simp only [mem_preimage]
  classical
  specialize h_eq fun i ↦ if hi : i ∈ I then f ⟨i, hi⟩ else h_nonempty.some i
  have h_mem : ∀ j : J, ↑j ∈ I := fun j ↦ hJI j.prop
  simp only [Finset.coe_mem, dite_true, h_mem] at h_eq
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
h_nonempty : Nonempty ((i : ι) → α i)
I J : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
T : Set ((i : { x // x ∈ J }) → α ↑i)
hJI : J ⊆ I
f : (i : { x // x ∈ I }) → α ↑i
h_mem : ∀ (j : { x // x ∈ J }), ↑j ∈ I
h_eq :
  (fun i => f { val := ↑i, property := (_ : ↑i ∈ I) }) ∈ S ↔ (fun i => f { val := ↑i, property := (_ : ↑i ∈ I) }) ∈ T
⊢ f ∈ S ↔ (fun j => f { val := ↑j, property := (_ : ↑j ∈ I) }) ∈ T

Next tactic:
exact h_eq
theorem cylinder_eq_cylinder_union [DecidableEq ι] (I : Finset ι) (S : Set (∀ i : I, α i))
    (J : Finset ι) :
    cylinder I S =
      cylinder (I ∪ J) ((fun f ↦ fun j : I ↦ f ⟨j, Finset.mem_union_left J j.prop⟩) ⁻¹' S) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : DecidableEq ι
I : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
J : Finset ι
⊢ cylinder I S = cylinder (I ∪ J) ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ I ∪ J) }) ⁻¹' S)

Next tactic:
ext1 f
theorem cylinder_eq_cylinder_union [DecidableEq ι] (I : Finset ι) (S : Set (∀ i : I, α i))
    (J : Finset ι) :
    cylinder I S =
      cylinder (I ∪ J) ((fun f ↦ fun j : I ↦ f ⟨j, Finset.mem_union_left J j.prop⟩) ⁻¹' S) := by
  ext1 f; 

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
inst✝ : DecidableEq ι
I : Finset ι
S : Set ((i : { x // x ∈ I }) → α ↑i)
J : Finset ι
f : (i : ι) → α i
⊢ f ∈ cylinder I S ↔ f ∈ cylinder (I ∪ J) ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ I ∪ J) }) ⁻¹' S)

Next tactic:
simp only [mem_cylinder, mem_preimage]
theorem disjoint_cylinder_iff [Nonempty (∀ i, α i)] {s t : Finset ι} {S : Set (∀ i : s, α i)}
    {T : Set (∀ i : t, α i)} [DecidableEq ι] :
    Disjoint (cylinder s S) (cylinder t T) ↔
      Disjoint
        ((fun f : ∀ i : (s ∪ t : Finset ι), α i
          ↦ fun j : s ↦ f ⟨j, Finset.mem_union_left t j.prop⟩) ⁻¹' S)
        ((fun f ↦ fun j : t ↦ f ⟨j, Finset.mem_union_right s j.prop⟩) ⁻¹' T) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝¹ : Nonempty ((i : ι) → α i)
s t : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
T : Set ((i : { x // x ∈ t }) → α ↑i)
inst✝ : DecidableEq ι
⊢ Disjoint (cylinder s S) (cylinder t T) ↔
    Disjoint ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ s ∪ t) }) ⁻¹' S)
      ((fun f j => f { val := ↑j, property := (_ : ↑j ∈ s ∪ t) }) ⁻¹' T)

Next tactic:
simp_rw [Set.disjoint_iff, subset_empty_iff, inter_cylinder, cylinder_eq_empty_iff]
theorem empty_mem_measurableCylinders (α : ι → Type*) [∀ i, MeasurableSpace (α i)] :
    ∅ ∈ measurableCylinders α := by
  

Proof state:
ι : Type u_2
α✝ : ι → Type ?u.43141
α : ι → Type u_1
inst✝ : (i : ι) → MeasurableSpace (α i)
⊢ ∅ ∈ measurableCylinders α

Next tactic:
simp_rw [measurableCylinders, mem_iUnion, mem_singleton_iff]
theorem empty_mem_measurableCylinders (α : ι → Type*) [∀ i, MeasurableSpace (α i)] :
    ∅ ∈ measurableCylinders α := by
  simp_rw [measurableCylinders, mem_iUnion, mem_singleton_iff]
  

Proof state:
ι : Type u_2
α✝ : ι → Type ?u.43141
α : ι → Type u_1
inst✝ : (i : ι) → MeasurableSpace (α i)
⊢ ∃ i i_1, ∃ (_ : MeasurableSet i_1), ∅ = cylinder i i_1

Next tactic:
exact ⟨∅, ∅, MeasurableSet.empty, (cylinder_empty _).symm⟩
@[simp]
theorem mem_measurableCylinders (t : Set (∀ i, α i)) :
    t ∈ measurableCylinders α ↔ ∃ s S, MeasurableSet S ∧ t = cylinder s S := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t✝ t : Set ((i : ι) → α i)
⊢ t ∈ measurableCylinders α ↔ ∃ s S, MeasurableSet S ∧ t = cylinder s S

Next tactic:
simp_rw [measurableCylinders, mem_iUnion, exists_prop, mem_singleton_iff]
theorem cylinder_mem_measurableCylinders (s : Finset ι) (S : Set (∀ i : s, α i))
    (hS : MeasurableSet S) :
    cylinder s S ∈ measurableCylinders α := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s✝ t : Set ((i : ι) → α i)
s : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
hS : MeasurableSet S
⊢ cylinder s S ∈ measurableCylinders α

Next tactic:
rw [mem_measurableCylinders]
theorem cylinder_mem_measurableCylinders (s : Finset ι) (S : Set (∀ i : s, α i))
    (hS : MeasurableSet S) :
    cylinder s S ∈ measurableCylinders α := by
  rw [mem_measurableCylinders]; 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s✝ t : Set ((i : ι) → α i)
s : Finset ι
S : Set ((i : { x // x ∈ s }) → α ↑i)
hS : MeasurableSet S
⊢ ∃ s_1 S_1, MeasurableSet S_1 ∧ cylinder s S = cylinder s_1 S_1

Next tactic:
exact ⟨s, S, hS, rfl⟩
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
hs : s ∈ measurableCylinders α
ht : t ∈ measurableCylinders α
⊢ s ∩ t ∈ measurableCylinders α

Next tactic:
rw [mem_measurableCylinders] at *
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at *
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
hs : ∃ s_1 S, MeasurableSet S ∧ s = cylinder s_1 S
ht : ∃ s S, MeasurableSet S ∧ t = cylinder s S
⊢ ∃ s_1 S, MeasurableSet S ∧ s ∩ t = cylinder s_1 S

Next tactic:
obtain ⟨s₁, S₁, hS₁, rfl⟩ := hs