l3lab/ntp-mathlib huggingface dataset:
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> 

Proof state:
case inter.inr
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
U t✝ : Set α
a✝¹ : GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) t✝
h₂ : t✝ = ∅ ∨ t✝ = univ
a✝ : GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) univ
⊢ univ ∩ t✝ = ∅ ∨ univ ∩ t✝ = univ

Next tactic:
rcases h₂ with (rfl | rfl)
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> rcases h₂ with (rfl | rfl) <;> 

Proof state:
case inter.inl.inl
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
U : Set α
a✝¹ a✝ : GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) ∅
⊢ ∅ ∩ ∅ = ∅ ∨ ∅ ∩ ∅ = univ

Next tactic:
simp
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> rcases h₂ with (rfl | rfl) <;> 

Proof state:
case inter.inl.inr
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
U : Set α
a✝¹ : GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) ∅
a✝ : GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) univ
⊢ ∅ ∩ univ = ∅ ∨ ∅ ∩ univ = univ

Next tactic:
simp
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> rcases h₂ with (rfl | rfl) <;> 

Proof state:
case inter.inr.inl
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
U : Set α
a✝¹ : GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) univ
a✝ : GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) ∅
⊢ univ ∩ ∅ = ∅ ∨ univ ∩ ∅ = univ

Next tactic:
simp
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> rcases h₂ with (rfl | rfl) <;> 

Proof state:
case inter.inr.inr
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
U : Set α
a✝¹ a✝ : GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) univ
⊢ univ ∩ univ = ∅ ∨ univ ∩ univ = univ

Next tactic:
simp
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> rcases h₂ with (rfl | rfl) <;> simp
    

Proof state:
case sUnion
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
U : Set α
S✝ : Set (Set α)
a✝ : ∀ s ∈ S✝, GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) s
ih : ∀ s ∈ S✝, s = ∅ ∨ s = univ
⊢ ⋃₀ S✝ = ∅ ∨ ⋃₀ S✝ = univ

Next tactic:
| sUnion _ _ ih => exact sUnion_mem_empty_univ ih
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> rcases h₂ with (rfl | rfl) <;> simp
    | sUnion _ _ ih => 

Proof state:
case sUnion
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
U : Set α
S✝ : Set (Set α)
a✝ : ∀ s ∈ S✝, GenerateOpen (OrderDual.ofDual (OrderDual.ofDual ⊥)) s
ih : ∀ s ∈ S✝, s = ∅ ∨ s = univ
⊢ ⋃₀ S✝ = ∅ ∨ ⋃₀ S✝ = univ

Next tactic:
exact sUnion_mem_empty_univ ih
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> rcases h₂ with (rfl | rfl) <;> simp
    | sUnion _ _ ih => exact sUnion_mem_empty_univ ih, by
      

Proof state:
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
U : Set α
⊢ U = ∅ ∨ U = univ → IsOpen U

Next tactic:
rintro (rfl | rfl)
/-- The only open sets in the indiscrete topology are the empty set and the whole space. -/
theorem TopologicalSpace.isOpen_top_iff {α} (U : Set α) : IsOpen[⊤] U ↔ U = ∅ ∨ U = univ :=
  ⟨fun h => by
    induction h with
    | basic _ h => exact False.elim h
    | univ => exact .inr rfl
    | inter _ _ _ _ h₁ h₂ =>
      rcases h₁ with (rfl | rfl) <;> rcases h₂ with (rfl | rfl) <;> simp
    | sUnion _ _ ih => exact sUnion_mem_empty_univ ih, by
      rintro (rfl | rfl)
      

Proof state:
case inl
α✝ : Type ?u.12870
t t₁ t₂ : TopologicalSpace α✝
s : Set α✝
α : Type u_1
⊢ IsOpen ∅
case inr α✝ : Type ?u.12870 t t₁ t₂ : TopologicalSpace α✝ s : Set α✝ α : Type u_1 ⊢ IsOpen univ

