l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem interior_iInter_of_finite {ι : Type*} [Finite ι] (f : ι → Set α) :
    interior (⋂ i, f i) = ⋂ i, interior (f i) := by
  

Proof state:
α : Type u
β : Type v
ι✝ : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝¹ : TopologicalSpace α
ι : Type u_1
inst✝ : Finite ι
f : ι → Set α
⊢ interior (⋂ i, f i) = ⋂ i, interior (f i)

Next tactic:
cases nonempty_fintype ι
@[simp]
theorem interior_iInter_of_finite {ι : Type*} [Finite ι] (f : ι → Set α) :
    interior (⋂ i, f i) = ⋂ i, interior (f i) := by
  cases nonempty_fintype ι
  

Proof state:
case intro
α : Type u
β : Type v
ι✝ : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝¹ : TopologicalSpace α
ι : Type u_1
inst✝ : Finite ι
f : ι → Set α
val✝ : Fintype ι
⊢ interior (⋂ i, f i) = ⋂ i, interior (f i)

Next tactic:
convert Finset.univ.interior_iInter f
@[simp]
theorem interior_iInter_of_finite {ι : Type*} [Finite ι] (f : ι → Set α) :
    interior (⋂ i, f i) = ⋂ i, interior (f i) := by
  cases nonempty_fintype ι
  convert Finset.univ.interior_iInter f <;> 

Proof state:
case h.e'_2.h.e'_3.h.e'_3.h
α : Type u
β : Type v
ι✝ : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝¹ : TopologicalSpace α
ι : Type u_1
inst✝ : Finite ι
f : ι → Set α
val✝ : Fintype ι
x✝ : ι
⊢ f x✝ = ⋂ (_ : x✝ ∈ Finset.univ), f x✝

Next tactic:
simp
@[simp]
theorem interior_iInter_of_finite {ι : Type*} [Finite ι] (f : ι → Set α) :
    interior (⋂ i, f i) = ⋂ i, interior (f i) := by
  cases nonempty_fintype ι
  convert Finset.univ.interior_iInter f <;> 

Proof state:
case h.e'_3.h.e'_3.h
α : Type u
β : Type v
ι✝ : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝¹ : TopologicalSpace α
ι : Type u_1
inst✝ : Finite ι
f : ι → Set α
val✝ : Fintype ι
x✝ : ι
⊢ interior (f x✝) = ⋂ (_ : x✝ ∈ Finset.univ), interior (f x✝)

Next tactic:
simp
theorem interior_union_isClosed_of_interior_empty {s t : Set α} (h₁ : IsClosed s)
    (h₂ : interior t = ∅) : interior (s ∪ t) = interior s :=
  have : interior (s ∪ t) ⊆ s := fun x ⟨u, ⟨(hu₁ : IsOpen u), (hu₂ : u ⊆ s ∪ t)⟩, (hx₁ : x ∈ u)⟩ =>
    by_contradiction fun hx₂ : x ∉ s =>
      have : u \ s ⊆ t := fun x ⟨h₁, h₂⟩ => Or.resolve_left (hu₂ h₁) h₂
      have : u \ s ⊆ interior t := by 

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t✝ : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s t : Set α
h₁ : IsClosed s
h₂ : interior t = ∅
x : α
x✝ : x ∈ interior (s ∪ t)
u : Set α
hu₁ : IsOpen u
hu₂ : u ⊆ s ∪ t
hx₁ : x ∈ u
hx₂ : x ∉ s
this : u \ s ⊆ t
⊢ u \ s ⊆ interior t

