l3lab/ntp-mathlib huggingface dataset:
/-- If `s` is a closed set, `v` is a partial refinement, and `i` is an index such that
`i ∉ v.carrier`, then there exists a partial refinement that is strictly greater than `v`. -/
theorem exists_gt (v : PartialRefinement u s) (hs : IsClosed s) (i : ι) (hi : i ∉ v.carrier) :
    ∃ v' : PartialRefinement u s, v < v' := by
  have I : (s ∩ ⋂ (j) (_ : j ≠ i), (v j)ᶜ) ⊆ v i := by
    simp only [subset_def, mem_inter_iff, mem_iInter, and_imp]
    intro x hxs H
    rcases mem_iUnion.1 (v.subset_iUnion hxs) with ⟨j, hj⟩
    exact (em (j = i)).elim (fun h => h ▸ hj) fun h => (H j h hj).elim
  have C : IsClosed (s ∩ ⋂ (j) (_ : j ≠ i), (v j)ᶜ) :=
    IsClosed.inter hs (isClosed_biInter fun _ _ => isClosed_compl_iff.2 <| v.isOpen _)
  rcases normal_exists_closure_subset C (v.isOpen i) I with ⟨vi, ovi, hvi, cvi⟩
  refine' ⟨⟨update v i vi, insert i v.carrier, _, _, _, _⟩, _, _⟩
  · intro j
    rcases eq_or_ne j i with (rfl| hne) <;> simp [*, v.isOpen]
  · refine' fun x hx => mem_iUnion.2 _
    rcases em (∃ (j : _) (_ : j ≠ i), x ∈ v j) with (⟨j, hji, hj⟩ | h)
    · use j
      rwa [update_noteq hji]
    · push_neg at h
      use i
      rw [update_same]
      exact hvi ⟨hx, mem_biInter h⟩
  · rintro j (rfl | hj)
    · rwa [update_same, ← v.apply_eq hi]
    · rw [update_noteq (ne_of_mem_of_not_mem hj hi)]
      exact v.closure_subset hj
  · intro j hj
    rw [mem_insert_iff, not_or] at hj
    rw [update_noteq hj.1, v.apply_eq hj.2]
  · 

Proof state:
case intro.intro.intro.refine'_5
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
v : PartialRefinement u s
hs : IsClosed s
i : ι
hi : i ∉ v.carrier
I : s ∩ ⋂ j, ⋂ (_ : j ≠ i), (toFun v j)ᶜ ⊆ toFun v i
C : IsClosed (s ∩ ⋂ j, ⋂ (_ : j ≠ i), (toFun v j)ᶜ)
vi : Set X
ovi : IsOpen vi
hvi : s ∩ ⋂ j, ⋂ (_ : j ≠ i), (toFun v j)ᶜ ⊆ vi
cvi : closure vi ⊆ toFun v i
⊢ v.carrier ⊆
      { toFun := update v.toFun i vi, carrier := insert i v.carrier,
          isOpen := (_ : ∀ (j : ι), IsOpen (update v.toFun i vi j)),
          subset_iUnion := (_ : ∀ x ∈ s, x ∈ ⋃ i_1, update v.toFun i vi i_1),
          closure_subset := (_ : ∀ {j : ι}, j ∈ insert i v.carrier → closure (update v.toFun i vi j) ⊆ u j),
          apply_eq := (_ : ∀ {j : ι}, j ∉ insert i v.carrier → update v.toFun i vi j = u j) }.carrier ∧
    ∀ i_1 ∈ v.carrier,
      toFun v i_1 =
        toFun
          { toFun := update v.toFun i vi, carrier := insert i v.carrier,
            isOpen := (_ : ∀ (j : ι), IsOpen (update v.toFun i vi j)),
            subset_iUnion := (_ : ∀ x ∈ s, x ∈ ⋃ i_2, update v.toFun i vi i_2),
            closure_subset := (_ : ∀ {j : ι}, j ∈ insert i v.carrier → closure (update v.toFun i vi j) ⊆ u j),
            apply_eq := (_ : ∀ {j : ι}, j ∉ insert i v.carrier → update v.toFun i vi j = u j) }
          i_1