Next tactic:
exacts [@isOpen_empty _ ⊤, @isOpen_univ _ ⊤]
@[simp] theorem dense_discrete {s : Set α} : Dense s ↔ s = univ := by 

Proof state:
α : Type u_1
t t₁ t₂ : TopologicalSpace α
s✝ : Set α
inst✝¹ : TopologicalSpace α
inst✝ : DiscreteTopology α
s : Set α
⊢ Dense s ↔ s = univ

Next tactic:
simp [dense_iff_closure_eq]
@[simp]
theorem denseRange_discrete {f : ι → α} : DenseRange f ↔ Surjective f := by
  

Proof state:
α : Type u_2
t t₁ t₂ : TopologicalSpace α
s : Set α
inst✝¹ : TopologicalSpace α
inst✝ : DiscreteTopology α
ι : Type u_1
f : ι → α
⊢ DenseRange f ↔ Surjective f

Next tactic:
rw [DenseRange, dense_discrete, range_iff_surjective]
theorem mem_nhds_discrete {x : α} {s : Set α} :
    s ∈ 𝓝 x ↔ x ∈ s := by 

Proof state:
α : Type u_1
t t₁ t₂ : TopologicalSpace α
s✝ : Set α
inst✝¹ : TopologicalSpace α
inst✝ : DiscreteTopology α
x : α
s : Set α
⊢ s ∈ 𝓝 x ↔ x ∈ s

Next tactic:
rw [nhds_discrete, mem_pure]
theorem le_of_nhds_le_nhds (h : ∀ x, @nhds α t₁ x ≤ @nhds α t₂ x) : t₁ ≤ t₂ := fun s => by
  

Proof state:
α : Type u_1
t t₁ t₂ : TopologicalSpace α
s✝ : Set α
h : ∀ (x : α), 𝓝 x ≤ 𝓝 x
s : Set α
⊢ IsOpen s → IsOpen s

Next tactic:
rw [@isOpen_iff_mem_nhds _ t₁, @isOpen_iff_mem_nhds α t₂]
theorem le_of_nhds_le_nhds (h : ∀ x, @nhds α t₁ x ≤ @nhds α t₂ x) : t₁ ≤ t₂ := fun s => by
  rw [@isOpen_iff_mem_nhds _ t₁, @isOpen_iff_mem_nhds α t₂]
  

Proof state:
α : Type u_1
t t₁ t₂ : TopologicalSpace α
s✝ : Set α
h : ∀ (x : α), 𝓝 x ≤ 𝓝 x
s : Set α
⊢ (∀ a ∈ s, s ∈ 𝓝 a) → ∀ a ∈ s, s ∈ 𝓝 a

Next tactic:
exact fun hs a ha => h _ (hs _ ha)
theorem discreteTopology_iff_singleton_mem_nhds [TopologicalSpace α] :
    DiscreteTopology α ↔ ∀ x : α, {x} ∈ 𝓝 x := by
  

Proof state:
α : Type u_1
t t₁ t₂ : TopologicalSpace α
s : Set α
inst✝ : TopologicalSpace α
⊢ DiscreteTopology α ↔ ∀ (x : α), {x} ∈ 𝓝 x

Next tactic:
simp only [← singletons_open_iff_discrete, isOpen_iff_mem_nhds, mem_singleton_iff, forall_eq]
/-- This lemma characterizes discrete topological spaces as those whose singletons are
neighbourhoods. -/
theorem discreteTopology_iff_nhds [TopologicalSpace α] :
    DiscreteTopology α ↔ ∀ x : α, 𝓝 x = pure x := by
  

Proof state:
α : Type u_1
t t₁ t₂ : TopologicalSpace α
s : Set α
inst✝ : TopologicalSpace α
⊢ DiscreteTopology α ↔ ∀ (x : α), 𝓝 x = pure x

