-- Mathlib/MeasureTheory/MeasurableSpace/Pi.lean
theorem generateFrom_pi_eq {C : ∀ i, Set (Set (α i))} (hC : ∀ i, IsCountablySpanning (C i)) :
    (@MeasurableSpace.pi _ _ fun i => generateFrom (C i)) =
    generateFrom (pi univ '' pi univ C)

Proof state:
case intro.a.h.intro.intro.h
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
this : univ.pi (update (fun i' => iUnion (t i')) i (⋃ x, s)) = univ.pi fun k => ⋃ j, update (fun i' => t i' j) i s k
n : ι → ℕ
⊢ MeasurableSet (univ.pi fun a => update (fun i' => t i' (n a)) i s a)

Tactic:
apply measurableSet_generateFrom

Result:
case intro.a.h.intro.intro.h.ht
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
this : univ.pi (update (fun i' => iUnion (t i')) i (⋃ x, s)) = univ.pi fun k => ⋃ j, update (fun i' => t i' j) i s k
n : ι → ℕ
⊢ (univ.pi fun a => update (fun i' => t i' (n a)) i s a) ∈ univ.pi '' univ.pi C

Proof state:
case intro.a
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
val✝ : Encodable ι
⊢ MeasurableSpace.pi ≤ generateFrom (univ.pi '' univ.pi C)

Tactic:
refine iSup_le ?_

Result:
case intro.a
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
val✝ : Encodable ι
⊢ ∀ (i : ι),
    MeasurableSpace.comap (fun b => b i) ((fun i => generateFrom (C i)) i) ≤ generateFrom (univ.pi '' univ.pi C)

Proof state:
case intro.a.h.intro.intro
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
val✝ : Encodable ι
s : (i : ι) → Set (α i)
hs : s ∈ univ.pi C
⊢ MeasurableSet (univ.pi s)

Tactic:
rw [univ_pi_eq_iInter]

Result:
case intro.a.h.intro.intro
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
val✝ : Encodable ι
s : (i : ι) → Set (α i)
hs : s ∈ univ.pi C
⊢ MeasurableSet (⋂ i, eval i ⁻¹' s i)

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
⊢ univ.pi (update (fun i' => iUnion (t i')) i (⋃ x, s)) = univ.pi fun k => ⋃ j, update (fun i' => t i' j) i s k

Tactic:
ext

Result:
case h
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
x✝ : (i : ι) → α i
⊢ x✝ ∈ univ.pi (update (fun i' => iUnion (t i')) i (⋃ x, s)) ↔
    x✝ ∈ univ.pi fun k => ⋃ j, update (fun i' => t i' j) i s k

Proof state:
case h.h
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
x✝ : (i : ι) → α i
⊢ ∀ (a : ι), x✝ a ∈ update (fun i' => iUnion (t i')) i (⋃ x, s) a ↔ x✝ a ∈ ⋃ j, update (fun i' => t i' j) i s a

Tactic:
intro i'

Result:
case h.h
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
x✝ : (i : ι) → α i
i' : ι
⊢ x✝ i' ∈ update (fun i' => iUnion (t i')) i (⋃ x, s) i' ↔ x✝ i' ∈ ⋃ j, update (fun i' => t i' j) i s i'

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
⊢ MeasurableSpace.pi = generateFrom (univ.pi '' univ.pi C)

Tactic:
cases nonempty_encodable ι

Result:
case intro
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
val✝ : Encodable ι
⊢ MeasurableSpace.pi = generateFrom (univ.pi '' univ.pi C)

Proof state:
case intro.a.h.intro.intro.h.ht.h
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
this : univ.pi (update (fun i' => iUnion (t i')) i (⋃ x, s)) = univ.pi fun k => ⋃ j, update (fun i' => t i' j) i s k
n : ι → ℕ
⊢ (fun a => update (fun i' => t i' (n a)) i s a) ∈ univ.pi C

Tactic:
intro j _

Result:
case intro.a.h.intro.intro.h.ht.h
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
this : univ.pi (update (fun i' => iUnion (t i')) i (⋃ x, s)) = univ.pi fun k => ⋃ j, update (fun i' => t i' j) i s k
n : ι → ℕ
j : ι
a✝ : j ∈ univ
⊢ (fun a => update (fun i' => t i' (n a)) i s a) j ∈ C j

Proof state:
case intro
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
val✝ : Encodable ι
⊢ MeasurableSpace.pi = generateFrom (univ.pi '' univ.pi C)

Tactic:
apply le_antisymm

Result:
case intro.a
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
val✝ : Encodable ι
⊢ MeasurableSpace.pi ≤ generateFrom (univ.pi '' univ.pi C)

case intro.a
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
hC : ∀ (i : ι), IsCountablySpanning (C i)
val✝ : Encodable ι
⊢ generateFrom (univ.pi '' univ.pi C) ≤ MeasurableSpace.pi

Proof state:
case intro.a.h.intro.intro
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
⊢ MeasurableSet ((fun b => b i) ⁻¹' s)

Tactic:
simp_rw [eval_preimage, ← h2t]

Result:
case intro.a.h.intro.intro
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
⊢ MeasurableSet (univ.pi (update (fun x => ⋃ n, t x n) i s))

Proof state:
case neg
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
x✝ : (i : ι) → α i
i' : ι
h : i' ≠ i
⊢ x✝ i' ∈ update (fun i' => iUnion (t i')) i (⋃ x, s) i' ↔ x✝ i' ∈ ⋃ j, update (fun i' => t i' j) i s i'

Tactic:
simp [h]

Result:
no goals

Proof state:
case pos
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
i : ι
s : Set (α i)
hs : s ∈ C i
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
x✝ : (i : ι) → α i
i' : ι
h : i' = i
⊢ x✝ i' ∈ update (fun i' => iUnion (t i')) i (⋃ x, s) i' ↔ x✝ i' ∈ ⋃ j, update (fun i' => t i' j) i s i'

Tactic:
subst h

Result:
case pos
ι : Type u_1
α : ι → Type u_2
inst✝ : Finite ι
C : (i : ι) → Set (Set (α i))
val✝ : Encodable ι
t : (i : ι) → ℕ → Set (α i)
h1t : ∀ (i : ι) (n : ℕ), t i n ∈ C i
h2t : ∀ (i : ι), ⋃ n, t i n = univ
x✝ : (i : ι) → α i
i' : ι
s : Set (α i')
hs : s ∈ C i'
⊢ x✝ i' ∈ update (fun i' => iUnion (t i')) i' (⋃ x, s) i' ↔ x✝ i' ∈ ⋃ j, update (fun i' => t i' j) i' s i'