Next tactic:
rwa [(IsOpen.sdiff hu₁ h₁).subset_interior_iff]
theorem interior_union_isClosed_of_interior_empty {s t : Set α} (h₁ : IsClosed s)
    (h₂ : interior t = ∅) : interior (s ∪ t) = interior s :=
  have : interior (s ∪ t) ⊆ s := fun x ⟨u, ⟨(hu₁ : IsOpen u), (hu₂ : u ⊆ s ∪ t)⟩, (hx₁ : x ∈ u)⟩ =>
    by_contradiction fun hx₂ : x ∉ s =>
      have : u \ s ⊆ t := fun x ⟨h₁, h₂⟩ => Or.resolve_left (hu₂ h₁) h₂
      have : u \ s ⊆ interior t := by rwa [(IsOpen.sdiff hu₁ h₁).subset_interior_iff]
      have : u \ s ⊆ ∅ := by 

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t✝ : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s t : Set α
h₁ : IsClosed s
h₂ : interior t = ∅
x : α
x✝ : x ∈ interior (s ∪ t)
u : Set α
hu₁ : IsOpen u
hu₂ : u ⊆ s ∪ t
hx₁ : x ∈ u
hx₂ : x ∉ s
this✝ : u \ s ⊆ t
this : u \ s ⊆ interior t
⊢ u \ s ⊆ ∅

Next tactic:
rwa [h₂] at this
theorem isOpen_iff_forall_mem_open : IsOpen s ↔ ∀ x ∈ s, ∃ t, t ⊆ s ∧ IsOpen t ∧ x ∈ t := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
⊢ IsOpen s ↔ ∀ x ∈ s, ∃ t ⊆ s, IsOpen t ∧ x ∈ t

Next tactic:
rw [← subset_interior_iff_isOpen]
theorem isOpen_iff_forall_mem_open : IsOpen s ↔ ∀ x ∈ s, ∃ t, t ⊆ s ∧ IsOpen t ∧ x ∈ t := by
  rw [← subset_interior_iff_isOpen]
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
⊢ s ⊆ interior s ↔ ∀ x ∈ s, ∃ t ⊆ s, IsOpen t ∧ x ∈ t

Next tactic:
simp only [subset_def, mem_interior]
theorem interior_sInter_subset (S : Set (Set α)) : interior (⋂₀ S) ⊆ ⋂ s ∈ S, interior s :=
  calc
    interior (⋂₀ S) = interior (⋂ s ∈ S, s) := by 

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
S : Set (Set α)
⊢ interior (⋂₀ S) = interior (⋂ s ∈ S, s)

Next tactic:
rw [sInter_eq_biInter]
theorem diff_subset_closure_iff {s t : Set α} : s \ t ⊆ closure t ↔ s ⊆ closure t := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t✝ : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s t : Set α
⊢ s \ t ⊆ closure t ↔ s ⊆ closure t

Next tactic:
rw [diff_subset_iff, union_eq_self_of_subset_left subset_closure]
theorem isClosed_of_closure_subset {s : Set α} (h : closure s ⊆ s) : IsClosed s := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : closure s ⊆ s
⊢ IsClosed s

Next tactic:
rw [subset_closure.antisymm h]
theorem isClosed_of_closure_subset {s : Set α} (h : closure s ⊆ s) : IsClosed s := by
  rw [subset_closure.antisymm h]; 

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : closure s ⊆ s
⊢ IsClosed (closure s)

Next tactic:
exact isClosed_closure
@[simp]
theorem closure_nonempty_iff {s : Set α} : (closure s).Nonempty ↔ s.Nonempty := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ Set.Nonempty (closure s) ↔ Set.Nonempty s

Next tactic:
simp only [nonempty_iff_ne_empty, Ne.def, closure_empty_iff]
@[simp]
theorem Finset.closure_biUnion {ι : Type*} (s : Finset ι) (f : ι → Set α) :
    closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i) := by
  

Proof state:
α : Type u
β : Type v
ι✝ : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
ι : Type u_1
s : Finset ι
f : ι → Set α
⊢ closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i)

Next tactic:
classical
    refine' s.induction_on (by simp) _
    intro i s _ h₂
    simp [h₂]
@[simp]
theorem Finset.closure_biUnion {ι : Type*} (s : Finset ι) (f : ι → Set α) :
    closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i) := by
  classical
    

Proof state:
α : Type u
β : Type v
ι✝ : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
ι : Type u_1
s : Finset ι
f : ι → Set α
⊢ closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i)

Next tactic:
refine' s.induction_on (by simp) _
@[simp]
theorem Finset.closure_biUnion {ι : Type*} (s : Finset ι) (f : ι → Set α) :
    closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i) := by
  classical
    refine' s.induction_on (by 