Next tactic:
simp only [discreteTopology_iff_singleton_mem_nhds, ← nhds_neBot.le_pure_iff, le_pure_iff]
theorem discreteTopology_iff_nhds_ne [TopologicalSpace α] :
    DiscreteTopology α ↔ ∀ x : α, 𝓝[≠] x = ⊥ := by
  

Proof state:
α : Type u_1
t t₁ t₂ : TopologicalSpace α
s : Set α
inst✝ : TopologicalSpace α
⊢ DiscreteTopology α ↔ ∀ (x : α), 𝓝[≠] x = ⊥

Next tactic:
simp only [discreteTopology_iff_singleton_mem_nhds, nhdsWithin, inf_principal_eq_bot, compl_compl]
/-- Given `f : α → β` and a topology on `β`, the induced topology on `α` is the collection of
  sets that are preimages of some open set in `β`. This is the coarsest topology that
  makes `f` continuous. -/
def TopologicalSpace.induced {α : Type u} {β : Type v} (f : α → β) (t : TopologicalSpace β) :
    TopologicalSpace α where
  IsOpen s := ∃ s', IsOpen s' ∧ f ⁻¹' s' = s
  isOpen_univ := ⟨univ, isOpen_univ, preimage_univ⟩
  isOpen_inter := by
    

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Type u
β : Type v
f : α → β
t : TopologicalSpace β
⊢ ∀ (s t_1 : Set α),
    (fun s => ∃ s', IsOpen s' ∧ f ⁻¹' s' = s) s →
      (fun s => ∃ s', IsOpen s' ∧ f ⁻¹' s' = s) t_1 → (fun s => ∃ s', IsOpen s' ∧ f ⁻¹' s' = s) (s ∩ t_1)

Next tactic:
rintro s₁ s₂ ⟨s'₁, hs₁, rfl⟩ ⟨s'₂, hs₂, rfl⟩
/-- Given `f : α → β` and a topology on `β`, the induced topology on `α` is the collection of
  sets that are preimages of some open set in `β`. This is the coarsest topology that
  makes `f` continuous. -/
def TopologicalSpace.induced {α : Type u} {β : Type v} (f : α → β) (t : TopologicalSpace β) :
    TopologicalSpace α where
  IsOpen s := ∃ s', IsOpen s' ∧ f ⁻¹' s' = s
  isOpen_univ := ⟨univ, isOpen_univ, preimage_univ⟩
  isOpen_inter := by
    rintro s₁ s₂ ⟨s'₁, hs₁, rfl⟩ ⟨s'₂, hs₂, rfl⟩
    

Proof state:
case intro.intro.intro.intro
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Type u
β : Type v
f : α → β
t : TopologicalSpace β
s'₁ : Set β
hs₁ : IsOpen s'₁
s'₂ : Set β
hs₂ : IsOpen s'₂
⊢ ∃ s', IsOpen s' ∧ f ⁻¹' s' = f ⁻¹' s'₁ ∩ f ⁻¹' s'₂

Next tactic:
exact ⟨s'₁ ∩ s'₂, hs₁.inter hs₂, preimage_inter⟩
/-- Given `f : α → β` and a topology on `β`, the induced topology on `α` is the collection of
  sets that are preimages of some open set in `β`. This is the coarsest topology that
  makes `f` continuous. -/
def TopologicalSpace.induced {α : Type u} {β : Type v} (f : α → β) (t : TopologicalSpace β) :
    TopologicalSpace α where
  IsOpen s := ∃ s', IsOpen s' ∧ f ⁻¹' s' = s
  isOpen_univ := ⟨univ, isOpen_univ, preimage_univ⟩
  isOpen_inter := by
    rintro s₁ s₂ ⟨s'₁, hs₁, rfl⟩ ⟨s'₂, hs₂, rfl⟩
    exact ⟨s'₁ ∩ s'₂, hs₁.inter hs₂, preimage_inter⟩
  isOpen_sUnion S h := by
    

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Type u
β : Type v
f : α → β
t : TopologicalSpace β
S : Set (Set α)
h : ∀ t_1 ∈ S, (fun s => ∃ s', IsOpen s' ∧ f ⁻¹' s' = s) t_1
⊢ (fun s => ∃ s', IsOpen s' ∧ f ⁻¹' s' = s) (⋃₀ S)

