l3lab/ntp-mathlib huggingface dataset:
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at *
  obtain ⟨s₁, S₁, hS₁, rfl⟩ := hs
  

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

Next tactic:
obtain ⟨s₂, S₂, hS₂, rfl⟩ := ht
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at *
  obtain ⟨s₁, S₁, hS₁, rfl⟩ := hs
  obtain ⟨s₂, S₂, hS₂, rfl⟩ := ht
  

Proof state:
case intro.intro.intro.intro.intro.intro
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s₁ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
hS₁ : MeasurableSet S₁
s₂ : Finset ι
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
hS₂ : MeasurableSet S₂
⊢ ∃ s S, MeasurableSet S ∧ cylinder s₁ S₁ ∩ cylinder s₂ S₂ = cylinder s S

Next tactic:
classical
  refine ⟨s₁ ∪ s₂,
    (fun f ↦ (fun i ↦ f ⟨i, Finset.mem_union_left s₂ i.prop⟩ : ∀ i : s₁, α i)) ⁻¹' S₁ ∩
      {f | (fun i ↦ f ⟨i, Finset.mem_union_right s₁ i.prop⟩ : ∀ i : s₂, α i) ∈ S₂}, ?_, ?_⟩
  · refine MeasurableSet.inter ?_ ?_
    · exact measurable_pi_lambda _ (fun _ ↦ measurable_pi_apply _) hS₁
    · exact measurable_pi_lambda _ (fun _ ↦ measurable_pi_apply _) hS₂
  · exact inter_cylinder _ _ _ _
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at *
  obtain ⟨s₁, S₁, hS₁, rfl⟩ := hs
  obtain ⟨s₂, S₂, hS₂, rfl⟩ := ht
  classical
  

Proof state:
case intro.intro.intro.intro.intro.intro
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s₁ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
hS₁ : MeasurableSet S₁
s₂ : Finset ι
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
hS₂ : MeasurableSet S₂
⊢ ∃ s S, MeasurableSet S ∧ cylinder s₁ S₁ ∩ cylinder s₂ S₂ = cylinder s S

Next tactic:
refine ⟨s₁ ∪ s₂,
    (fun f ↦ (fun i ↦ f ⟨i, Finset.mem_union_left s₂ i.prop⟩ : ∀ i : s₁, α i)) ⁻¹' S₁ ∩
      {f | (fun i ↦ f ⟨i, Finset.mem_union_right s₁ i.prop⟩ : ∀ i : s₂, α i) ∈ S₂}, ?_, ?_⟩
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at *
  obtain ⟨s₁, S₁, hS₁, rfl⟩ := hs
  obtain ⟨s₂, S₂, hS₂, rfl⟩ := ht
  classical
  refine ⟨s₁ ∪ s₂,
    (fun f ↦ (fun i ↦ f ⟨i, Finset.mem_union_left s₂ i.prop⟩ : ∀ i : s₁, α i)) ⁻¹' S₁ ∩
      {f | (fun i ↦ f ⟨i, Finset.mem_union_right s₁ i.prop⟩ : ∀ i : s₂, α i) ∈ S₂}, ?_, ?_⟩
  · 

Proof state:
case intro.intro.intro.intro.intro.intro.refine_1
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s₁ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
hS₁ : MeasurableSet S₁
s₂ : Finset ι
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
hS₂ : MeasurableSet S₂
⊢ MeasurableSet
    ((fun f i => f { val := ↑i, property := (_ : ↑i ∈ s₁ ∪ s₂) }) ⁻¹' S₁ ∩
      {f | (fun i => f { val := ↑i, property := (_ : ↑i ∈ s₁ ∪ s₂) }) ∈ S₂})

Next tactic:
refine MeasurableSet.inter ?_ ?_
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at *
  obtain ⟨s₁, S₁, hS₁, rfl⟩ := hs
  obtain ⟨s₂, S₂, hS₂, rfl⟩ := ht
  classical
  refine ⟨s₁ ∪ s₂,
    (fun f ↦ (fun i ↦ f ⟨i, Finset.mem_union_left s₂ i.prop⟩ : ∀ i : s₁, α i)) ⁻¹' S₁ ∩
      {f | (fun i ↦ f ⟨i, Finset.mem_union_right s₁ i.prop⟩ : ∀ i : s₂, α i) ∈ S₂}, ?_, ?_⟩
  · refine MeasurableSet.inter ?_ ?_
    · 

