l3lab/ntp-mathlib huggingface dataset:
/-- The monoidal structure coming from finite coproducts is symmetric.
-/
@[simps]
def symmetricOfHasFiniteCoproducts [HasInitial C] [HasBinaryCoproducts C] :
    SymmetricCategory C where
  braiding := Limits.coprod.braiding
  braiding_naturality f g := by dsimp [tensorHom]; simp
  hexagon_forward X Y Z := by dsimp [monoidalOfHasFiniteCoproducts.associator_hom]; simp
  hexagon_reverse X Y Z := by dsimp [monoidalOfHasFiniteCoproducts.associator_inv]; simp
  symmetry X Y := by dsimp; 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y✝ : C
inst✝¹ : HasInitial C
inst✝ : HasBinaryCoproducts C
X Y : C
⊢ coprod.desc coprod.inr coprod.inl ≫ coprod.desc coprod.inr coprod.inl = 𝟙 (X ⨿ Y)

Next tactic:
simp
theorem isInvariant_iff_image : IsInvariant ϕ s ↔ ∀ t, ϕ t '' s ⊆ s := by
  

Proof state:
τ : Type u_1
α : Type u_2
ϕ : τ → α → α
s : Set α
⊢ IsInvariant ϕ s ↔ ∀ (t : τ), ϕ t '' s ⊆ s