Next tactic:
choose! g hgo hfg using h
/-- Given `f : α → β` and a topology on `β`, the induced topology on `α` is the collection of
  sets that are preimages of some open set in `β`. This is the coarsest topology that
  makes `f` continuous. -/
def TopologicalSpace.induced {α : Type u} {β : Type v} (f : α → β) (t : TopologicalSpace β) :
    TopologicalSpace α where
  IsOpen s := ∃ s', IsOpen s' ∧ f ⁻¹' s' = s
  isOpen_univ := ⟨univ, isOpen_univ, preimage_univ⟩
  isOpen_inter := by
    rintro s₁ s₂ ⟨s'₁, hs₁, rfl⟩ ⟨s'₂, hs₂, rfl⟩
    exact ⟨s'₁ ∩ s'₂, hs₁.inter hs₂, preimage_inter⟩
  isOpen_sUnion S h := by
    choose! g hgo hfg using h
    

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Type u
β : Type v
f : α → β
t : TopologicalSpace β
S : Set (Set α)
g : Set α → Set β
hgo : ∀ t_1 ∈ S, IsOpen (g t_1)
hfg : ∀ t ∈ S, f ⁻¹' g t = t
⊢ ∃ s', IsOpen s' ∧ f ⁻¹' s' = ⋃₀ S

Next tactic:
refine ⟨⋃ s ∈ S, g s, isOpen_biUnion fun s hs => hgo s hs, ?_⟩
/-- Given `f : α → β` and a topology on `β`, the induced topology on `α` is the collection of
  sets that are preimages of some open set in `β`. This is the coarsest topology that
  makes `f` continuous. -/
def TopologicalSpace.induced {α : Type u} {β : Type v} (f : α → β) (t : TopologicalSpace β) :
    TopologicalSpace α where
  IsOpen s := ∃ s', IsOpen s' ∧ f ⁻¹' s' = s
  isOpen_univ := ⟨univ, isOpen_univ, preimage_univ⟩
  isOpen_inter := by
    rintro s₁ s₂ ⟨s'₁, hs₁, rfl⟩ ⟨s'₂, hs₂, rfl⟩
    exact ⟨s'₁ ∩ s'₂, hs₁.inter hs₂, preimage_inter⟩
  isOpen_sUnion S h := by
    choose! g hgo hfg using h
    refine ⟨⋃ s ∈ S, g s, isOpen_biUnion fun s hs => hgo s hs, ?_⟩
    

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Type u
β : Type v
f : α → β
t : TopologicalSpace β
S : Set (Set α)
g : Set α → Set β
hgo : ∀ t_1 ∈ S, IsOpen (g t_1)
hfg : ∀ t ∈ S, f ⁻¹' g t = t
⊢ f ⁻¹' ⋃ s ∈ S, g s = ⋃₀ S

Next tactic:
rw [preimage_iUnion₂, sUnion_eq_biUnion]
/-- Given `f : α → β` and a topology on `β`, the induced topology on `α` is the collection of
  sets that are preimages of some open set in `β`. This is the coarsest topology that
  makes `f` continuous. -/