Next tactic:
refine' ⟨subset_insert _ _, fun j hj => _⟩
/-- If `s` is a closed set, `v` is a partial refinement, and `i` is an index such that
`i ∉ v.carrier`, then there exists a partial refinement that is strictly greater than `v`. -/
theorem exists_gt (v : PartialRefinement u s) (hs : IsClosed s) (i : ι) (hi : i ∉ v.carrier) :
    ∃ v' : PartialRefinement u s, v < v' := by
  have I : (s ∩ ⋂ (j) (_ : j ≠ i), (v j)ᶜ) ⊆ v i := by
    simp only [subset_def, mem_inter_iff, mem_iInter, and_imp]
    intro x hxs H
    rcases mem_iUnion.1 (v.subset_iUnion hxs) with ⟨j, hj⟩
    exact (em (j = i)).elim (fun h => h ▸ hj) fun h => (H j h hj).elim
  have C : IsClosed (s ∩ ⋂ (j) (_ : j ≠ i), (v j)ᶜ) :=
    IsClosed.inter hs (isClosed_biInter fun _ _ => isClosed_compl_iff.2 <| v.isOpen _)
  rcases normal_exists_closure_subset C (v.isOpen i) I with ⟨vi, ovi, hvi, cvi⟩
  refine' ⟨⟨update v i vi, insert i v.carrier, _, _, _, _⟩, _, _⟩
  · intro j
    rcases eq_or_ne j i with (rfl| hne) <;> simp [*, v.isOpen]
  · refine' fun x hx => mem_iUnion.2 _
    rcases em (∃ (j : _) (_ : j ≠ i), x ∈ v j) with (⟨j, hji, hj⟩ | h)
    · use j
      rwa [update_noteq hji]
    · push_neg at h
      use i
      rw [update_same]
      exact hvi ⟨hx, mem_biInter h⟩
  · rintro j (rfl | hj)
    · rwa [update_same, ← v.apply_eq hi]
    · rw [update_noteq (ne_of_mem_of_not_mem hj hi)]
      exact v.closure_subset hj
  · intro j hj
    rw [mem_insert_iff, not_or] at hj
    rw [update_noteq hj.1, v.apply_eq hj.2]
  · refine' ⟨subset_insert _ _, fun j hj => _⟩
    

Proof state:
case intro.intro.intro.refine'_5
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
v : PartialRefinement u s
hs : IsClosed s
i : ι
hi : i ∉ v.carrier
I : s ∩ ⋂ j, ⋂ (_ : j ≠ i), (toFun v j)ᶜ ⊆ toFun v i
C : IsClosed (s ∩ ⋂ j, ⋂ (_ : j ≠ i), (toFun v j)ᶜ)
vi : Set X
ovi : IsOpen vi
hvi : s ∩ ⋂ j, ⋂ (_ : j ≠ i), (toFun v j)ᶜ ⊆ vi
cvi : closure vi ⊆ toFun v i
j : ι
hj : j ∈ v.carrier
⊢ toFun v j =
    toFun
      { toFun := update v.toFun i vi, carrier := insert i v.carrier,
        isOpen := (_ : ∀ (j : ι), IsOpen (update v.toFun i vi j)),
        subset_iUnion := (_ : ∀ x ∈ s, x ∈ ⋃ i_1, update v.toFun i vi i_1),
        closure_subset := (_ : ∀ {j : ι}, j ∈ insert i v.carrier → closure (update v.toFun i vi j) ⊆ u j),
        apply_eq := (_ : ∀ {j : ι}, j ∉ insert i v.carrier → update v.toFun i vi j = u j) }
      j

Next tactic:
exact (update_noteq (ne_of_mem_of_not_mem hj hi) _ _).symm
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  

Proof state:
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
⊢ ∃ v, s ⊆ iUnion v ∧ (∀ (i : ι), IsOpen (v i)) ∧ ∀ (i : ι), closure (v i) ⊆ u i

Next tactic:
haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
  