Proof state:
α : Type u
β : Type v
ι✝ : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
ι : Type u_1
s : Finset ι
f : ι → Set α
⊢ closure (⋃ i ∈ ∅, f i) = ⋃ i ∈ ∅, closure (f i)

Next tactic:
simp
@[simp]
theorem Finset.closure_biUnion {ι : Type*} (s : Finset ι) (f : ι → Set α) :
    closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i) := by
  classical
    refine' s.induction_on (by simp) _
    

Proof state:
α : Type u
β : Type v
ι✝ : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
ι : Type u_1
s : Finset ι
f : ι → Set α
⊢ ∀ ⦃a : ι⦄ {s : Finset ι},
    a ∉ s →
      closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i) →
        closure (⋃ i ∈ insert a s, f i) = ⋃ i ∈ insert a s, closure (f i)

Next tactic:
intro i s _ h₂
@[simp]
theorem Finset.closure_biUnion {ι : Type*} (s : Finset ι) (f : ι → Set α) :
    closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i) := by
  classical
    refine' s.induction_on (by simp) _
    intro i s _ h₂
    

Proof state:
α : Type u
β : Type v
ι✝ : Sort w
a : α
s✝¹ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
ι : Type u_1
s✝ : Finset ι
f : ι → Set α
i : ι
s : Finset ι
a✝ : i ∉ s
h₂ : closure (⋃ i ∈ s, f i) = ⋃ i ∈ s, closure (f i)
⊢ closure (⋃ i_1 ∈ insert i s, f i_1) = ⋃ i_1 ∈ insert i s, closure (f i_1)

Next tactic:
simp [h₂]
@[simp]
theorem closure_iUnion_of_finite {ι : Type*} [Finite ι] (f : ι → Set α) :
    closure (⋃ i, f i) = ⋃ i, closure (f i) := by
  

Proof state:
α : Type u
β : Type v
ι✝ : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝¹ : TopologicalSpace α
ι : Type u_1
inst✝ : Finite ι
f : ι → Set α
⊢ closure (⋃ i, f i) = ⋃ i, closure (f i)

Next tactic:
cases nonempty_fintype ι
@[simp]
theorem closure_iUnion_of_finite {ι : Type*} [Finite ι] (f : ι → Set α) :
    closure (⋃ i, f i) = ⋃ i, closure (f i) := by
  cases nonempty_fintype ι
  

Proof state:
case intro
α : Type u
β : Type v
ι✝ : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝¹ : TopologicalSpace α
ι : Type u_1
inst✝ : Finite ι
f : ι → Set α
val✝ : Fintype ι
⊢ closure (⋃ i, f i) = ⋃ i, closure (f i)

Next tactic:
convert Finset.univ.closure_biUnion f
@[simp]
theorem closure_iUnion_of_finite {ι : Type*} [Finite ι] (f : ι → Set α) :
    closure (⋃ i, f i) = ⋃ i, closure (f i) := by
  cases nonempty_fintype ι
  convert Finset.univ.closure_biUnion f <;> 

Proof state:
case h.e'_2.h.e'_3.h.e'_3.h
α : Type u
β : Type v
ι✝ : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝¹ : TopologicalSpace α
ι : Type u_1
inst✝ : Finite ι
f : ι → Set α
val✝ : Fintype ι
x✝ : ι
⊢ f x✝ = ⋃ (_ : x✝ ∈ Finset.univ), f x✝

Next tactic:
simp
@[simp]
theorem closure_iUnion_of_finite {ι : Type*} [Finite ι] (f : ι → Set α) :
    closure (⋃ i, f i) = ⋃ i, closure (f i) := by
  cases nonempty_fintype ι
  convert Finset.univ.closure_biUnion f <;> 

Proof state:
case h.e'_3.h.e'_3.h
α : Type u
β : Type v
ι✝ : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝¹ : TopologicalSpace α
ι : Type u_1
inst✝ : Finite ι
f : ι → Set α
val✝ : Fintype ι
x✝ : ι
⊢ closure (f x✝) = ⋃ (_ : x✝ ∈ Finset.univ), closure (f x✝)

Next tactic:
simp
theorem closure_eq_compl_interior_compl {s : Set α} : closure s = (interior sᶜ)ᶜ := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ closure s = (interior sᶜ)ᶜ