def TopologicalSpace.induced {α : Type u} {β : Type v} (f : α → β) (t : TopologicalSpace β) :
    TopologicalSpace α where
  IsOpen s := ∃ s', IsOpen s' ∧ f ⁻¹' s' = s
  isOpen_univ := ⟨univ, isOpen_univ, preimage_univ⟩
  isOpen_inter := by
    rintro s₁ s₂ ⟨s'₁, hs₁, rfl⟩ ⟨s'₂, hs₂, rfl⟩
    exact ⟨s'₁ ∩ s'₂, hs₁.inter hs₂, preimage_inter⟩
  isOpen_sUnion S h := by
    choose! g hgo hfg using h
    refine ⟨⋃ s ∈ S, g s, isOpen_biUnion fun s hs => hgo s hs, ?_⟩
    rw [preimage_iUnion₂, sUnion_eq_biUnion]
    

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Type u
β : Type v
f : α → β
t : TopologicalSpace β
S : Set (Set α)
g : Set α → Set β
hgo : ∀ t_1 ∈ S, IsOpen (g t_1)
hfg : ∀ t ∈ S, f ⁻¹' g t = t
⊢ ⋃ i ∈ S, f ⁻¹' g i = ⋃ i ∈ S, i

Next tactic:
exact iUnion₂_congr hfg
theorem isClosed_induced_iff [t : TopologicalSpace β] {s : Set α} {f : α → β} :
    IsClosed[t.induced f] s ↔ ∃ t, IsClosed t ∧ f ⁻¹' t = s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
t : TopologicalSpace β
s : Set α
f : α → β
⊢ IsClosed s ↔ ∃ t_1, IsClosed t_1 ∧ f ⁻¹' t_1 = s

Next tactic:
letI := t.induced f
theorem isClosed_induced_iff [t : TopologicalSpace β] {s : Set α} {f : α → β} :
    IsClosed[t.induced f] s ↔ ∃ t, IsClosed t ∧ f ⁻¹' t = s := by
  letI := t.induced f
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
t : TopologicalSpace β
s : Set α
f : α → β
this : TopologicalSpace α := TopologicalSpace.induced f t
⊢ IsClosed s ↔ ∃ t_1, IsClosed t_1 ∧ f ⁻¹' t_1 = s

Next tactic:
simp only [← isOpen_compl_iff, isOpen_induced_iff]
theorem isClosed_induced_iff [t : TopologicalSpace β] {s : Set α} {f : α → β} :
    IsClosed[t.induced f] s ↔ ∃ t, IsClosed t ∧ f ⁻¹' t = s := by
  letI := t.induced f
  simp only [← isOpen_compl_iff, isOpen_induced_iff]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