Proof state:
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this : Nonempty (PartialRefinement u s)
⊢ ∃ v, s ⊆ iUnion v ∧ (∀ (i : ι), IsOpen (v i)) ∧ ∀ (i : ι), closure (v i) ⊆ u i

Next tactic:
have : ∀ c : Set (PartialRefinement u s),
      IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub :=
    fun c hc ne => ⟨.chainSup c hc ne uf us, fun v hv => PartialRefinement.le_chainSup _ _ _ _ hv⟩
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
  have : ∀ c : Set (PartialRefinement u s),
      IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub :=
    fun c hc ne => ⟨.chainSup c hc ne uf us, fun v hv => PartialRefinement.le_chainSup _ _ _ _ hv⟩
  

Proof state:
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this✝ : Nonempty (PartialRefinement u s)
this : ∀ (c : Set (PartialRefinement u s)), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ∃ ub, ∀ v ∈ c, v ≤ ub
⊢ ∃ v, s ⊆ iUnion v ∧ (∀ (i : ι), IsOpen (v i)) ∧ ∀ (i : ι), closure (v i) ⊆ u i

Next tactic:
rcases zorn_nonempty_partialOrder this with ⟨v, hv⟩
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
  have : ∀ c : Set (PartialRefinement u s),
      IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub :=
    fun c hc ne => ⟨.chainSup c hc ne uf us, fun v hv => PartialRefinement.le_chainSup _ _ _ _ hv⟩
  rcases zorn_nonempty_partialOrder this with ⟨v, hv⟩
  

Proof state:
case intro
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this✝ : Nonempty (PartialRefinement u s)
this : ∀ (c : Set (PartialRefinement u s)), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ∃ ub, ∀ v ∈ c, v ≤ ub
v : PartialRefinement u s
hv : ∀ (a : PartialRefinement u s), v ≤ a → a = v
⊢ ∃ v, s ⊆ iUnion v ∧ (∀ (i : ι), IsOpen (v i)) ∧ ∀ (i : ι), closure (v i) ⊆ u i

Next tactic:
suffices : ∀ i, i ∈ v.carrier
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
  have : ∀ c : Set (PartialRefinement u s),
      IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub :=
    fun c hc ne => ⟨.chainSup c hc ne uf us, fun v hv => PartialRefinement.le_chainSup _ _ _ _ hv⟩
  rcases zorn_nonempty_partialOrder this with ⟨v, hv⟩
  suffices : ∀ i, i ∈ v.carrier
  

Proof state:
case intro
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this✝¹ : Nonempty (PartialRefinement u s)
this✝ : ∀ (c : Set (PartialRefinement u s)), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ∃ ub, ∀ v ∈ c, v ≤ ub
v : PartialRefinement u s
hv : ∀ (a : PartialRefinement u s), v ≤ a → a = v
this : ∀ (i : ι), i ∈ v.carrier
⊢ ∃ v, s ⊆ iUnion v ∧ (∀ (i : ι), IsOpen (v i)) ∧ ∀ (i : ι), closure (v i) ⊆ u i
case this
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this✝ : Nonempty (PartialRefinement u s)
this : ∀ (c : Set (PartialRefinement u s)), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ∃ ub, ∀ v ∈ c, v ≤ ub
v : PartialRefinement u s
hv : ∀ (a : PartialRefinement u s), v ≤ a → a = v
⊢ ∀ (i : ι), i ∈ v.carrier

Next tactic:
exact ⟨v, v.subset_iUnion, fun i => v.isOpen _, fun i => v.closure_subset (this i)⟩
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
  have : ∀ c : Set (PartialRefinement u s),
      IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub :=
    fun c hc ne => ⟨.chainSup c hc ne uf us, fun v hv => PartialRefinement.le_chainSup _ _ _ _ hv⟩
  rcases zorn_nonempty_partialOrder this with ⟨v, hv⟩
  suffices : ∀ i, i ∈ v.carrier
  exact ⟨v, v.subset_iUnion, fun i => v.isOpen _, fun i => v.closure_subset (this i)⟩
  