Next tactic:
rw [interior, closure, compl_sUnion, compl_image_set_of]
theorem closure_eq_compl_interior_compl {s : Set α} : closure s = (interior sᶜ)ᶜ := by
  rw [interior, closure, compl_sUnion, compl_image_set_of]
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ ⋂₀ {t | IsClosed t ∧ s ⊆ t} = ⋂₀ {s_1 | IsOpen s_1ᶜ ∧ s_1ᶜ ⊆ sᶜ}

Next tactic:
simp only [compl_subset_compl, isOpen_compl_iff]
@[simp]
theorem interior_compl {s : Set α} : interior sᶜ = (closure s)ᶜ := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ interior sᶜ = (closure s)ᶜ

Next tactic:
simp [closure_eq_compl_interior_compl]
@[simp]
theorem closure_compl {s : Set α} : closure sᶜ = (interior s)ᶜ := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ closure sᶜ = (interior s)ᶜ

Next tactic:
simp [closure_eq_compl_interior_compl]
@[simp]
theorem Filter.lift'_closure_eq_bot {l : Filter α} : l.lift' closure = ⊥ ↔ l = ⊥ :=
  ⟨fun h => bot_unique <| h ▸ l.le_lift'_closure, fun h =>
    h.symm ▸ by 

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
l : Filter α
h : l = ⊥
⊢ Filter.lift' ⊥ closure = ⊥