Proof state:
case intro.intro.intro.intro.intro.intro.refine_1.refine_1
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s₁ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
hS₁ : MeasurableSet S₁
s₂ : Finset ι
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
hS₂ : MeasurableSet S₂
⊢ MeasurableSet ((fun f i => f { val := ↑i, property := (_ : ↑i ∈ s₁ ∪ s₂) }) ⁻¹' S₁)

Next tactic:
exact measurable_pi_lambda _ (fun _ ↦ measurable_pi_apply _) hS₁
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at *
  obtain ⟨s₁, S₁, hS₁, rfl⟩ := hs
  obtain ⟨s₂, S₂, hS₂, rfl⟩ := ht
  classical
  refine ⟨s₁ ∪ s₂,
    (fun f ↦ (fun i ↦ f ⟨i, Finset.mem_union_left s₂ i.prop⟩ : ∀ i : s₁, α i)) ⁻¹' S₁ ∩
      {f | (fun i ↦ f ⟨i, Finset.mem_union_right s₁ i.prop⟩ : ∀ i : s₂, α i) ∈ S₂}, ?_, ?_⟩
  · refine MeasurableSet.inter ?_ ?_
    · exact measurable_pi_lambda _ (fun _ ↦ measurable_pi_apply _) hS₁
    · 

Proof state:
case intro.intro.intro.intro.intro.intro.refine_1.refine_2
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s₁ : Finset ι
S₁ : Set ((i : { x // x ∈ s₁ }) → α ↑i)
hS₁ : MeasurableSet S₁
s₂ : Finset ι
S₂ : Set ((i : { x // x ∈ s₂ }) → α ↑i)
hS₂ : MeasurableSet S₂
⊢ MeasurableSet {f | (fun i => f { val := ↑i, property := (_ : ↑i ∈ s₁ ∪ s₂) }) ∈ S₂}

Next tactic:
exact measurable_pi_lambda _ (fun _ ↦ measurable_pi_apply _) hS₂
theorem inter_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∩ t ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at *
  obtain ⟨s₁, S₁, hS₁, rfl⟩ := hs
  obtain ⟨s₂, S₂, hS₂, rfl⟩ := ht
  classical
  refine ⟨s₁ ∪ s₂,
    (fun f ↦ (fun i ↦ f ⟨i, Finset.mem_union_left s₂ i.prop⟩ : ∀ i : s₁, α i)) ⁻¹' S₁ ∩
      {f | (fun i ↦ f ⟨i, Finset.mem_union_right s₁ i.prop⟩ : ∀ i : s₂, α i) ∈ S₂}, ?_, ?_⟩
  · refine MeasurableSet.inter ?_ ?_
    · exact measurable_pi_lambda _ (fun _ ↦ measurable_pi_apply _) hS₁
    · exact measurable_pi_lambda _ (fun _ ↦ measurable_pi_apply _) hS₂
  · 

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

Next tactic:
exact inter_cylinder _ _ _ _
theorem compl_mem_measurableCylinders (hs : s ∈ measurableCylinders α) :
    sᶜ ∈ measurableCylinders α := by
  

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

Next tactic:
rw [mem_measurableCylinders] at hs ⊢
theorem compl_mem_measurableCylinders (hs : s ∈ measurableCylinders α) :
    sᶜ ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at hs ⊢
  

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
⊢ ∃ s_1 S, MeasurableSet S ∧ sᶜ = cylinder s_1 S

Next tactic:
obtain ⟨s, S, hS, rfl⟩ := hs
theorem compl_mem_measurableCylinders (hs : s ∈ measurableCylinders α) :
    sᶜ ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at hs ⊢
  obtain ⟨s, S, hS, rfl⟩ := hs
  

Proof state:
case intro.intro.intro
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
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:
refine ⟨s, Sᶜ, hS.compl, ?_⟩
theorem compl_mem_measurableCylinders (hs : s ∈ measurableCylinders α) :
    sᶜ ∈ measurableCylinders α := by
  rw [mem_measurableCylinders] at hs ⊢
  obtain ⟨s, S, hS, rfl⟩ := hs
  refine ⟨s, Sᶜ, hS.compl, ?_⟩
  

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

Next tactic:
rw [compl_cylinder]
theorem univ_mem_measurableCylinders (α : ι → Type*) [∀ i, MeasurableSpace (α i)] :
    Set.univ ∈ measurableCylinders α := by
  

Proof state:
ι : Type u_2
α✝ : ι → Type ?u.54508
inst✝¹ : (i : ι) → MeasurableSpace (α✝ i)
s t : Set ((i : ι) → α✝ i)
α : ι → Type u_1
inst✝ : (i : ι) → MeasurableSpace (α i)
⊢ univ ∈ measurableCylinders α

Next tactic:
rw [← compl_empty]
theorem univ_mem_measurableCylinders (α : ι → Type*) [∀ i, MeasurableSpace (α i)] :
    Set.univ ∈ measurableCylinders α := by
  rw [← compl_empty]; 

Proof state:
ι : Type u_2
α✝ : ι → Type ?u.54508
inst✝¹ : (i : ι) → MeasurableSpace (α✝ i)
s t : Set ((i : ι) → α✝ i)
α : ι → Type u_1
inst✝ : (i : ι) → MeasurableSpace (α i)
⊢ ∅ᶜ ∈ measurableCylinders α

Next tactic:
exact compl_mem_measurableCylinders (empty_mem_measurableCylinders α)
theorem union_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 [union_eq_compl_compl_inter_compl]
theorem union_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s ∪ t ∈ measurableCylinders α := by
  rw [union_eq_compl_compl_inter_compl]
  

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:
exact compl_mem_measurableCylinders (inter_mem_measurableCylinders
    (compl_mem_measurableCylinders hs) (compl_mem_measurableCylinders ht))
theorem diff_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 [diff_eq_compl_inter]
theorem diff_mem_measurableCylinders (hs : s ∈ measurableCylinders α)
    (ht : t ∈ measurableCylinders α) :
    s \ t ∈ measurableCylinders α := by
  rw [diff_eq_compl_inter]
  

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

Next tactic:
exact inter_mem_measurableCylinders (compl_mem_measurableCylinders ht) hs
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
⊢ MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi

Next tactic:
apply le_antisymm
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · 

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
⊢ MeasurableSpace.generateFrom (measurableCylinders α) ≤ MeasurableSpace.pi

Next tactic:
refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t S : Set ((i : ι) → α i)
hS : S ∈ measurableCylinders α
⊢ MeasurableSet S

Next tactic:
obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    

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

Next tactic:
exact hSm.cylinder
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    exact hSm.cylinder
  · 

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
⊢ MeasurableSpace.pi ≤ MeasurableSpace.generateFrom (measurableCylinders α)

Next tactic:
refine iSup_le fun i ↦ ?_
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    exact hSm.cylinder
  · refine iSup_le fun i ↦ ?_
    

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
i : ι
⊢ MeasurableSpace.comap (fun b => b i) ((fun i => inst✝ i) i) ≤ MeasurableSpace.generateFrom (measurableCylinders α)

Next tactic:
refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    exact hSm.cylinder
  · refine iSup_le fun i ↦ ?_
    refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_
    

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
i : ι
⊢ MeasurableSpace.generateFrom ((fun t => pi {i} t) '' pi univ fun i => {s | MeasurableSet s}) ≤
    MeasurableSpace.generateFrom (measurableCylinders α)

Next tactic:
refine MeasurableSpace.generateFrom_mono (fun x ↦ ?_)
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    exact hSm.cylinder
  · refine iSup_le fun i ↦ ?_
    refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_
    refine MeasurableSpace.generateFrom_mono (fun x ↦ ?_)
    

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
i : ι
x : Set ((i : ι) → α i)
⊢ (x ∈ (fun t => pi {i} t) '' pi univ fun i => {s | MeasurableSet s}) → x ∈ measurableCylinders α

Next tactic:
simp only [singleton_pi, Function.eval, mem_image, mem_pi, mem_univ, mem_setOf_eq,
      forall_true_left, mem_measurableCylinders, exists_prop, forall_exists_index, and_imp]
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    exact hSm.cylinder
  · refine iSup_le fun i ↦ ?_
    refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_
    refine MeasurableSpace.generateFrom_mono (fun x ↦ ?_)
    simp only [singleton_pi, Function.eval, mem_image, mem_pi, mem_univ, mem_setOf_eq,
      forall_true_left, mem_measurableCylinders, exists_prop, forall_exists_index, and_imp]
    

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t : Set ((i : ι) → α i)
i : ι
x : Set ((i : ι) → α i)
⊢ ∀ (x_1 : (i : ι) → Set (α i)),
    (∀ (i : ι), MeasurableSet (x_1 i)) → Function.eval i ⁻¹' x_1 i = x → ∃ s S, MeasurableSet S ∧ x = cylinder s S

Next tactic:
rintro t ht rfl
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    exact hSm.cylinder
  · refine iSup_le fun i ↦ ?_
    refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_
    refine MeasurableSpace.generateFrom_mono (fun x ↦ ?_)
    simp only [singleton_pi, Function.eval, mem_image, mem_pi, mem_univ, mem_setOf_eq,
      forall_true_left, mem_measurableCylinders, exists_prop, forall_exists_index, and_imp]
    rintro t ht rfl
    

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t✝ : Set ((i : ι) → α i)
i : ι
t : (i : ι) → Set (α i)
ht : ∀ (i : ι), MeasurableSet (t i)
⊢ ∃ s S, MeasurableSet S ∧ Function.eval i ⁻¹' t i = cylinder s S

Next tactic:
refine ⟨{i}, {f | f ⟨i, Finset.mem_singleton_self i⟩ ∈ t i}, measurable_pi_apply _ (ht i), ?_⟩
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    exact hSm.cylinder
  · refine iSup_le fun i ↦ ?_
    refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_
    refine MeasurableSpace.generateFrom_mono (fun x ↦ ?_)
    simp only [singleton_pi, Function.eval, mem_image, mem_pi, mem_univ, mem_setOf_eq,
      forall_true_left, mem_measurableCylinders, exists_prop, forall_exists_index, and_imp]
    rintro t ht rfl
    refine ⟨{i}, {f | f ⟨i, Finset.mem_singleton_self i⟩ ∈ t i}, measurable_pi_apply _ (ht i), ?_⟩
    

Proof state:
case a
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t✝ : Set ((i : ι) → α i)
i : ι
t : (i : ι) → Set (α i)
ht : ∀ (i : ι), MeasurableSet (t i)
⊢ Function.eval i ⁻¹' t i = cylinder {i} {f | f { val := i, property := (_ : i ∈ {i}) } ∈ t i}

Next tactic:
ext1 x
/-- The measurable cylinders generate the product σ-algebra. -/
theorem generateFrom_measurableCylinders :
    MeasurableSpace.generateFrom (measurableCylinders α) = MeasurableSpace.pi := by
  apply le_antisymm
  · refine MeasurableSpace.generateFrom_le (fun S hS ↦ ?_)
    obtain ⟨s, S, hSm, rfl⟩ := (mem_measurableCylinders _).mp hS
    exact hSm.cylinder
  · refine iSup_le fun i ↦ ?_
    refine (comap_eval_le_generateFrom_squareCylinders_singleton α i).trans ?_
    refine MeasurableSpace.generateFrom_mono (fun x ↦ ?_)
    simp only [singleton_pi, Function.eval, mem_image, mem_pi, mem_univ, mem_setOf_eq,
      forall_true_left, mem_measurableCylinders, exists_prop, forall_exists_index, and_imp]
    rintro t ht rfl
    refine ⟨{i}, {f | f ⟨i, Finset.mem_singleton_self i⟩ ∈ t i}, measurable_pi_apply _ (ht i), ?_⟩
    ext1 x
    

Proof state:
case a.h
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → MeasurableSpace (α i)
s t✝ : Set ((i : ι) → α i)
i : ι
t : (i : ι) → Set (α i)
ht : ∀ (i : ι), MeasurableSet (t i)
x : (x : ι) → α x
⊢ x ∈ Function.eval i ⁻¹' t i ↔ x ∈ cylinder {i} {f | f { val := i, property := (_ : i ∈ {i}) } ∈ t i}

Next tactic:
simp only [singleton_pi, Function.eval, mem_preimage, mem_cylinder, mem_setOf_eq]
instance Prj.mvqpf : MvQPF (Prj i) where
  P := Prj.P i
  abs := @Prj.abs _ i
  repr := @Prj.repr _ i
  abs_repr := by 

Proof state:
n : ℕ
i : Fin2 n
⊢ ∀ {α : TypeVec.{?u.1409} n} (x : Prj i α), abs i (repr i x) = x

Next tactic:
intros
instance Prj.mvqpf : MvQPF (Prj i) where
  P := Prj.P i
  abs := @Prj.abs _ i
  repr := @Prj.repr _ i
  abs_repr := by intros; 

Proof state:
n : ℕ
i : Fin2 n
α✝ : TypeVec.{?u.1409} n
x✝ : Prj i α✝
⊢ abs i (repr i x✝) = x✝

Next tactic:
rfl
instance Prj.mvqpf : MvQPF (Prj i) where
  P := Prj.P i
  abs := @Prj.abs _ i
  repr := @Prj.repr _ i
  abs_repr := by intros; rfl
  abs_map := by 

Proof state:
n : ℕ
i : Fin2 n
⊢ ∀ {α β : TypeVec.{?u.1409} n} (f : α ⟹ β) (p : ↑(P i) α), abs i (f <$$> p) = f <$$> abs i p

Next tactic:
intros α β f P
instance Prj.mvqpf : MvQPF (Prj i) where
  P := Prj.P i
  abs := @Prj.abs _ i
  repr := @Prj.repr _ i
  abs_repr := by intros; rfl
  abs_map := by intros α β f P; 

Proof state:
n : ℕ
i : Fin2 n
α β : TypeVec.{?u.1409} n
f : α ⟹ β
P : ↑(MvQPF.Prj.P i) α
⊢ abs i (f <$$> P) = f <$$> abs i P

Next tactic:
cases P
instance Prj.mvqpf : MvQPF (Prj i) where
  P := Prj.P i
  abs := @Prj.abs _ i
  repr := @Prj.repr _ i
  abs_repr := by intros; rfl
  abs_map := by intros α β f P; cases P; 

Proof state:
case mk
n : ℕ
i : Fin2 n
α β : TypeVec.{?u.1409} n
f : α ⟹ β
fst✝ : (P i).A
snd✝ : MvPFunctor.B (P i) fst✝ ⟹ α
⊢ abs i (f <$$> { fst := fst✝, snd := snd✝ }) = f <$$> abs i { fst := fst✝, snd := snd✝ }

Next tactic:
rfl
instance : SetLike (ClopenUpperSet α) α where
  coe s := s.carrier
  coe_injective' s t h := by
    

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : TopologicalSpace α
inst✝² : LE α
inst✝¹ : TopologicalSpace β
inst✝ : LE β
s t : ClopenUpperSet α
h : (fun s => s.carrier) s = (fun s => s.carrier) t
⊢ s = t

Next tactic:
obtain ⟨⟨_, _⟩, _⟩ := s
instance : SetLike (ClopenUpperSet α) α where
  coe s := s.carrier
  coe_injective' s t h := by
    obtain ⟨⟨_, _⟩, _⟩ := s
    

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
inst✝³ : TopologicalSpace α
inst✝² : LE α
inst✝¹ : TopologicalSpace β
inst✝ : LE β
t : ClopenUpperSet α
carrier✝ : Set α
isClopen'✝ : IsClopen carrier✝
upper'✝ : IsUpperSet { carrier := carrier✝, isClopen' := isClopen'✝ }.carrier
h :
  (fun s => s.carrier) { toClopens := { carrier := carrier✝, isClopen' := isClopen'✝ }, upper' := upper'✝ } =
    (fun s => s.carrier) t
⊢ { toClopens := { carrier := carrier✝, isClopen' := isClopen'✝ }, upper' := upper'✝ } = t

Next tactic:
obtain ⟨⟨_, _⟩, _⟩ := t
instance : SetLike (ClopenUpperSet α) α where
  coe s := s.carrier
  coe_injective' s t h := by
    obtain ⟨⟨_, _⟩, _⟩ := s
    obtain ⟨⟨_, _⟩, _⟩ := t
    

Proof state:
case mk.mk.mk.mk
α : Type u_1
β : Type u_2
inst✝³ : TopologicalSpace α
inst✝² : LE α
inst✝¹ : TopologicalSpace β
inst✝ : LE β
carrier✝¹ : Set α
isClopen'✝¹ : IsClopen carrier✝¹
upper'✝¹ : IsUpperSet { carrier := carrier✝¹, isClopen' := isClopen'✝¹ }.carrier
carrier✝ : Set α
isClopen'✝ : IsClopen carrier✝
upper'✝ : IsUpperSet { carrier := carrier✝, isClopen' := isClopen'✝ }.carrier
h :
  (fun s => s.carrier) { toClopens := { carrier := carrier✝¹, isClopen' := isClopen'✝¹ }, upper' := upper'✝¹ } =
    (fun s => s.carrier) { toClopens := { carrier := carrier✝, isClopen' := isClopen'✝ }, upper' := upper'✝ }
⊢ { toClopens := { carrier := carrier✝¹, isClopen' := isClopen'✝¹ }, upper' := upper'✝¹ } =
    { toClopens := { carrier := carrier✝, isClopen' := isClopen'✝ }, upper' := upper'✝ }

Next tactic:
congr