Skip to content

Commit ee63e95

Browse files
kim-emclaude
andcommitted
chore: merge SLSC branch into paths_discrete
Merge the At/On/full refactoring from SLSC branch, adapting the discrete topology machinery to use the new structure. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2 parents e3a950a + 86c833d commit ee63e95

2 files changed

Lines changed: 164 additions & 45 deletions

File tree

Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,16 @@ theorem trans_assoc {x₀ x₁ x₂ x₃ : X} (p : Path x₀ x₁) (q : Path x
200200
((p.trans q).trans r).Homotopic (p.trans (q.trans r)) :=
201201
⟨Homotopy.transAssoc p q r⟩
202202

203+
/-- If `γ.trans γ'.symm` is nullhomotopic, then `γ` and `γ'` are homotopic.
204+
This is the path-homotopy analogue of `a * b⁻¹ = 1 → a = b`. -/
205+
theorem eq_of_trans_symm {γ γ' : Path x₀ x₁}
206+
(h : (γ.trans γ'.symm).Homotopic (Path.refl x₀)) : γ.Homotopic γ' :=
207+
(trans_refl γ).symm |>.trans <|
208+
(hcomp (.refl γ) (symm_trans γ').symm) |>.trans <|
209+
(trans_assoc γ γ'.symm γ').symm |>.trans <|
210+
(hcomp h (.refl γ')) |>.trans <|
211+
refl_trans γ'
212+
203213
namespace Quotient
204214

205215
@[simp, grind =]
@@ -253,6 +263,15 @@ theorem trans_assoc {x₀ x₁ x₂ x₃ : X}
253263
induction γ₂ using Quotient.ind with | mk γ₂ =>
254264
simpa [← mk_trans, eq] using Homotopic.trans_assoc γ₀ γ₁ γ₂
255265

266+
/-- If `trans γ (symm γ') = refl`, then `γ = γ'`.
267+
This is the quotient analogue of `a * b⁻¹ = 1 → a = b`. -/
268+
theorem eq_of_trans_symm {γ γ' : Homotopic.Quotient x₀ x₁}
269+
(h : trans γ (symm γ') = refl x₀) : γ = γ' := by
270+
induction γ using Quotient.ind with | mk γ =>
271+
induction γ' using Quotient.ind with | mk γ' =>
272+
simp only [← mk_trans, ← mk_symm, ← mk_refl] at h
273+
exact Quotient.sound (Homotopic.eq_of_trans_symm (Quotient.exact h))
274+
256275
end Quotient
257276

258277
end Homotopic

Mathlib/AlgebraicTopology/FundamentalGroupoid/SemilocallySimplyConnected.lean

Lines changed: 145 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,18 @@ such that loops in that neighborhood are nullhomotopic in the whole space.
2222
2323
## Main definitions
2424
25-
* `SemilocallySimplyConnected X` - A space where every point has a neighborhood with
25+
* `SemilocallySimplyConnectedAt x` - The property at a single point: `x` has a neighborhood with
2626
trivial fundamental group relative to the ambient space.
27+
* `SemilocallySimplyConnectedOn s` - The property holds at every point of `s`.
28+
* `SemilocallySimplyConnected X` - The property holds at every point of `X`.
2729
2830
## Main theorems
2931
30-
* `semilocallySimplyConnected_iff` - Characterization in terms of loops
31-
being nullhomotopic.
32-
* `SemilocallySimplyConnected.of_simplyConnected` - Simply connected spaces are semilocally
33-
simply connected.
32+
* `semilocallySimplyConnectedAt_iff` - Characterization in terms of loops being nullhomotopic.
33+
* `semilocallySimplyConnectedAt_iff_paths` - Characterization: any two paths in U between the same
34+
endpoints are homotopic.
35+
* `SemilocallySimplyConnectedAt.of_simplyConnected` - Simply connected spaces are semilocally
36+
simply connected at every point.
3437
* `Path.Homotopic.Quotient.discreteTopology` - In a semilocally simply connected,
3538
locally path-connected space, the quotient of paths by homotopy has the discrete topology.
3639
-/
@@ -39,62 +42,62 @@ such that loops in that neighborhood are nullhomotopic in the whole space.
3942

4043
noncomputable section
4144

42-
open CategoryTheory FundamentalGroupoid Topology
45+
open CategoryTheory Filter FundamentalGroupoid Set Topology
4346

4447
variable {X : Type*} [TopologicalSpace X]
4548

46-
/-- A topological space is semilocally simply connected if every point has a neighborhood `U`
47-
such that the inclusion map from `π₁(U, base)` to `π₁(X, base)` is trivial for all basepoints
48-
in `U`. Equivalently, every loop in `U` is nullhomotopic in `X`. -/
49-
def SemilocallySimplyConnected (X : Type*) [TopologicalSpace X] : Prop :=
50-
∀ x : X, ∃ U : Set X, IsOpen U ∧ x ∈ U ∧
51-
∀ (base : U),
52-
(FundamentalGroup.map (⟨Subtype.val, continuous_subtype_val⟩ : C(U, X)) base).range = ⊥
49+
/-! ### SemilocallySimplyConnectedAt -/
5350

54-
namespace SemilocallySimplyConnected
55-
56-
variable {X : Type*} [TopologicalSpace X]
51+
/-- A space is semilocally simply connected at `x` if `x` has a neighborhood `U` such that
52+
the map from `π₁(U, base)` to `π₁(X, base)` induced by the inclusion is trivial for all
53+
basepoints in `U`. Equivalently, every loop in `U` is nullhomotopic in `X`. -/
54+
def SemilocallySimplyConnectedAt (x : X) : Prop :=
55+
∃ U ∈ 𝓝 x, ∀ (base : U),
56+
(FundamentalGroup.map (⟨Subtype.val, continuous_subtype_val⟩ : C(U, X)) base).range = ⊥
5757

58-
/-- Simply connected spaces are semilocally simply connected. -/
59-
theorem of_simplyConnected [SimplyConnectedSpace X] : SemilocallySimplyConnected X := fun x =>
60-
⟨Set.univ, isOpen_univ, Set.mem_univ x, fun base => by
58+
/-- Simply connected spaces are semilocally simply connected at every point. -/
59+
theorem SemilocallySimplyConnectedAt.of_simplyConnected [SimplyConnectedSpace X] (x : X) :
60+
SemilocallySimplyConnectedAt x :=
61+
⟨univ, univ_mem, fun base => by
6162
simp only [MonoidHom.range_eq_bot_iff]
6263
ext
6364
exact Subsingleton.elim (α := Path.Homotopic.Quotient base.val base.val) _ _⟩
6465

65-
theorem semilocallySimplyConnected_iff :
66-
SemilocallySimplyConnected X
67-
∀ x : X, ∃ U : Set X, IsOpen U ∧ x ∈ U ∧
68-
∀ {u : U} (γ : Path u.val u.val) (_ : Set.range γ ⊆ U),
69-
Path.Homotopic γ (Path.refl u.val) := by
66+
theorem semilocallySimplyConnectedAt_iff {x : X} :
67+
SemilocallySimplyConnectedAt x
68+
∃ U : Set X, IsOpen U ∧ x ∈ U ∧
69+
∀ {u : X} (γ : Path u u) (_ : range γ ⊆ U),
70+
Path.Homotopic γ (Path.refl u) := by
7071
constructor
71-
· -- Forward direction: SemilocallySimplyConnected implies small loops are null
72-
intro h x
73-
obtain ⟨U, hU_open, hx_in_U, hU_loops⟩ := h x
74-
use U, hU_open, hx_in_U
72+
· -- Forward direction: SemilocallySimplyConnectedAt implies small loops are null
73+
intro ⟨U, hU_nhd, hU_loops⟩
74+
obtain ⟨V, hVU, hV_open, hx_in_V⟩ := mem_nhds_iff.mp hU_nhd
75+
refine ⟨V, hV_open, hx_in_V, ?_⟩
7576
intro u γ hγ_range
77+
-- Since range γ ⊆ V ⊆ U, γ takes values in U
78+
have hγ_mem : ∀ t, γ t ∈ U := fun t => hVU (hγ_range ⟨t, rfl⟩)
7679
-- Restrict γ to a path in the subspace U
77-
have hγ_mem : ∀ t, γ t ∈ U := fun t => hγ_range ⟨t, rfl⟩
78-
let γ_U := γ.codRestrict hγ_mem
79-
-- The map from π₁(U, u) to π₁(X, u.val) has trivial range
80-
have h_range := hU_loops u
80+
let γ_U : Path (⟨u, γ.source ▸ hγ_mem 0⟩ : U) ⟨u, γ.target ▸ hγ_mem 1⟩ := γ.codRestrict hγ_mem
81+
-- The basepoint u' : U
82+
let u' : U := ⟨u, γ.source ▸ hγ_mem 0
83+
-- The map from π₁(U, u') to π₁(X, u) has trivial range
84+
have h_range := hU_loops u'
8185
rw [MonoidHom.range_eq_bot_iff] at h_range
82-
have h_map : FundamentalGroup.map ⟨Subtype.val, continuous_subtype_val⟩ u
86+
have h_map : FundamentalGroup.map ⟨Subtype.val, continuous_subtype_val⟩ u'
8387
(FundamentalGroup.fromPath ⟦γ_U⟧) =
84-
FundamentalGroup.fromPath ⟦Path.refl u.val⟧ := by
88+
FundamentalGroup.fromPath ⟦Path.refl u⟧ := by
8589
rw [h_range]; rfl
86-
rw [show FundamentalGroup.map ⟨Subtype.val, continuous_subtype_val⟩ u
90+
rw [show FundamentalGroup.map ⟨Subtype.val, continuous_subtype_val⟩ u'
8791
(FundamentalGroup.fromPath ⟦γ_U⟧) =
8892
FundamentalGroup.fromPath ⟦γ_U.map continuous_subtype_val⟧ from rfl,
8993
Path.map_codRestrict] at h_map
9094
exact Quotient.eq.mp h_map
91-
· -- Backward direction: small loops null implies SemilocallySimplyConnected
92-
intro h x
93-
obtain ⟨U, hU_open, hx_in_U, hU_loops_null⟩ := h x
94-
use U, hU_open, hx_in_U; intro base
95+
· -- Backward direction: small loops null implies SemilocallySimplyConnectedAt
96+
intro ⟨U, hU_open, hx_in_U, hU_loops_null⟩
97+
refine ⟨U, hU_open.mem_nhds hx_in_U, ?_⟩; intro base
9598
simp only [MonoidHom.range_eq_bot_iff]; ext p
9699
obtain ⟨γ', rfl⟩ := Quotient.exists_rep (FundamentalGroup.toPath p)
97-
have hrange : Set.range (γ'.map continuous_subtype_val) ⊆ U := by
100+
have hrange : range (γ'.map continuous_subtype_val) ⊆ U := by
98101
rintro _ ⟨t, rfl⟩
99102
exact (γ' t).property
100103
have hhom := hU_loops_null (γ'.map continuous_subtype_val) hrange
@@ -104,6 +107,103 @@ theorem semilocallySimplyConnected_iff :
104107
Quotient.sound hhom]
105108
rfl
106109

110+
/-- Characterization of semilocally simply connected at a point: any two paths in U between
111+
the same endpoints are homotopic. -/
112+
theorem semilocallySimplyConnectedAt_iff_paths {x : X} :
113+
SemilocallySimplyConnectedAt x ↔
114+
∃ U : Set X, IsOpen U ∧ x ∈ U ∧
115+
∀ {u u' : X} (γ γ' : Path u u'),
116+
range γ ⊆ U → range γ' ⊆ U → γ.Homotopic γ' := by
117+
rw [semilocallySimplyConnectedAt_iff]
118+
constructor
119+
· intro ⟨U, hU_open, hx_in_U, hU_loops⟩
120+
refine ⟨U, hU_open, hx_in_U, ?_⟩
121+
intro u u' γ γ' hγ hγ'
122+
-- γ.trans γ'.symm is a loop in U, hence nullhomotopic
123+
have hloop : range (γ.trans γ'.symm) ⊆ U := by
124+
intro y hy
125+
simp only [Path.trans_range, Path.symm_range] at hy
126+
exact hy.elim (fun h => hγ h) (fun h => hγ' h)
127+
have hnull := hU_loops (γ.trans γ'.symm) hloop
128+
exact Path.Homotopic.eq_of_trans_symm hnull
129+
· intro ⟨U, hU_open, hx_in_U, hU_paths⟩
130+
refine ⟨U, hU_open, hx_in_U, ?_⟩
131+
intro u γ hγ
132+
have hrefl : range (Path.refl u) ⊆ U := by
133+
simp only [Path.refl_range, singleton_subset_iff]
134+
exact hγ ⟨0, γ.source⟩
135+
exact hU_paths γ (Path.refl u) hγ hrefl
136+
137+
/-! ### SemilocallySimplyConnectedOn -/
138+
139+
variable {s t : Set X} {x : X}
140+
141+
/-- A space is semilocally simply connected on `s` if it is semilocally simply connected
142+
at every point of `s`. -/
143+
def SemilocallySimplyConnectedOn (s : Set X) : Prop :=
144+
∀ x ∈ s, SemilocallySimplyConnectedAt x
145+
146+
theorem SemilocallySimplyConnectedOn.at (h : SemilocallySimplyConnectedOn s) (hx : x ∈ s) :
147+
SemilocallySimplyConnectedAt x :=
148+
h x hx
149+
150+
theorem SemilocallySimplyConnectedOn.mono (h : SemilocallySimplyConnectedOn t) (hst : s ⊆ t) :
151+
SemilocallySimplyConnectedOn s :=
152+
fun x hx => h x (hst hx)
153+
154+
theorem semilocallySimplyConnectedOn_iff :
155+
SemilocallySimplyConnectedOn s ↔
156+
∀ x ∈ s, ∃ U : Set X, IsOpen U ∧ x ∈ U ∧
157+
∀ {u : X} (γ : Path u u) (_ : range γ ⊆ U),
158+
Path.Homotopic γ (Path.refl u) :=
159+
forall₂_congr fun _ _ => semilocallySimplyConnectedAt_iff
160+
161+
theorem semilocallySimplyConnectedOn_iff_paths :
162+
SemilocallySimplyConnectedOn s ↔
163+
∀ x ∈ s, ∃ U : Set X, IsOpen U ∧ x ∈ U ∧
164+
∀ {u u' : X} (γ γ' : Path u u'),
165+
range γ ⊆ U → range γ' ⊆ U → γ.Homotopic γ' :=
166+
forall₂_congr fun _ _ => semilocallySimplyConnectedAt_iff_paths
167+
168+
/-! ### SemilocallySimplyConnected -/
169+
170+
/-- A topological space is semilocally simply connected if every point has a neighborhood `U`
171+
such that the map from `π₁(U, base)` to `π₁(X, base)` induced by the inclusion is trivial for all
172+
basepoints in `U`. Equivalently, every loop in `U` is nullhomotopic in `X`. -/
173+
def SemilocallySimplyConnected (X : Type*) [TopologicalSpace X] : Prop :=
174+
∀ x : X, SemilocallySimplyConnectedAt x
175+
176+
theorem SemilocallySimplyConnected.at (h : SemilocallySimplyConnected X) (x : X) :
177+
SemilocallySimplyConnectedAt x :=
178+
h x
179+
180+
theorem SemilocallySimplyConnected.on (h : SemilocallySimplyConnected X) (s : Set X) :
181+
SemilocallySimplyConnectedOn s :=
182+
fun x _ => h x
183+
184+
theorem semilocallySimplyConnectedOn_univ :
185+
SemilocallySimplyConnectedOn (univ : Set X) ↔ SemilocallySimplyConnected X :=
186+
fun h x => h x (mem_univ x), fun h x _ => h x⟩
187+
188+
/-- Simply connected spaces are semilocally simply connected. -/
189+
theorem SemilocallySimplyConnected.of_simplyConnected [SimplyConnectedSpace X] :
190+
SemilocallySimplyConnected X :=
191+
fun x => SemilocallySimplyConnectedAt.of_simplyConnected x
192+
193+
theorem semilocallySimplyConnected_iff :
194+
SemilocallySimplyConnected X ↔
195+
∀ x : X, ∃ U : Set X, IsOpen U ∧ x ∈ U ∧
196+
∀ {u : X} (γ : Path u u) (_ : range γ ⊆ U),
197+
Path.Homotopic γ (Path.refl u) :=
198+
forall_congr' fun _ => semilocallySimplyConnectedAt_iff
199+
200+
theorem semilocallySimplyConnected_iff_paths :
201+
SemilocallySimplyConnected X ↔
202+
∀ x : X, ∃ U : Set X, IsOpen U ∧ x ∈ U ∧
203+
∀ {u u' : X} (γ γ' : Path u u'),
204+
range γ ⊆ U → range γ' ⊆ U → γ.Homotopic γ' :=
205+
forall_congr' fun _ => semilocallySimplyConnectedAt_iff_paths
206+
107207
/-! ### Helper lemmas for discreteness of path homotopy quotients -/
108208

109209
/-- In an SLSC neighborhood where loops are nullhomotopic, any two paths with the same
@@ -152,7 +252,7 @@ theorem exists_uniquePath_neighborhood (hX : SemilocallySimplyConnected X) (x :
152252
intro a b ha hb p q hp_range hq_range
153253
apply Path.homotopic_of_loops_nullhomotopic_in_neighborhood U
154254
· intro z γ hz hγ_range
155-
exact @hU_loops ⟨z, hz⟩ γ hγ_range
255+
exact hU_loops γ hγ_range
156256
· exact hp_range
157257
· exact hq_range
158258

@@ -663,12 +763,12 @@ theorem Path.paste_segment_homotopies {x y : X} {n : ℕ} (γ γ' : Path x y)
663763
apply exact
664764
simp only [γ_aux, mk_trans, mk_cast]
665765
-- Decompose γ|[0, i+1] = γ|[0, i] · γ|[i, i+1]
666-
rw [← subpathOn_trans γ
766+
rw [← Path.Homotopic.Quotient.subpathOn_trans γ
667767
(part.t 0) (part.t i.castSucc) (part.t i.succ)
668768
(part.h_mono.monotone (Fin.zero_le i.castSucc))
669769
(part.h_mono.monotone i.castSucc_lt_succ.le)]
670770
-- Decompose γ'|[i, last n] = γ'|[i, i+1] · γ'|[i+1, last n]
671-
rw [← subpathOn_trans γ'
771+
rw [← Path.Homotopic.Quotient.subpathOn_trans γ'
672772
(part.t i.castSucc) (part.t i.succ) (part.t (Fin.last n))
673773
(part.h_mono.monotone i.castSucc_lt_succ.le)
674774
(part.h_mono.monotone (Fin.le_last i.succ))]
@@ -939,6 +1039,6 @@ theorem Path.Homotopic.Quotient.discreteTopology
9391039
convert isOpen_setOf_homotopic hX p
9401040
ext p'
9411041
simp only [Set.mem_preimage, Set.mem_singleton_iff, Set.mem_setOf_eq]
942-
exact Quotient.eq (r := Path.Homotopic.setoid x y)
1042+
exact Path.Homotopic.Quotient.eq
9431043

944-
end SemilocallySimplyConnected
1044+
end

0 commit comments

Comments
 (0)