Proof state:
case this
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this✝ : Nonempty (PartialRefinement u s)
this : ∀ (c : Set (PartialRefinement u s)), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ∃ ub, ∀ v ∈ c, v ≤ ub
v : PartialRefinement u s
hv : ∀ (a : PartialRefinement u s), v ≤ a → a = v
⊢ ∀ (i : ι), i ∈ v.carrier

Next tactic:
contrapose! hv
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
  have : ∀ c : Set (PartialRefinement u s),
      IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub :=
    fun c hc ne => ⟨.chainSup c hc ne uf us, fun v hv => PartialRefinement.le_chainSup _ _ _ _ hv⟩
  rcases zorn_nonempty_partialOrder this with ⟨v, hv⟩
  suffices : ∀ i, i ∈ v.carrier
  exact ⟨v, v.subset_iUnion, fun i => v.isOpen _, fun i => v.closure_subset (this i)⟩
  contrapose! hv
  

Proof state:
case this
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this✝ : Nonempty (PartialRefinement u s)
this : ∀ (c : Set (PartialRefinement u s)), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ∃ ub, ∀ v ∈ c, v ≤ ub
v : PartialRefinement u s
hv : ∃ i, i ∉ v.carrier
⊢ ∃ a, v ≤ a ∧ a ≠ v

Next tactic:
rcases hv with ⟨i, hi⟩
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
  have : ∀ c : Set (PartialRefinement u s),
      IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub :=
    fun c hc ne => ⟨.chainSup c hc ne uf us, fun v hv => PartialRefinement.le_chainSup _ _ _ _ hv⟩
  rcases zorn_nonempty_partialOrder this with ⟨v, hv⟩
  suffices : ∀ i, i ∈ v.carrier
  exact ⟨v, v.subset_iUnion, fun i => v.isOpen _, fun i => v.closure_subset (this i)⟩
  contrapose! hv
  rcases hv with ⟨i, hi⟩
  

Proof state:
case this.intro
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this✝ : Nonempty (PartialRefinement u s)
this : ∀ (c : Set (PartialRefinement u s)), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ∃ ub, ∀ v ∈ c, v ≤ ub
v : PartialRefinement u s
i : ι
hi : i ∉ v.carrier
⊢ ∃ a, v ≤ a ∧ a ≠ v

Next tactic:
rcases v.exists_gt hs i hi with ⟨v', hlt⟩
/-- **Shrinking lemma**. A point-finite open cover of a closed subset of a normal space can be
"shrunk" to a new open cover so that the closure of each new open set is contained in the
corresponding original open set. -/
theorem exists_subset_iUnion_closure_subset (hs : IsClosed s) (uo : ∀ i, IsOpen (u i))
    (uf : ∀ x ∈ s, { i | x ∈ u i }.Finite) (us : s ⊆ ⋃ i, u i) :
    ∃ v : ι → Set X, s ⊆ iUnion v ∧ (∀ i, IsOpen (v i)) ∧ ∀ i, closure (v i) ⊆ u i := by
  haveI : Nonempty (PartialRefinement u s) := ⟨⟨u, ∅, uo, us, False.elim, fun _ => rfl⟩⟩
  have : ∀ c : Set (PartialRefinement u s),
      IsChain (· ≤ ·) c → c.Nonempty → ∃ ub, ∀ v ∈ c, v ≤ ub :=
    fun c hc ne => ⟨.chainSup c hc ne uf us, fun v hv => PartialRefinement.le_chainSup _ _ _ _ hv⟩
  rcases zorn_nonempty_partialOrder this with ⟨v, hv⟩
  suffices : ∀ i, i ∈ v.carrier
  exact ⟨v, v.subset_iUnion, fun i => v.isOpen _, fun i => v.closure_subset (this i)⟩
  contrapose! hv
  rcases hv with ⟨i, hi⟩
  rcases v.exists_gt hs i hi with ⟨v', hlt⟩
  