t : TopologicalSpace β
s : Set α
f : α → β
this : TopologicalSpace α := TopologicalSpace.induced f t
⊢ (∃ t_1, IsOpen t_1 ∧ f ⁻¹' t_1 = sᶜ) ↔ ∃ t_1, IsOpen t_1ᶜ ∧ f ⁻¹' t_1 = s

Next tactic:
exact compl_surjective.exists.trans (by simp only [preimage_compl, compl_inj_iff])
theorem isClosed_induced_iff [t : TopologicalSpace β] {s : Set α} {f : α → β} :
    IsClosed[t.induced f] s ↔ ∃ t, IsClosed t ∧ f ⁻¹' t = s := by
  letI := t.induced f
  simp only [← isOpen_compl_iff, isOpen_induced_iff]
  exact compl_surjective.exists.trans (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
t : TopologicalSpace β
s : Set α
f : α → β
this : TopologicalSpace α := TopologicalSpace.induced f t
⊢ (∃ x, IsOpen xᶜ ∧ f ⁻¹' xᶜ = sᶜ) ↔ ∃ t_1, IsOpen t_1ᶜ ∧ f ⁻¹' t_1 = s

Next tactic:
simp only [preimage_compl, compl_inj_iff]
/-- Given `f : α → β` and a topology on `α`, the coinduced topology on `β` is defined
  such that `s : Set β` is open if the preimage of `s` is open. This is the finest topology that
  makes `f` continuous. -/
def TopologicalSpace.coinduced {α : Type u} {β : Type v} (f : α → β) (t : TopologicalSpace α) :
    TopologicalSpace β where
  IsOpen s := IsOpen[t] (f ⁻¹' s)
  isOpen_univ := t.isOpen_univ
  isOpen_inter s₁ s₂ h₁ h₂ := h₁.inter h₂
  isOpen_sUnion s h := by 

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
α : Type u
β : Type v
f : α → β
t : TopologicalSpace α
s : Set (Set β)
h : ∀ t_1 ∈ s, (fun s => IsOpen (f ⁻¹' s)) t_1
⊢ (fun s => IsOpen (f ⁻¹' s)) (⋃₀ s)

Next tactic:
simpa only [preimage_sUnion] using isOpen_biUnion h
theorem preimage_nhds_coinduced [TopologicalSpace α] {π : α → β} {s : Set β} {a : α}
    (hs : s ∈ @nhds β (TopologicalSpace.coinduced π ‹_›) (π a)) : π ⁻¹' s ∈ 𝓝 a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : TopologicalSpace α
π : α → β
s : Set β
a : α
hs : s ∈ 𝓝 (π a)
⊢ π ⁻¹' s ∈ 𝓝 a

Next tactic:
letI := TopologicalSpace.coinduced π ‹_›
theorem preimage_nhds_coinduced [TopologicalSpace α] {π : α → β} {s : Set β} {a : α}
    (hs : s ∈ @nhds β (TopologicalSpace.coinduced π ‹_›) (π a)) : π ⁻¹' s ∈ 𝓝 a := by
  letI := TopologicalSpace.coinduced π ‹_›
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : TopologicalSpace α
π : α → β
s : Set β
a : α
hs : s ∈ 𝓝 (π a)
this : TopologicalSpace β := TopologicalSpace.coinduced π inst✝
⊢ π ⁻¹' s ∈ 𝓝 a

Next tactic:
rcases mem_nhds_iff.mp hs with ⟨V, hVs, V_op, mem_V⟩
theorem preimage_nhds_coinduced [TopologicalSpace α] {π : α → β} {s : Set β} {a : α}
    (hs : s ∈ @nhds β (TopologicalSpace.coinduced π ‹_›) (π a)) : π ⁻¹' s ∈ 𝓝 a := by
  letI := TopologicalSpace.coinduced π ‹_›
  rcases mem_nhds_iff.mp hs with ⟨V, hVs, V_op, mem_V⟩
  

Proof state:
case intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝ : TopologicalSpace α
π : α → β
s : Set β
a : α
hs : s ∈ 𝓝 (π a)
this : TopologicalSpace β := TopologicalSpace.coinduced π inst✝
V : Set β
hVs : V ⊆ s
V_op : IsOpen V
mem_V : π a ∈ V
⊢ π ⁻¹' s ∈ 𝓝 a

Next tactic:
exact mem_nhds_iff.mpr ⟨π ⁻¹' V, Set.preimage_mono hVs, V_op, mem_V⟩
theorem Equiv.induced_symm {α β : Type*} (e : α ≃ β) :
    TopologicalSpace.induced e.symm = TopologicalSpace.coinduced e := by
  

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
t t₁ t₂ : TopologicalSpace α✝
t' : TopologicalSpace β✝
f : α✝ → β✝
g : β✝ → α✝
α : Type u_4
β : Type u_5
e : α ≃ β
⊢ TopologicalSpace.induced ⇑e.symm = TopologicalSpace.coinduced ⇑e

Next tactic:
ext t U
theorem Equiv.induced_symm {α β : Type*} (e : α ≃ β) :
    TopologicalSpace.induced e.symm = TopologicalSpace.coinduced e := by
  ext t U
  

Proof state:
case h.a.h.a
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
t✝ t₁ t₂ : TopologicalSpace α✝
t' : TopologicalSpace β✝
f : α✝ → β✝
g : β✝ → α✝
α : Type u_4
β : Type u_5
e : α ≃ β
t : TopologicalSpace α
U : Set β
⊢ IsOpen U ↔ IsOpen U

Next tactic:
rw [isOpen_induced_iff, isOpen_coinduced]
theorem Equiv.induced_symm {α β : Type*} (e : α ≃ β) :
    TopologicalSpace.induced e.symm = TopologicalSpace.coinduced e := by
  ext t U
  rw [isOpen_induced_iff, isOpen_coinduced]
  

Proof state:
case h.a.h.a
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
t✝ t₁ t₂ : TopologicalSpace α✝
t' : TopologicalSpace β✝
f : α✝ → β✝
g : β✝ → α✝
α : Type u_4
β : Type u_5
e : α ≃ β
t : TopologicalSpace α
U : Set β
⊢ (∃ t_1, IsOpen t_1 ∧ ⇑e.symm ⁻¹' t_1 = U) ↔ IsOpen (⇑e ⁻¹' U)

Next tactic:
simp only [e.symm.preimage_eq_iff_eq_image, exists_eq_right, ← preimage_equiv_eq_image_symm]
theorem le_induced_generateFrom {α β} [t : TopologicalSpace α] {b : Set (Set β)} {f : α → β}
    (h : ∀ a : Set β, a ∈ b → IsOpen (f ⁻¹' a)) : t ≤ induced f (generateFrom b) := by
  

Proof state:
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
t : TopologicalSpace α
b : Set (Set β)
f : α → β
h : ∀ a ∈ b, IsOpen (f ⁻¹' a)
⊢ t ≤ induced f (generateFrom b)

Next tactic:
rw [induced_generateFrom_eq]
theorem le_induced_generateFrom {α β} [t : TopologicalSpace α] {b : Set (Set β)} {f : α → β}
    (h : ∀ a : Set β, a ∈ b → IsOpen (f ⁻¹' a)) : t ≤ induced f (generateFrom b) := by
  rw [induced_generateFrom_eq]
  

Proof state:
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
t : TopologicalSpace α
b : Set (Set β)
f : α → β
h : ∀ a ∈ b, IsOpen (f ⁻¹' a)
⊢ t ≤ generateFrom (preimage f '' b)

Next tactic:
apply le_generateFrom
theorem le_induced_generateFrom {α β} [t : TopologicalSpace α] {b : Set (Set β)} {f : α → β}
    (h : ∀ a : Set β, a ∈ b → IsOpen (f ⁻¹' a)) : t ≤ induced f (generateFrom b) := by
  rw [induced_generateFrom_eq]
  apply le_generateFrom
  

Proof state:
case h
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
t : TopologicalSpace α
b : Set (Set β)
f : α → β
h : ∀ a ∈ b, IsOpen (f ⁻¹' a)
⊢ ∀ s ∈ preimage f '' b, IsOpen s

Next tactic:
simp only [mem_image, and_imp, forall_apply_eq_imp_iff₂, exists_imp]
theorem le_induced_generateFrom {α β} [t : TopologicalSpace α] {b : Set (Set β)} {f : α → β}
    (h : ∀ a : Set β, a ∈ b → IsOpen (f ⁻¹' a)) : t ≤ induced f (generateFrom b) := by
  rw [induced_generateFrom_eq]
  apply le_generateFrom
  simp only [mem_image, and_imp, forall_apply_eq_imp_iff₂, exists_imp]
  

Proof state:
case h
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
t : TopologicalSpace α
b : Set (Set β)
f : α → β
h : ∀ a ∈ b, IsOpen (f ⁻¹' a)
⊢ ∀ a ∈ b, IsOpen (f ⁻¹' a)

Next tactic:
exact h
theorem gc_nhds (a : α) : GaloisConnection (nhdsAdjoint a) fun t => @nhds α t a := fun f t => by
  

Proof state:
α : Type u
β : Type v
a : α
f : Filter α
t : TopologicalSpace α
⊢ nhdsAdjoint a f ≤ t ↔ f ≤ (fun t => 𝓝 a) t

Next tactic:
rw [le_nhds_iff]
theorem gc_nhds (a : α) : GaloisConnection (nhdsAdjoint a) fun t => @nhds α t a := fun f t => by
  rw [le_nhds_iff]
  

Proof state:
α : Type u
β : Type v
a : α
f : Filter α
t : TopologicalSpace α
⊢ nhdsAdjoint a f ≤ t ↔ ∀ (s : Set α), a ∈ s → IsOpen s → s ∈ f

Next tactic:
exact ⟨fun H s hs has => H _ has hs, fun H s has hs => H _ hs has⟩
theorem nhdsAdjoint_nhds {α : Type*} (a : α) (f : Filter α) :
    @nhds α (nhdsAdjoint a f) a = pure a ⊔ f := by
  

Proof state:
α✝ : Type u
β : Type v
α : Type u_1
a : α
f : Filter α
⊢ 𝓝 a = pure a ⊔ f

Next tactic:
letI := nhdsAdjoint a f
theorem nhdsAdjoint_nhds {α : Type*} (a : α) (f : Filter α) :
    @nhds α (nhdsAdjoint a f) a = pure a ⊔ f := by
  letI := nhdsAdjoint a f
  

Proof state:
α✝ : Type u
β : Type v
α : Type u_1
a : α
f : Filter α
this : TopologicalSpace α := nhdsAdjoint a f
⊢ 𝓝 a = pure a ⊔ f

Next tactic:
ext U
theorem nhdsAdjoint_nhds {α : Type*} (a : α) (f : Filter α) :
    @nhds α (nhdsAdjoint a f) a = pure a ⊔ f := by
  letI := nhdsAdjoint a f
  ext U
  

Proof state:
case a
α✝ : Type u
β : Type v
α : Type u_1
a : α
f : Filter α
this : TopologicalSpace α := nhdsAdjoint a f
U : Set α
⊢ U ∈ 𝓝 a ↔ U ∈ pure a ⊔ f

Next tactic:
rw [mem_nhds_iff]
theorem nhdsAdjoint_nhds {α : Type*} (a : α) (f : Filter α) :
    @nhds α (nhdsAdjoint a f) a = pure a ⊔ f := by
  letI := nhdsAdjoint a f
  ext U
  rw [mem_nhds_iff]
  

Proof state:
case a
α✝ : Type u
β : Type v
α : Type u_1
a : α
f : Filter α
this : TopologicalSpace α := nhdsAdjoint a f
U : Set α
⊢ (∃ t ⊆ U, IsOpen t ∧ a ∈ t) ↔ U ∈ pure a ⊔ f

Next tactic:
constructor
theorem nhdsAdjoint_nhds {α : Type*} (a : α) (f : Filter α) :
    @nhds α (nhdsAdjoint a f) a = pure a ⊔ f := by
  letI := nhdsAdjoint a f
  ext U
  rw [mem_nhds_iff]
  constructor
  · 

Proof state:
case a.mp
α✝ : Type u
β : Type v
α : Type u_1
a : α
f : Filter α
this : TopologicalSpace α := nhdsAdjoint a f
U : Set α
⊢ (∃ t ⊆ U, IsOpen t ∧ a ∈ t) → U ∈ pure a ⊔ f

Next tactic:
rintro ⟨t, htU, ht, hat⟩
theorem nhdsAdjoint_nhds {α : Type*} (a : α) (f : Filter α) :
    @nhds α (nhdsAdjoint a f) a = pure a ⊔ f := by
  letI := nhdsAdjoint a f
  ext U
  rw [mem_nhds_iff]
  constructor
  · rintro ⟨t, htU, ht, hat⟩
    

Proof state:
case a.mp.intro.intro.intro
α✝ : Type u
β : Type v
α : Type u_1
a : α
f : Filter α
this : TopologicalSpace α := nhdsAdjoint a f
U t : Set α
htU : t ⊆ U
ht : IsOpen t
hat : a ∈ t
⊢ U ∈ pure a ⊔ f

Next tactic:
exact ⟨htU hat, mem_of_superset (ht hat) htU⟩