Next tactic:
simp_rw [IsInvariant, mapsTo']
@[ext]
theorem ext : ∀ {ϕ₁ ϕ₂ : Flow τ α}, (∀ t x, ϕ₁ t x = ϕ₂ t x) → ϕ₁ = ϕ₂
  | ⟨f₁, _, _, _⟩, ⟨f₂, _, _, _⟩, h => by
    

Proof state:
τ : Type u_1
inst✝³ : AddMonoid τ
inst✝² : TopologicalSpace τ
inst✝¹ : ContinuousAdd τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
f₁ : τ → α → α
cont'✝¹ : Continuous (uncurry f₁)
map_add'✝¹ : ∀ (t₁ t₂ : τ) (x : α), f₁ (t₁ + t₂) x = f₁ t₁ (f₁ t₂ x)
map_zero'✝¹ : ∀ (x : α), f₁ 0 x = x
f₂ : τ → α → α
cont'✝ : Continuous (uncurry f₂)
map_add'✝ : ∀ (t₁ t₂ : τ) (x : α), f₂ (t₁ + t₂) x = f₂ t₁ (f₂ t₂ x)
map_zero'✝ : ∀ (x : α), f₂ 0 x = x
h :
  ∀ (t : τ) (x : α),
    toFun { toFun := f₁, cont' := cont'✝¹, map_add' := map_add'✝¹, map_zero' := map_zero'✝¹ } t x =
      toFun { toFun := f₂, cont' := cont'✝, map_add' := map_add'✝, map_zero' := map_zero'✝ } t x
⊢ { toFun := f₁, cont' := cont'✝¹, map_add' := map_add'✝¹, map_zero' := map_zero'✝¹ } =
    { toFun := f₂, cont' := cont'✝, map_add' := map_add'✝, map_zero' := map_zero'✝ }

Next tactic:
congr
@[ext]
theorem ext : ∀ {ϕ₁ ϕ₂ : Flow τ α}, (∀ t x, ϕ₁ t x = ϕ₂ t x) → ϕ₁ = ϕ₂
  | ⟨f₁, _, _, _⟩, ⟨f₂, _, _, _⟩, h => by
    congr
    

Proof state:
case e_toFun
τ : Type u_1
inst✝³ : AddMonoid τ
inst✝² : TopologicalSpace τ
inst✝¹ : ContinuousAdd τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
f₁ : τ → α → α
cont'✝¹ : Continuous (uncurry f₁)
map_add'✝¹ : ∀ (t₁ t₂ : τ) (x : α), f₁ (t₁ + t₂) x = f₁ t₁ (f₁ t₂ x)
map_zero'✝¹ : ∀ (x : α), f₁ 0 x = x
f₂ : τ → α → α
cont'✝ : Continuous (uncurry f₂)
map_add'✝ : ∀ (t₁ t₂ : τ) (x : α), f₂ (t₁ + t₂) x = f₂ t₁ (f₂ t₂ x)
map_zero'✝ : ∀ (x : α), f₂ 0 x = x
h :
  ∀ (t : τ) (x : α),
    toFun { toFun := f₁, cont' := cont'✝¹, map_add' := map_add'✝¹, map_zero' := map_zero'✝¹ } t x =
      toFun { toFun := f₂, cont' := cont'✝, map_add' := map_add'✝, map_zero' := map_zero'✝ } t x
⊢ f₁ = f₂

Next tactic:
funext
@[ext]
theorem ext : ∀ {ϕ₁ ϕ₂ : Flow τ α}, (∀ t x, ϕ₁ t x = ϕ₂ t x) → ϕ₁ = ϕ₂
  | ⟨f₁, _, _, _⟩, ⟨f₂, _, _, _⟩, h => by
    congr
    funext
    

Proof state:
case e_toFun.h.h
τ : Type u_1
inst✝³ : AddMonoid τ
inst✝² : TopologicalSpace τ
inst✝¹ : ContinuousAdd τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
f₁ : τ → α → α
cont'✝¹ : Continuous (uncurry f₁)
map_add'✝¹ : ∀ (t₁ t₂ : τ) (x : α), f₁ (t₁ + t₂) x = f₁ t₁ (f₁ t₂ x)
map_zero'✝¹ : ∀ (x : α), f₁ 0 x = x
f₂ : τ → α → α
cont'✝ : Continuous (uncurry f₂)
map_add'✝ : ∀ (t₁ t₂ : τ) (x : α), f₂ (t₁ + t₂) x = f₂ t₁ (f₂ t₂ x)
map_zero'✝ : ∀ (x : α), f₂ 0 x = x
h :
  ∀ (t : τ) (x : α),
    toFun { toFun := f₁, cont' := cont'✝¹, map_add' := map_add'✝¹, map_zero' := map_zero'✝¹ } t x =
      toFun { toFun := f₂, cont' := cont'✝, map_add' := map_add'✝, map_zero' := map_zero'✝ } t x
x✝¹ : τ
x✝ : α
⊢ f₁ x✝¹ x✝ = f₂ x✝¹ x✝

Next tactic:
exact h _ _
theorem isInvariant_iff_image_eq (s : Set α) : IsInvariant ϕ s ↔ ∀ t, ϕ t '' s = s :=
  (isInvariant_iff_image _ _).trans
    (Iff.intro
      (fun h t => Subset.antisymm (h t) fun _ hx => ⟨_, h (-t) ⟨_, hx, rfl⟩, by 

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
s : Set α
h : ∀ (t : τ), toFun ϕ t '' s ⊆ s
t : τ
x✝ : α
hx : x✝ ∈ s
⊢ toFun ϕ t (toFun ϕ (-t) x✝) = x✝

Next tactic:
simp [← map_add]
theorem isInvariant_iff_image_eq (s : Set α) : IsInvariant ϕ s ↔ ∀ t, ϕ t '' s = s :=
  (isInvariant_iff_image _ _).trans
    (Iff.intro
      (fun h t => Subset.antisymm (h t) fun _ hx => ⟨_, h (-t) ⟨_, hx, rfl⟩, by simp [← map_add]⟩)
      fun h t => by 

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
s : Set α
h : ∀ (t : τ), toFun ϕ t '' s = s
t : τ
⊢ toFun ϕ t '' s ⊆ s

Next tactic:
rw [h t]
/-- The time-reversal of a flow `ϕ` by a (commutative, additive) group
    is defined `ϕ.reverse t x = ϕ (-t) x`. -/
def reverse : Flow τ α where
  toFun t := ϕ (-t)
  cont' := ϕ.continuous continuous_fst.neg continuous_snd
  map_add' _ _ _ := by 

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
x✝² x✝¹ : τ
x✝ : α
⊢ (fun t => toFun ϕ (-t)) (x✝² + x✝¹) x✝ = (fun t => toFun ϕ (-t)) x✝² ((fun t => toFun ϕ (-t)) x✝¹ x✝)

Next tactic:
dsimp
/-- The time-reversal of a flow `ϕ` by a (commutative, additive) group
    is defined `ϕ.reverse t x = ϕ (-t) x`. -/
def reverse : Flow τ α where
  toFun t := ϕ (-t)
  cont' := ϕ.continuous continuous_fst.neg continuous_snd
  map_add' _ _ _ := by dsimp; 

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
x✝² x✝¹ : τ
x✝ : α
⊢ toFun ϕ (-(x✝² + x✝¹)) x✝ = toFun ϕ (-x✝²) (toFun ϕ (-x✝¹) x✝)

Next tactic:
rw [neg_add, map_add]
/-- The time-reversal of a flow `ϕ` by a (commutative, additive) group
    is defined `ϕ.reverse t x = ϕ (-t) x`. -/
def reverse : Flow τ α where
  toFun t := ϕ (-t)
  cont' := ϕ.continuous continuous_fst.neg continuous_snd
  map_add' _ _ _ := by dsimp; rw [neg_add, map_add]
  map_zero' _ := by 

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
x✝ : α
⊢ (fun t => toFun ϕ (-t)) 0 x✝ = x✝

Next tactic:
dsimp
/-- The time-reversal of a flow `ϕ` by a (commutative, additive) group
    is defined `ϕ.reverse t x = ϕ (-t) x`. -/
def reverse : Flow τ α where
  toFun t := ϕ (-t)
  cont' := ϕ.continuous continuous_fst.neg continuous_snd
  map_add' _ _ _ := by dsimp; rw [neg_add, map_add]
  map_zero' _ := by dsimp; 

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
x✝ : α
⊢ toFun ϕ (-0) x✝ = x✝

Next tactic:
rw [neg_zero, map_zero_apply]
@[continuity]
theorem continuous_toFun (t : τ) : Continuous (ϕ.toFun t) := by
  

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
t : τ
⊢ Continuous (toFun ϕ t)

Next tactic:
rw [← curry_uncurry ϕ.toFun]
@[continuity]
theorem continuous_toFun (t : τ) : Continuous (ϕ.toFun t) := by
  rw [← curry_uncurry ϕ.toFun]
  

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
t : τ
⊢ Continuous (curry (uncurry ϕ.toFun) t)

Next tactic:
apply continuous_curry
@[continuity]
theorem continuous_toFun (t : τ) : Continuous (ϕ.toFun t) := by
  rw [← curry_uncurry ϕ.toFun]
  apply continuous_curry
  

Proof state:
case h
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
t : τ
⊢ Continuous (uncurry ϕ.toFun)

Next tactic:
exact ϕ.cont'
/-- The map `ϕ t` as a homeomorphism. -/
def toHomeomorph (t : τ) : (α ≃ₜ α) where
  toFun := ϕ t
  invFun := ϕ (-t)
  left_inv x := by 

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
t : τ
x : α
⊢ toFun ϕ (-t) (toFun ϕ t x) = x

Next tactic:
rw [← map_add, neg_add_self, map_zero_apply]
/-- The map `ϕ t` as a homeomorphism. -/
def toHomeomorph (t : τ) : (α ≃ₜ α) where
  toFun := ϕ t
  invFun := ϕ (-t)
  left_inv x := by rw [← map_add, neg_add_self, map_zero_apply]
  right_inv x := by 

Proof state:
τ : Type u_1
inst✝³ : AddCommGroup τ
inst✝² : TopologicalSpace τ
inst✝¹ : TopologicalAddGroup τ
α : Type u_2
inst✝ : TopologicalSpace α
ϕ : Flow τ α
t : τ
x : α
⊢ toFun ϕ t (toFun ϕ (-t) x) = x

Next tactic:
rw [← map_add, add_neg_self, map_zero_apply]
/-- If `x` is an accumulation point of a set `C` and `U` is a neighborhood of `x`,
then `x` is an accumulation point of `U ∩ C`. -/
theorem AccPt.nhds_inter {x : α} {U : Set α} (h_acc : AccPt x (𝓟 C)) (hU : U ∈ 𝓝 x) :
    AccPt x (𝓟 (U ∩ C)) := by
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
x : α
U : Set α
h_acc : AccPt x (𝓟 C)
hU : U ∈ 𝓝 x
⊢ AccPt x (𝓟 (U ∩ C))

Next tactic:
have : 𝓝[≠] x ≤ 𝓟 U := by
    rw [le_principal_iff]
    exact mem_nhdsWithin_of_mem_nhds hU
/-- If `x` is an accumulation point of a set `C` and `U` is a neighborhood of `x`,
then `x` is an accumulation point of `U ∩ C`. -/
theorem AccPt.nhds_inter {x : α} {U : Set α} (h_acc : AccPt x (𝓟 C)) (hU : U ∈ 𝓝 x) :
    AccPt x (𝓟 (U ∩ C)) := by
  have : 𝓝[≠] x ≤ 𝓟 U := by
    

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
x : α
U : Set α
h_acc : AccPt x (𝓟 C)
hU : U ∈ 𝓝 x
⊢ 𝓝[≠] x ≤ 𝓟 U

Next tactic:
rw [le_principal_iff]
/-- If `x` is an accumulation point of a set `C` and `U` is a neighborhood of `x`,
then `x` is an accumulation point of `U ∩ C`. -/
theorem AccPt.nhds_inter {x : α} {U : Set α} (h_acc : AccPt x (𝓟 C)) (hU : U ∈ 𝓝 x) :
    AccPt x (𝓟 (U ∩ C)) := by
  have : 𝓝[≠] x ≤ 𝓟 U := by
    rw [le_principal_iff]
    

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
x : α
U : Set α
h_acc : AccPt x (𝓟 C)
hU : U ∈ 𝓝 x
⊢ U ∈ 𝓝[≠] x

Next tactic:
exact mem_nhdsWithin_of_mem_nhds hU
/-- If `x` is an accumulation point of a set `C` and `U` is a neighborhood of `x`,
then `x` is an accumulation point of `U ∩ C`. -/
theorem AccPt.nhds_inter {x : α} {U : Set α} (h_acc : AccPt x (𝓟 C)) (hU : U ∈ 𝓝 x) :
    AccPt x (𝓟 (U ∩ C)) := by
  have : 𝓝[≠] x ≤ 𝓟 U := by
    rw [le_principal_iff]
    exact mem_nhdsWithin_of_mem_nhds hU
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
x : α
U : Set α
h_acc : AccPt x (𝓟 C)
hU : U ∈ 𝓝 x
this : 𝓝[≠] x ≤ 𝓟 U
⊢ AccPt x (𝓟 (U ∩ C))

Next tactic:
rw [AccPt, ← inf_principal, ← inf_assoc, inf_of_le_left this]
/-- If `x` is an accumulation point of a set `C` and `U` is a neighborhood of `x`,
then `x` is an accumulation point of `U ∩ C`. -/
theorem AccPt.nhds_inter {x : α} {U : Set α} (h_acc : AccPt x (𝓟 C)) (hU : U ∈ 𝓝 x) :
    AccPt x (𝓟 (U ∩ C)) := by
  have : 𝓝[≠] x ≤ 𝓟 U := by
    rw [le_principal_iff]
    exact mem_nhdsWithin_of_mem_nhds hU
  rw [AccPt, ← inf_principal, ← inf_assoc, inf_of_le_left this]
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
x : α
U : Set α
h_acc : AccPt x (𝓟 C)
hU : U ∈ 𝓝 x
this : 𝓝[≠] x ≤ 𝓟 U
⊢ NeBot (𝓝[≠] x ⊓ 𝓟 C)

Next tactic:
exact h_acc
theorem preperfect_iff_nhds : Preperfect C ↔ ∀ x ∈ C, ∀ U ∈ 𝓝 x, ∃ y ∈ U ∩ C, y ≠ x := by
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
⊢ Preperfect C ↔ ∀ x ∈ C, ∀ U ∈ 𝓝 x, ∃ y ∈ U ∩ C, y ≠ x

Next tactic:
simp only [Preperfect, accPt_iff_nhds]
/-- The intersection of a preperfect set and an open set is preperfect. -/
theorem Preperfect.open_inter {U : Set α} (hC : Preperfect C) (hU : IsOpen U) :
    Preperfect (U ∩ C) := by
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C U : Set α
hC : Preperfect C
hU : IsOpen U
⊢ Preperfect (U ∩ C)

Next tactic:
rintro x ⟨xU, xC⟩
/-- The intersection of a preperfect set and an open set is preperfect. -/
theorem Preperfect.open_inter {U : Set α} (hC : Preperfect C) (hU : IsOpen U) :
    Preperfect (U ∩ C) := by
  rintro x ⟨xU, xC⟩
  

Proof state:
case intro
α : Type u_1
inst✝ : TopologicalSpace α
C U : Set α
hC : Preperfect C
hU : IsOpen U
x : α
xU : x ∈ U
xC : x ∈ C
⊢ AccPt x (𝓟 (U ∩ C))

Next tactic:
apply (hC _ xC).nhds_inter
/-- The intersection of a preperfect set and an open set is preperfect. -/
theorem Preperfect.open_inter {U : Set α} (hC : Preperfect C) (hU : IsOpen U) :
    Preperfect (U ∩ C) := by
  rintro x ⟨xU, xC⟩
  apply (hC _ xC).nhds_inter
  

Proof state:
case intro
α : Type u_1
inst✝ : TopologicalSpace α
C U : Set α
hC : Preperfect C
hU : IsOpen U
x : α
xU : x ∈ U
xC : x ∈ C
⊢ U ∈ 𝓝 x

Next tactic:
exact hU.mem_nhds xU
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
⊢ Perfect (closure C)

Next tactic:
constructor
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · 

Proof state:
case closed
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
⊢ IsClosed (closure C)

Next tactic:
exact isClosed_closure
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  

Proof state:
case acc
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
⊢ Preperfect (closure C)

Next tactic:
intro x hx
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  

Proof state:
case acc
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ closure C
⊢ AccPt x (𝓟 (closure C))

Next tactic:
by_cases h : x ∈ C
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  by_cases h : x ∈ C <;> 

Proof state:
case pos
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ closure C
h : x ∈ C
⊢ AccPt x (𝓟 (closure C))

Next tactic:
apply AccPt.mono _ (principal_mono.mpr subset_closure)
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  by_cases h : x ∈ C <;> 

Proof state:
case neg
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ closure C
h : x ∉ C
⊢ AccPt x (𝓟 (closure C))

Next tactic:
apply AccPt.mono _ (principal_mono.mpr subset_closure)
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  by_cases h : x ∈ C <;> apply AccPt.mono _ (principal_mono.mpr subset_closure)
  · 

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ closure C
h : x ∈ C
⊢ AccPt x (𝓟 C)

Next tactic:
exact hC _ h
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  by_cases h : x ∈ C <;> apply AccPt.mono _ (principal_mono.mpr subset_closure)
  · exact hC _ h
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ closure C
h : x ∉ C
⊢ AccPt x (𝓟 C)

Next tactic:
have : {x}ᶜ ∩ C = C := by simp [h]
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  by_cases h : x ∈ C <;> apply AccPt.mono _ (principal_mono.mpr subset_closure)
  · exact hC _ h
  have : {x}ᶜ ∩ C = C := by 

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ closure C
h : x ∉ C
⊢ {x}ᶜ ∩ C = C

Next tactic:
simp [h]
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  by_cases h : x ∈ C <;> apply AccPt.mono _ (principal_mono.mpr subset_closure)
  · exact hC _ h
  have : {x}ᶜ ∩ C = C := by simp [h]
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ closure C
h : x ∉ C
this : {x}ᶜ ∩ C = C
⊢ AccPt x (𝓟 C)

Next tactic:
rw [AccPt, nhdsWithin, inf_assoc, inf_principal, this]
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  by_cases h : x ∈ C <;> apply AccPt.mono _ (principal_mono.mpr subset_closure)
  · exact hC _ h
  have : {x}ᶜ ∩ C = C := by simp [h]
  rw [AccPt, nhdsWithin, inf_assoc, inf_principal, this]
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ closure C
h : x ∉ C
this : {x}ᶜ ∩ C = C
⊢ NeBot (𝓝 x ⊓ 𝓟 C)

Next tactic:
rw [closure_eq_cluster_pts] at hx
/-- The closure of a preperfect set is perfect.
For a converse, see `preperfect_iff_perfect_closure`. -/
theorem Preperfect.perfect_closure (hC : Preperfect C) : Perfect (closure C) := by
  constructor; · exact isClosed_closure
  intro x hx
  by_cases h : x ∈ C <;> apply AccPt.mono _ (principal_mono.mpr subset_closure)
  · exact hC _ h
  have : {x}ᶜ ∩ C = C := by simp [h]
  rw [AccPt, nhdsWithin, inf_assoc, inf_principal, this]
  rw [closure_eq_cluster_pts] at hx
  

Proof state:
α : Type u_1
inst✝ : TopologicalSpace α
C : Set α
hC : Preperfect C
x : α
hx : x ∈ {a | ClusterPt a (𝓟 C)}
h : x ∉ C
this : {x}ᶜ ∩ C = C
⊢ NeBot (𝓝 x ⊓ 𝓟 C)

Next tactic:
exact hx
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  

Proof state:
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
⊢ Preperfect C ↔ Perfect (closure C)

Next tactic:
constructor
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> 

Proof state:
case mp
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
⊢ Preperfect C → Perfect (closure C)

Next tactic:
intro h
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> 

Proof state:
case mpr
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
⊢ Perfect (closure C) → Preperfect C

Next tactic:
intro h
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> intro h
  · 

Proof state:
case mp
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
h : Preperfect C
⊢ Perfect (closure C)

Next tactic:
exact h.perfect_closure
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> intro h
  · exact h.perfect_closure
  

Proof state:
case mpr
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
h : Perfect (closure C)
⊢ Preperfect C

Next tactic:
intro x xC
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> intro h
  · exact h.perfect_closure
  intro x xC
  

Proof state:
case mpr
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
h : Perfect (closure C)
x : α
xC : x ∈ C
⊢ AccPt x (𝓟 C)

Next tactic:
have H : AccPt x (𝓟 (closure C)) := h.acc _ (subset_closure xC)
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> intro h
  · exact h.perfect_closure
  intro x xC
  have H : AccPt x (𝓟 (closure C)) := h.acc _ (subset_closure xC)
  

Proof state:
case mpr
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
h : Perfect (closure C)
x : α
xC : x ∈ C
H : AccPt x (𝓟 (closure C))
⊢ AccPt x (𝓟 C)

Next tactic:
rw [accPt_iff_frequently] at *
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> intro h
  · exact h.perfect_closure
  intro x xC
  have H : AccPt x (𝓟 (closure C)) := h.acc _ (subset_closure xC)
  rw [accPt_iff_frequently] at *
  

Proof state:
case mpr
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
h : Perfect (closure C)
x : α
xC : x ∈ C
H : ∃ᶠ (y : α) in 𝓝 x, y ≠ x ∧ y ∈ closure C
⊢ ∃ᶠ (y : α) in 𝓝 x, y ≠ x ∧ y ∈ C

Next tactic:
have : ∀ y, y ≠ x ∧ y ∈ closure C → ∃ᶠ z in 𝓝 y, z ≠ x ∧ z ∈ C := by
    rintro y ⟨hyx, yC⟩
    simp only [← mem_compl_singleton_iff, and_comm, ← frequently_nhdsWithin_iff,
      hyx.nhdsWithin_compl_singleton, ← mem_closure_iff_frequently]
    exact yC
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> intro h
  · exact h.perfect_closure
  intro x xC
  have H : AccPt x (𝓟 (closure C)) := h.acc _ (subset_closure xC)
  rw [accPt_iff_frequently] at *
  have : ∀ y, y ≠ x ∧ y ∈ closure C → ∃ᶠ z in 𝓝 y, z ≠ x ∧ z ∈ C := by
    

Proof state:
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
h : Perfect (closure C)
x : α
xC : x ∈ C
H : ∃ᶠ (y : α) in 𝓝 x, y ≠ x ∧ y ∈ closure C
⊢ ∀ (y : α), y ≠ x ∧ y ∈ closure C → ∃ᶠ (z : α) in 𝓝 y, z ≠ x ∧ z ∈ C

Next tactic:
rintro y ⟨hyx, yC⟩
/-- In a T1 space, being preperfect is equivalent to having perfect closure.-/
theorem preperfect_iff_perfect_closure [T1Space α] : Preperfect C ↔ Perfect (closure C) := by
  constructor <;> intro h
  · exact h.perfect_closure
  intro x xC
  have H : AccPt x (𝓟 (closure C)) := h.acc _ (subset_closure xC)
  rw [accPt_iff_frequently] at *
  have : ∀ y, y ≠ x ∧ y ∈ closure C → ∃ᶠ z in 𝓝 y, z ≠ x ∧ z ∈ C := by
    rintro y ⟨hyx, yC⟩
    

Proof state:
case intro
α : Type u_1
inst✝¹ : TopologicalSpace α
C : Set α
inst✝ : T1Space α
h : Perfect (closure C)
x : α
xC : x ∈ C
H : ∃ᶠ (y : α) in 𝓝 x, y ≠ x ∧ y ∈ closure C
y : α
hyx : y ≠ x
yC : y ∈ closure C
⊢ ∃ᶠ (z : α) in 𝓝 y, z ≠ x ∧ z ∈ C

Next tactic:
simp only [← mem_compl_singleton_iff, and_comm, ← frequently_nhdsWithin_iff,
      hyx.nhdsWithin_compl_singleton, ← mem_closure_iff_frequently]