Proof state:
case this.intro.intro
ι : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : NormalSpace X
u : ι → Set X
s : Set X
hs : IsClosed s
uo : ∀ (i : ι), IsOpen (u i)
uf : ∀ x ∈ s, Set.Finite {i | x ∈ u i}
us : s ⊆ ⋃ i, u i
this✝ : Nonempty (PartialRefinement u s)
this : ∀ (c : Set (PartialRefinement u s)), IsChain (fun x x_1 => x ≤ x_1) c → Set.Nonempty c → ∃ ub, ∀ v ∈ c, v ≤ ub
v : PartialRefinement u s
i : ι
hi : i ∉ v.carrier
v' : PartialRefinement u s
hlt : v < v'
⊢ ∃ a, v ≤ a ∧ a ≠ v

Next tactic:
exact ⟨v', hlt.le, hlt.ne'⟩
instance Path.continuousMapClass : ContinuousMapClass (Path x y) I X where
  coe := fun γ ↦ ⇑γ.toContinuousMap
  coe_injective' := fun γ₁ γ₂ h => by
    

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ₁ γ₂ : Path x y
h : (fun γ => ⇑γ.toContinuousMap) γ₁ = (fun γ => ⇑γ.toContinuousMap) γ₂
⊢ γ₁ = γ₂

Next tactic:
simp only [FunLike.coe_fn_eq] at h
instance Path.continuousMapClass : ContinuousMapClass (Path x y) I X where
  coe := fun γ ↦ ⇑γ.toContinuousMap
  coe_injective' := fun γ₁ γ₂ h => by
    simp only [FunLike.coe_fn_eq] at h
    

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ₁ γ₂ : Path x y
h : γ₁.toContinuousMap = γ₂.toContinuousMap
⊢ γ₁ = γ₂

Next tactic:
cases γ₁
instance Path.continuousMapClass : ContinuousMapClass (Path x y) I X where
  coe := fun γ ↦ ⇑γ.toContinuousMap
  coe_injective' := fun γ₁ γ₂ h => by
    simp only [FunLike.coe_fn_eq] at h
    cases γ₁; 

Proof state:
case mk
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ₂ : Path x y
toContinuousMap✝ : C(↑I, X)
source'✝ : ContinuousMap.toFun toContinuousMap✝ 0 = x
target'✝ : ContinuousMap.toFun toContinuousMap✝ 1 = y
h :
  { toContinuousMap := toContinuousMap✝, source' := source'✝, target' := target'✝ }.toContinuousMap = γ₂.toContinuousMap
⊢ { toContinuousMap := toContinuousMap✝, source' := source'✝, target' := target'✝ } = γ₂

Next tactic:
cases γ₂
instance Path.continuousMapClass : ContinuousMapClass (Path x y) I X where
  coe := fun γ ↦ ⇑γ.toContinuousMap
  coe_injective' := fun γ₁ γ₂ h => by
    simp only [FunLike.coe_fn_eq] at h
    cases γ₁; cases γ₂; 

Proof state:
case mk.mk
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
toContinuousMap✝¹ : C(↑I, X)
source'✝¹ : ContinuousMap.toFun toContinuousMap✝¹ 0 = x
target'✝¹ : ContinuousMap.toFun toContinuousMap✝¹ 1 = y
toContinuousMap✝ : C(↑I, X)
source'✝ : ContinuousMap.toFun toContinuousMap✝ 0 = x
target'✝ : ContinuousMap.toFun toContinuousMap✝ 1 = y
h :
  { toContinuousMap := toContinuousMap✝¹, source' := source'✝¹, target' := target'✝¹ }.toContinuousMap =
    { toContinuousMap := toContinuousMap✝, source' := source'✝, target' := target'✝ }.toContinuousMap
⊢ { toContinuousMap := toContinuousMap✝¹, source' := source'✝¹, target' := target'✝¹ } =
    { toContinuousMap := toContinuousMap✝, source' := source'✝, target' := target'✝ }

Next tactic:
congr
instance Path.continuousMapClass : ContinuousMapClass (Path x y) I X where
  coe := fun γ ↦ ⇑γ.toContinuousMap
  coe_injective' := fun γ₁ γ₂ h => by
    simp only [FunLike.coe_fn_eq] at h
    cases γ₁; cases γ₂; congr
  map_continuous := fun γ => by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
