-- Mathlib/Topology/Constructions.lean
theorem pi_generateFrom_eq_finite {π : ι → Type*} {g : ∀ a, Set (Set (π a))} [Finite ι]
    (hg : ∀ a, ⋃₀ g a = univ) :
    (@Pi.topologicalSpace ι π fun a => generateFrom (g a)) =
      generateFrom { t | ∃ s : ∀ a, Set (π a), (∀ a, s a ∈ g a) ∧ t = pi univ s }

Proof state:
case intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
⊢ generateFrom {t | ∃ s i, (∀ a ∈ i, s a ∈ g a) ∧ t = (↑i).pi s} =
    generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}

Tactic:
refine le_antisymm (generateFrom_anti ?_) (le_generateFrom ?_)

Result:
case intro.refine_1
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
⊢ {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s} ⊆ {t | ∃ s i, (∀ a ∈ i, s a ∈ g a) ∧ t = (↑i).pi s}

case intro.refine_2
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
⊢ ∀ s ∈ {t | ∃ s i, (∀ a ∈ i, s a ∈ g a) ∧ t = (↑i).pi s}, IsOpen s

Proof state:
case intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
⊢ Pi.topologicalSpace = generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}

Tactic:
rw [pi_generateFrom_eq]

Result:
case intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
⊢ generateFrom {t | ∃ s i, (∀ a ∈ i, s a ∈ g a) ∧ t = (↑i).pi s} =
    generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}

Proof state:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
⊢ IsOpen ((↑i).pi t)

Tactic:
refine isOpen_iff_forall_mem_open.2 fun f hf => ?_

Result:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
f : (i : ι) → π i
hf : f ∈ (↑i).pi t
⊢ ∃ t_1 ⊆ (↑i).pi t, IsOpen t_1 ∧ f ∈ t_1

Proof state:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
f : (i : ι) → π i
hf : f ∈ (↑i).pi t
⊢ ∃ t_1 ⊆ (↑i).pi t, IsOpen t_1 ∧ f ∈ t_1

Tactic:
choose c hcg hfc using fun a => sUnion_eq_univ_iff.1 (hg a) (f a)

Result:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
f : (i : ι) → π i
hf : f ∈ (↑i).pi t
c : (a : ι) → Set (π a)
hcg : ∀ (a : ι), c a ∈ g a
hfc : ∀ (a : ι), f a ∈ c a
⊢ ∃ t_1 ⊆ (↑i).pi t, IsOpen t_1 ∧ f ∈ t_1

Proof state:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
⊢ IsOpen ((↑i).pi t)

Tactic:
letI := generateFrom { t | ∃ s : ∀ a, Set (π a), (∀ a, s a ∈ g a) ∧ t = pi univ s }

Result:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
⊢ IsOpen ((↑i).pi t)

Proof state:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
f : (i : ι) → π i
hf : f ∈ (↑i).pi t
c : (a : ι) → Set (π a)
hcg : ∀ (a : ι), c a ∈ g a
hfc : ∀ (a : ι), f a ∈ c a
a : ι
⊢ (↑i).piecewise t c a ∈ g a

Tactic:
by_cases a ∈ i <;> simp [*]

Result:
no goals

Proof state:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
f : (i : ι) → π i
hf : f ∈ (↑i).pi t
c : (a : ι) → Set (π a)
hcg : ∀ (a : ι), c a ∈ g a
hfc : ∀ (a : ι), f a ∈ c a
⊢ IsOpen ((↑i).pi t ∩ (↑i)ᶜ.pi c)

Tactic:
rw [← univ_pi_piecewise]

Result:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
f : (i : ι) → π i
hf : f ∈ (↑i).pi t
c : (a : ι) → Set (π a)
hcg : ∀ (a : ι), c a ∈ g a
hfc : ∀ (a : ι), f a ∈ c a
⊢ IsOpen (univ.pi ((↑i).piecewise t c))

Proof state:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
this : TopologicalSpace ((i : ι) → π i) := generateFrom {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
f : (i : ι) → π i
hf : f ∈ (↑i).pi t
c : (a : ι) → Set (π a)
hcg : ∀ (a : ι), c a ∈ g a
hfc : ∀ (a : ι), f a ∈ c a
⊢ IsOpen ((↑i).pi t ∩ (↑i)ᶜ.pi c)

Tactic:
classical
rw [← univ_pi_piecewise]
refine GenerateOpen.basic _ ⟨_, fun a => ?_, rfl⟩
by_cases a ∈ i <;> simp [*]

Result:
no goals

Proof state:
case intro.refine_2
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
⊢ ∀ s ∈ {t | ∃ s i, (∀ a ∈ i, s a ∈ g a) ∧ t = (↑i).pi s}, IsOpen s

Tactic:
rintro s ⟨t, i, ht, rfl⟩

Result:
case intro.refine_2.intro.intro.intro
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
t : (a : ι) → Set (π a)
i : Finset ι
ht : ∀ a ∈ i, t a ∈ g a
⊢ IsOpen ((↑i).pi t)

Proof state:
ι : Type u_5
π : ι → Type u_8
g : (a : ι) → Set (Set (π a))
inst✝ : Finite ι
hg : ∀ (a : ι), ⋃₀ g a = univ
val✝ : Fintype ι
s : Set ((i : ι) → π i)
x✝ : s ∈ {t | ∃ s, (∀ (a : ι), s a ∈ g a) ∧ t = univ.pi s}
t : (a : ι) → Set (π a)
ht : ∀ (a : ι), t a ∈ g a
Eq : s = univ.pi t
⊢ (∀ a ∈ Finset.univ, t a ∈ g a) ∧ s = (↑Finset.univ).pi t

Tactic:
simp [ht, Eq]

Result:
no goals