Next tactic:
rw [lift'_bot (monotone_closure _), closure_empty, principal_empty]
theorem interior_eq_empty_iff_dense_compl {s : Set α} : interior s = ∅ ↔ Dense sᶜ := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ interior s = ∅ ↔ Dense sᶜ

Next tactic:
rw [dense_iff_closure_eq, closure_compl, compl_univ_iff]
theorem Dense.interior_compl {s : Set α} (h : Dense s) : interior sᶜ = ∅ :=
  interior_eq_empty_iff_dense_compl.2 <| by 

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : Dense s
⊢ Dense sᶜᶜ

Next tactic:
rwa [compl_compl]
/-- The closure of a set `s` is dense if and only if `s` is dense. -/
@[simp]
theorem dense_closure {s : Set α} : Dense (closure s) ↔ Dense s := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ Dense (closure s) ↔ Dense s

Next tactic:
rw [Dense, Dense, closure_closure]
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ Dense s ↔ ∀ (U : Set α), IsOpen U → Set.Nonempty U → Set.Nonempty (U ∩ s)

Next tactic:
constructor
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  constructor <;> 

Proof state:
case mp
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ Dense s → ∀ (U : Set α), IsOpen U → Set.Nonempty U → Set.Nonempty (U ∩ s)

Next tactic:
intro h
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  constructor <;> 

Proof state:
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ (∀ (U : Set α), IsOpen U → Set.Nonempty U → Set.Nonempty (U ∩ s)) → Dense s

Next tactic:
intro h
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  constructor <;> intro h
  · 

Proof state:
case mp
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : Dense s
⊢ ∀ (U : Set α), IsOpen U → Set.Nonempty U → Set.Nonempty (U ∩ s)

Next tactic:
rintro U U_op ⟨x, x_in⟩
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  constructor <;> intro h
  · rintro U U_op ⟨x, x_in⟩
    

Proof state:
case mp.intro
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : Dense s
U : Set α
U_op : IsOpen U
x : α
x_in : x ∈ U
⊢ Set.Nonempty (U ∩ s)

Next tactic:
exact mem_closure_iff.1 (h _) U U_op x_in
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  constructor <;> intro h
  · rintro U U_op ⟨x, x_in⟩
    exact mem_closure_iff.1 (h _) U U_op x_in
  · 

Proof state:
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : ∀ (U : Set α), IsOpen U → Set.Nonempty U → Set.Nonempty (U ∩ s)
⊢ Dense s

Next tactic:
intro x
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  constructor <;> intro h
  · rintro U U_op ⟨x, x_in⟩
    exact mem_closure_iff.1 (h _) U U_op x_in
  · intro x
    

Proof state:
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : ∀ (U : Set α), IsOpen U → Set.Nonempty U → Set.Nonempty (U ∩ s)
x : α
⊢ x ∈ closure s

Next tactic:
rw [mem_closure_iff]
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  constructor <;> intro h
  · rintro U U_op ⟨x, x_in⟩
    exact mem_closure_iff.1 (h _) U U_op x_in
  · intro x
    rw [mem_closure_iff]
    

Proof state:
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : ∀ (U : Set α), IsOpen U → Set.Nonempty U → Set.Nonempty (U ∩ s)
x : α
⊢ ∀ (o : Set α), IsOpen o → x ∈ o → Set.Nonempty (o ∩ s)

Next tactic:
intro U U_op x_in
/-- A set is dense if and only if it has a nonempty intersection with each nonempty open set. -/
theorem dense_iff_inter_open {s : Set α} :
    Dense s ↔ ∀ U, IsOpen U → U.Nonempty → (U ∩ s).Nonempty := by
  constructor <;> intro h
  · rintro U U_op ⟨x, x_in⟩
    exact mem_closure_iff.1 (h _) U U_op x_in
  · intro x
    rw [mem_closure_iff]
    intro U U_op x_in
    

Proof state:
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
h : ∀ (U : Set α), IsOpen U → Set.Nonempty U → Set.Nonempty (U ∩ s)
x : α
U : Set α
U_op : IsOpen U
x_in : x ∈ U
⊢ Set.Nonempty (U ∩ s)

Next tactic:
exact h U U_op ⟨_, x_in⟩
/-- Complement to a singleton is dense if and only if the singleton is not an open set. -/
theorem dense_compl_singleton_iff_not_open {x : α} :
    Dense ({x}ᶜ : Set α) ↔ ¬IsOpen ({x} : Set α) := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
x : α
⊢ Dense {x}ᶜ ↔ ¬IsOpen {x}

Next tactic:
constructor
/-- Complement to a singleton is dense if and only if the singleton is not an open set. -/
theorem dense_compl_singleton_iff_not_open {x : α} :
    Dense ({x}ᶜ : Set α) ↔ ¬IsOpen ({x} : Set α) := by
  constructor
  · 

Proof state:
case mp
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
x : α
⊢ Dense {x}ᶜ → ¬IsOpen {x}

Next tactic:
intro hd ho
/-- Complement to a singleton is dense if and only if the singleton is not an open set. -/
theorem dense_compl_singleton_iff_not_open {x : α} :
    Dense ({x}ᶜ : Set α) ↔ ¬IsOpen ({x} : Set α) := by
  constructor
  · intro hd ho
    

Proof state:
case mp
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
x : α
hd : Dense {x}ᶜ
ho : IsOpen {x}
⊢ False

Next tactic:
exact (hd.inter_open_nonempty _ ho (singleton_nonempty _)).ne_empty (inter_compl_self _)
/-- Complement to a singleton is dense if and only if the singleton is not an open set. -/
theorem dense_compl_singleton_iff_not_open {x : α} :
    Dense ({x}ᶜ : Set α) ↔ ¬IsOpen ({x} : Set α) := by
  constructor
  · intro hd ho
    exact (hd.inter_open_nonempty _ ho (singleton_nonempty _)).ne_empty (inter_compl_self _)
  · 

Proof state:
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
x : α
⊢ ¬IsOpen {x} → Dense {x}ᶜ

Next tactic:
refine' fun ho => dense_iff_inter_open.2 fun U hU hne => inter_compl_nonempty_iff.2 fun hUx => _
/-- Complement to a singleton is dense if and only if the singleton is not an open set. -/
theorem dense_compl_singleton_iff_not_open {x : α} :
    Dense ({x}ᶜ : Set α) ↔ ¬IsOpen ({x} : Set α) := by
  constructor
  · intro hd ho
    exact (hd.inter_open_nonempty _ ho (singleton_nonempty _)).ne_empty (inter_compl_self _)
  · refine' fun ho => dense_iff_inter_open.2 fun U hU hne => inter_compl_nonempty_iff.2 fun hUx => _
    

Proof state:
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
x : α
ho : ¬IsOpen {x}
U : Set α
hU : IsOpen U
hne : Set.Nonempty U
hUx : U ⊆ {x}
⊢ False

Next tactic:
obtain rfl : U = {x}
/-- Complement to a singleton is dense if and only if the singleton is not an open set. -/
theorem dense_compl_singleton_iff_not_open {x : α} :
    Dense ({x}ᶜ : Set α) ↔ ¬IsOpen ({x} : Set α) := by
  constructor
  · intro hd ho
    exact (hd.inter_open_nonempty _ ho (singleton_nonempty _)).ne_empty (inter_compl_self _)
  · refine' fun ho => dense_iff_inter_open.2 fun U hU hne => inter_compl_nonempty_iff.2 fun hUx => _
    obtain rfl : U = {x}
    

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
x : α
ho : ¬IsOpen {x}
U : Set α
hU : IsOpen U
hne : Set.Nonempty U
hUx : U ⊆ {x}
⊢ U = {x}
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
x : α
ho : ¬IsOpen {x}
hU : IsOpen {x}
hne : Set.Nonempty {x}
hUx : {x} ⊆ {x}
⊢ False

Next tactic:
exact eq_singleton_iff_nonempty_unique_mem.2 ⟨hne, hUx⟩
/-- Complement to a singleton is dense if and only if the singleton is not an open set. -/
theorem dense_compl_singleton_iff_not_open {x : α} :
    Dense ({x}ᶜ : Set α) ↔ ¬IsOpen ({x} : Set α) := by
  constructor
  · intro hd ho
    exact (hd.inter_open_nonempty _ ho (singleton_nonempty _)).ne_empty (inter_compl_self _)
  · refine' fun ho => dense_iff_inter_open.2 fun U hU hne => inter_compl_nonempty_iff.2 fun hUx => _
    obtain rfl : U = {x}
    exact eq_singleton_iff_nonempty_unique_mem.2 ⟨hne, hUx⟩
    

Proof state:
case mpr
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
x : α
ho : ¬IsOpen {x}
hU : IsOpen {x}
hne : Set.Nonempty {x}
hUx : {x} ⊆ {x}
⊢ False

Next tactic:
exact ho hU
/-- Interior and frontier are disjoint. -/
lemma disjoint_interior_frontier : Disjoint (interior s) (frontier s) := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
⊢ Disjoint (interior s) (frontier s)

Next tactic:
rw [disjoint_iff_inter_eq_empty, ← closure_diff_interior, diff_eq,
    ← inter_assoc, inter_comm, ← inter_assoc, compl_inter_self, empty_inter]
@[simp]
theorem closure_diff_frontier (s : Set α) : closure s \ frontier s = interior s := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ closure s \ frontier s = interior s

Next tactic:
rw [frontier, diff_diff_right_self, inter_eq_self_of_subset_right interior_subset_closure]
@[simp]
theorem self_diff_frontier (s : Set α) : s \ frontier s = interior s := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ s \ frontier s = interior s

Next tactic:
rw [frontier, diff_diff_right, diff_eq_empty.2 subset_closure,
    inter_eq_self_of_subset_right interior_subset, empty_union]
theorem frontier_eq_closure_inter_closure {s : Set α} : frontier s = closure s ∩ closure sᶜ := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ frontier s = closure s ∩ closure sᶜ

Next tactic:
rw [closure_compl, frontier, diff_eq]
/-- The complement of a set has the same frontier as the original set. -/
@[simp]
theorem frontier_compl (s : Set α) : frontier sᶜ = frontier s := by
  

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s✝ s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
s : Set α
⊢ frontier sᶜ = frontier s

Next tactic:
simp only [frontier_eq_closure_inter_closure, compl_compl, inter_comm]
@[simp]
theorem frontier_univ : frontier (univ : Set α) = ∅ := by 

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
⊢ frontier univ = ∅

Next tactic:
simp [frontier]
@[simp]
theorem frontier_empty : frontier (∅ : Set α) = ∅ := by 

Proof state:
α : Type u
β : Type v
ι : Sort w
a : α
s s₁ s₂ t : Set α
p p₁ p₂ : α → Prop
inst✝ : TopologicalSpace α
⊢ frontier ∅ = ∅

Next tactic:
simp [frontier]