⊢ Continuous ⇑γ

Next tactic:
continuity
@[ext]
protected theorem Path.ext : ∀ {γ₁ γ₂ : Path x y}, (γ₁ : I → X) = γ₂ → γ₁ = γ₂ := by
  

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
⊢ ∀ {γ₁ γ₂ : Path x y}, ⇑γ₁ = ⇑γ₂ → γ₁ = γ₂

Next tactic:
rintro ⟨⟨x, h11⟩, h12, h13⟩ ⟨⟨x, h21⟩, h22, h23⟩ rfl
@[ext]
protected theorem Path.ext : ∀ {γ₁ γ₂ : Path x y}, (γ₁ : I → X) = γ₂ → γ₁ = γ₂ := by
  rintro ⟨⟨x, h11⟩, h12, h13⟩ ⟨⟨x, h21⟩, h22, h23⟩ rfl
  

Proof state:
case mk.mk.mk.mk
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
x : ↑I → X
h11 : Continuous x
h12 : ContinuousMap.toFun (ContinuousMap.mk x) 0 = x✝
h13 : ContinuousMap.toFun (ContinuousMap.mk x) 1 = y
h21 : Continuous ⇑{ toContinuousMap := ContinuousMap.mk x, source' := h12, target' := h13 }
h22 :
  ContinuousMap.toFun (ContinuousMap.mk ⇑{ toContinuousMap := ContinuousMap.mk x, source' := h12, target' := h13 }) 0 =
    x✝
h23 :
  ContinuousMap.toFun (ContinuousMap.mk ⇑{ toContinuousMap := ContinuousMap.mk x, source' := h12, target' := h13 }) 1 =
    y
⊢ { toContinuousMap := ContinuousMap.mk x, source' := h12, target' := h13 } =
    { toContinuousMap := ContinuousMap.mk ⇑{ toContinuousMap := ContinuousMap.mk x, source' := h12, target' := h13 },
      source' := h22, target' := h23 }

Next tactic:
rfl
@[simp]
theorem refl_range {a : X} : range (Path.refl a) = {a} := by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
a : X
⊢ range ⇑(refl a) = {a}

Next tactic:
simp [Path.refl, CoeFun.coe]
/-- The reverse of a path from `x` to `y`, as a path from `y` to `x` -/
@[symm, simps]
def symm (γ : Path x y) : Path y x where
  toFun := γ ∘ σ
  continuous_toFun := by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ✝ γ : Path x y
⊢ Continuous (⇑γ ∘ σ)

Next tactic:
continuity
/-- The reverse of a path from `x` to `y`, as a path from `y` to `x` -/
@[symm, simps]
def symm (γ : Path x y) : Path y x where
  toFun := γ ∘ σ
  continuous_toFun := by continuity
  source' := by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ✝ γ : Path x y
⊢ ContinuousMap.toFun (ContinuousMap.mk (⇑γ ∘ σ)) 0 = y

Next tactic:
simpa [-Path.target] using γ.target
/-- The reverse of a path from `x` to `y`, as a path from `y` to `x` -/
@[symm, simps]
def symm (γ : Path x y) : Path y x where
  toFun := γ ∘ σ
  continuous_toFun := by continuity
  source' := by simpa [-Path.target] using γ.target
  target' := by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ✝ γ : Path x y
⊢ ContinuousMap.toFun (ContinuousMap.mk (⇑γ ∘ σ)) 1 = x

Next tactic:
simpa [-Path.source] using γ.source
@[simp]
theorem symm_symm (γ : Path x y) : γ.symm.symm = γ := by
  

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ✝ γ : Path x y
⊢ symm (symm γ) = γ

Next tactic:
ext t
@[simp]
theorem symm_symm (γ : Path x y) : γ.symm.symm = γ := by
  ext t
  

Proof state:
case a.h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ✝ γ : Path x y
t : ↑I
⊢ (symm (symm γ)) t = γ t

Next tactic:
show γ (σ (σ t)) = γ t