Skip to content

Commit 885688d

Browse files
committed
feat: lemmas for paths-up-to-homotopy (#31574)
We introduce `Path.Homotopic.Quotient.mk` as the normal form (rather than `_root_.Quotient.mk`) for constructing a path-up-to-homotopy from a path. This enables us to work more easily in the quotient. We add simp lemmas corresponding to the basic homotopies relating `refl` / `symm` / `trans` / `cast`.
1 parent e16997e commit 885688d

File tree

6 files changed

+206
-35
lines changed

6 files changed

+206
-35
lines changed

Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,69 @@ end Assoc
163163

164164
end Homotopy
165165

166+
namespace Homotopic
167+
168+
theorem refl_trans (p : Path x₀ x₁) :
169+
((Path.refl x₀).trans p).Homotopic p :=
170+
⟨Homotopy.reflTrans p⟩
171+
172+
theorem trans_refl (p : Path x₀ x₁) :
173+
(p.trans (Path.refl x₁)).Homotopic p :=
174+
⟨Homotopy.transRefl p⟩
175+
176+
theorem trans_symm (p : Path x₀ x₁) :
177+
(p.trans p.symm).Homotopic (Path.refl x₀) :=
178+
⟨(Homotopy.reflTransSymm p).symm⟩
179+
180+
theorem symm_trans (p : Path x₀ x₁) :
181+
(p.symm.trans p).Homotopic (Path.refl x₁) :=
182+
⟨(Homotopy.reflSymmTrans p).symm⟩
183+
184+
theorem trans_assoc {x₀ x₁ x₂ x₃ : X} (p : Path x₀ x₁) (q : Path x₁ x₂) (r : Path x₂ x₃) :
185+
((p.trans q).trans r).Homotopic (p.trans (q.trans r)) :=
186+
⟨Homotopy.transAssoc p q r⟩
187+
188+
namespace Quotient
189+
190+
@[simp, grind =]
191+
theorem refl_trans (γ : Homotopic.Quotient x₀ x₁) :
192+
trans (refl x₀) γ = γ := by
193+
induction γ using Quotient.ind with | mk γ =>
194+
simpa [← mk_trans, ← mk_refl, eq] using Homotopic.refl_trans γ
195+
196+
@[simp, grind =]
197+
theorem trans_refl (γ : Homotopic.Quotient x₀ x₁) :
198+
trans γ (refl x₁) = γ := by
199+
induction γ using Quotient.ind with | mk γ =>
200+
simpa [← mk_trans, ← mk_refl, eq] using Homotopic.trans_refl γ
201+
202+
@[simp, grind =]
203+
theorem trans_symm (γ : Homotopic.Quotient x₀ x₁) :
204+
trans γ (symm γ) = refl x₀ := by
205+
induction γ using Quotient.ind with | mk γ =>
206+
simpa [← mk_trans, ← mk_symm, ← mk_refl, eq] using Homotopic.trans_symm γ
207+
208+
@[simp, grind =]
209+
theorem symm_trans (γ : Homotopic.Quotient x₀ x₁) :
210+
trans (symm γ) γ = refl x₁ := by
211+
induction γ using Quotient.ind with | mk γ =>
212+
simpa [← mk_trans, ← mk_symm, ← mk_refl, eq] using Homotopic.symm_trans γ
213+
214+
@[simp, grind _=_]
215+
theorem trans_assoc {x₀ x₁ x₂ x₃ : X}
216+
(γ₀ : Homotopic.Quotient x₀ x₁)
217+
(γ₁ : Homotopic.Quotient x₁ x₂)
218+
(γ₂ : Homotopic.Quotient x₂ x₃) :
219+
trans (trans γ₀ γ₁) γ₂ = trans γ₀ (trans γ₁ γ₂) := by
220+
induction γ₀ using Quotient.ind with | mk γ₀ =>
221+
induction γ₁ using Quotient.ind with | mk γ₁ =>
222+
induction γ₂ using Quotient.ind with | mk γ₂ =>
223+
simpa [← mk_trans, eq] using Homotopic.trans_assoc γ₀ γ₁ γ₂
224+
225+
end Quotient
226+
227+
end Homotopic
228+
166229
end Path
167230

168231
/-- The fundamental groupoid of a space `X` is defined to be a wrapper around `X`, and we
@@ -218,22 +281,22 @@ instance {X : Type*} [Inhabited X] : Inhabited (FundamentalGroupoid X) :=
218281
instance : Groupoid (FundamentalGroupoid X) where
219282
Hom x y := Path.Homotopic.Quotient x.as y.as
220283
id x := ⟦Path.refl x.as⟧
221-
comp := Path.Homotopic.Quotient.comp
284+
comp := Path.Homotopic.Quotient.trans
222285
id_comp := by rintro _ _ ⟨f⟩; exact Quotient.sound ⟨Path.Homotopy.reflTrans f⟩
223286
comp_id := by rintro _ _ ⟨f⟩; exact Quotient.sound ⟨Path.Homotopy.transRefl f⟩
224287
assoc := by rintro _ _ _ _ ⟨f⟩ ⟨g⟩ ⟨h⟩; exact Quotient.sound ⟨Path.Homotopy.transAssoc f g h⟩
225288
inv := Quotient.lift (fun f ↦ ⟦f.symm⟧) (by rintro a b ⟨h⟩; exact Quotient.sound ⟨h.symm₂⟩)
226289
inv_comp := by rintro _ _ ⟨f⟩; exact Quotient.sound ⟨(Path.Homotopy.reflSymmTrans f).symm⟩
227290
comp_inv := by rintro _ _ ⟨f⟩; exact Quotient.sound ⟨(Path.Homotopy.reflTransSymm f).symm⟩
228291

229-
theorem comp_eq (x y z : FundamentalGroupoid X) (p : x ⟶ y) (q : y ⟶ z) : p ≫ q = p.comp q := rfl
292+
theorem comp_eq (x y z : FundamentalGroupoid X) (p : x ⟶ y) (q : y ⟶ z) : p ≫ q = p.trans q := rfl
230293

231294
theorem id_eq_path_refl (x : FundamentalGroupoid X) : 𝟙 x = ⟦Path.refl x.as⟧ := rfl
232295

233296
/-- The functor on fundamental groupoid induced by a continuous map. -/
234297
@[simps] def map (f : C(X, Y)) : FundamentalGroupoid X ⥤ FundamentalGroupoid Y where
235298
obj x := ⟨f x.as⟩
236-
map p := p.mapFn f
299+
map p := p.map f
237300
map_id _ := rfl
238301
map_comp := by rintro _ _ _ ⟨p⟩ ⟨q⟩; exact congr_arg Quotient.mk'' (p.map_trans q f.continuous)
239302

@@ -253,7 +316,7 @@ scoped notation "πₓ" => FundamentalGroupoid.fundamentalGroupoidFunctor.obj
253316
scoped notation "πₘ" => FundamentalGroupoid.fundamentalGroupoidFunctor.map
254317

255318
theorem map_eq {X Y : TopCat} {x₀ x₁ : X} (f : C(X, Y)) (p : Path.Homotopic.Quotient x₀ x₁) :
256-
(πₘ (TopCat.ofHom f)).map p = p.mapFn f := rfl
319+
(πₘ (TopCat.ofHom f)).map p = p.map f := rfl
257320

258321
/-- Help the typechecker by converting a point in a groupoid back to a point in
259322
the underlying topological space. -/

Mathlib/AlgebraicTopology/FundamentalGroupoid/InducedMaps.lean

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ include hfg
8484
/-- If `f(p(t) = g(q(t))` for two paths `p` and `q`, then the induced path homotopy classes
8585
`f(p)` and `g(p)` are the same as well, despite having a priori different types -/
8686
theorem heq_path_of_eq_image :
87-
(πₘ (TopCat.ofHom f)).map ⟦p⟧ ≍ (πₘ (TopCat.ofHom g)).map ⟦q⟧ := by
88-
simp only [map_eq, ← Path.Homotopic.map_lift]; apply Path.Homotopic.hpath_hext; exact hfg
87+
(πₘ (TopCat.ofHom f)).map ⟦p⟧ ≍ (πₘ (TopCat.ofHom g)).map (Path.Homotopic.Quotient.mk q) := by
88+
simp only [map_eq, ← Path.Homotopic.Quotient.mk_map]
89+
apply Path.Homotopic.hpath_hext
90+
exact hfg
8991

9092
private theorem start_path : f x₀ = g x₂ := by convert hfg 0 <;> simp only [Path.source]
9193

Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def piToPiTop : (∀ i, πₓ (X i)) ⥤ πₓ (TopCat.of (∀ i, X i)) where
5656
obj g := ⟨fun i => (g i).as⟩
5757
map p := Path.Homotopic.pi p
5858
map_id x := by
59-
change (Path.Homotopic.pi fun i => ⟦_⟧) = _
59+
change (Path.Homotopic.pi fun i => Path.Homotopic.Quotient.mk _) = _
6060
simp only [Path.Homotopic.pi_lift]
6161
rfl
6262
map_comp f g := (Path.Homotopic.comp_pi_eq_pi_comp f g).symm

Mathlib/Topology/Homotopy/Lifting.lean

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,12 @@ theorem liftPath_apply_one_eq_of_homotopicRel {γ₀ γ₁ : C(I, X)}
346346
/-- A covering map induces an injection on all Hom-sets of the fundamental groupoid,
347347
in particular on the fundamental group. -/
348348
lemma injective_path_homotopic_mapFn (e₀ e₁ : E) :
349-
Function.Injective fun γ : Path.Homotopic.Quotient e₀ e₁ ↦ γ.mapFn ⟨p, cov.continuous⟩ := by
349+
Function.Injective fun γ : Path.Homotopic.Quotient e₀ e₁ ↦ γ.map ⟨p, cov.continuous⟩ := by
350350
refine Quotient.ind₂ fun γ₀ γ₁ ↦ ?_
351351
dsimp only
352-
simp_rw [← Path.Homotopic.map_lift]
353-
iterate 2 rw [Quotient.eq]
352+
simp only [Path.Homotopic.Quotient.mk''_eq_mk]
353+
simp_rw [← Path.Homotopic.Quotient.mk_map]
354+
iterate 2 rw [Path.Homotopic.Quotient.eq]
354355
exact (cov.homotopicRel_iff_comp ⟨0, .inl rfl, γ₀.source.trans γ₁.source.symm⟩).mpr
355356

356357
/-- A map `f` from a simply-connected, locally path-connected space `A` to another space `X` lifts

Mathlib/Topology/Homotopy/Path.lean

Lines changed: 108 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ theorem refl (p : Path x₀ x₁) : p.Homotopic p :=
240240
theorem symm ⦃p₀ p₁ : Path x₀ x₁⦄ (h : p₀.Homotopic p₁) : p₁.Homotopic p₀ :=
241241
h.map Homotopy.symm
242242

243+
theorem symm₂ {p q : Path x₀ x₁} (h : p.Homotopic q) : p.symm.Homotopic q.symm :=
244+
h.map Homotopy.symm₂
245+
243246
@[trans]
244247
theorem trans ⦃p₀ p₁ p₂ : Path x₀ x₁⦄ (h₀ : p₀.Homotopic p₁) (h₁ : p₁.Homotopic p₂) :
245248
p₀.Homotopic p₂ :=
@@ -278,23 +281,123 @@ attribute [local instance] Homotopic.setoid
278281
instance : Inhabited (Homotopic.Quotient () ()) :=
279282
⟨Quotient.mk' <| Path.refl ()⟩
280283

284+
namespace Quotient
285+
286+
/--
287+
The canonical map from `Path x₀ x₁` to `Path.Homotopic.Quotient x₀ x₁`.
288+
289+
We prefer this as the normal form, rather than generic `_root_.Quotient.mk'`,
290+
to have better control of simp lemmas.
291+
-/
292+
def mk (p : Path x₀ x₁) : Path.Homotopic.Quotient x₀ x₁ :=
293+
_root_.Quotient.mk' p
294+
295+
/-- `Path.Homotopic.Quotient.mk` is the simp normal form. -/
296+
@[simp] theorem mk'_eq_mk (p : Path x₀ x₁) : Quotient.mk' p = mk p := rfl
297+
@[simp] theorem mk''_eq_mk (p : Path x₀ x₁) : Quotient.mk'' p = mk p := rfl
298+
299+
theorem exact {p q : Path x₀ x₁} (h : Quotient.mk p = Quotient.mk q) :
300+
Homotopic p q := by
301+
exact _root_.Quotient.exact h
302+
303+
theorem eq {p q : Path x₀ x₁} : mk p = mk q ↔ Homotopic p q :=
304+
_root_.Quotient.eq
305+
306+
/--
307+
A reasoning principle for quotients that allows proofs about quotients to assume that all values are
308+
constructed with `Quotient.mk`.
309+
-/
310+
@[induction_eliminator]
311+
protected theorem ind {x y : X} {motive : Homotopic.Quotient x y → Prop} :
312+
(mk : (a : Path x y) → motive (Quotient.mk a)) → (q : Homotopic.Quotient x y) → motive q :=
313+
Quot.ind
314+
315+
/--
316+
A reasoning principle for quotients that allows proofs about quotients to assume that all values are
317+
constructed with `Quotient.mk`. This is the two-variable version of `ind`.
318+
-/
319+
@[elab_as_elim]
320+
protected theorem ind₂ {Y : Type*} [TopologicalSpace Y] {x₀ y₀ : X} {x₁ y₁ : Y}
321+
{motive : Homotopic.Quotient x₀ y₀ → Path.Homotopic.Quotient x₁ y₁ → Prop}
322+
(mk : (a : Path x₀ y₀) → (b : Path x₁ y₁) → motive (Quotient.mk a) (Quotient.mk b))
323+
(q₀ : Homotopic.Quotient x₀ y₀) (q₁ : Path.Homotopic.Quotient x₁ y₁) : motive q₀ q₁ := by
324+
induction q₀ using Quot.ind with | mk a =>
325+
induction q₁ using Quot.ind with | mk b =>
326+
exact mk a b
327+
328+
/-- The constant path homotopy class at a point. This is `Path.refl` descended to the quotient. -/
329+
def refl (x : X) : Path.Homotopic.Quotient x x :=
330+
mk (Path.refl x)
331+
332+
@[simp, grind =]
333+
theorem mk_refl (x : X) : mk (Path.refl x) = refl x :=
334+
rfl
335+
336+
/-- The reverse of a path homotopy class. This is `Path.symm` descended to the quotient. -/
337+
def symm (P : Path.Homotopic.Quotient x₀ x₁) : Path.Homotopic.Quotient x₁ x₀ :=
338+
_root_.Quotient.map Path.symm (fun _ _ h => Homotopic.symm₂ h) P
339+
340+
@[simp, grind =]
341+
theorem mk_symm (P : Path x₀ x₁) : mk P.symm = symm (mk P) :=
342+
rfl
343+
344+
/-- Cast a path homotopy class using equalities of endpoints. -/
345+
def cast {x y : X} (γ : Homotopic.Quotient x y) {x' y'} (hx : x' = x) (hy : y' = y) :
346+
Homotopic.Quotient x' y' :=
347+
_root_.Quotient.map (fun p => p.cast hx hy)
348+
(fun _ _ h => Nonempty.map (fun F => F.cast (by simp) (by simp)) h) γ
349+
350+
@[simp, grind =]
351+
theorem mk_cast {x y : X} (P : Path x y) {x' y'} (hx : x' = x) (hy : y' = y) :
352+
mk (P.cast hx hy) = (mk P).cast hx hy :=
353+
rfl
354+
355+
@[simp, grind =]
356+
theorem cast_rfl_rfl {x y : X} (γ : Homotopic.Quotient x y) : γ.cast rfl rfl = γ := by
357+
induction γ using Quotient.ind with | mk γ =>
358+
rfl
359+
360+
@[simp, grind =]
361+
theorem cast_cast {x y : X} (γ : Homotopic.Quotient x y) {x' y'} (hx : x' = x) (hy : y' = y)
362+
{x'' y''} (hx' : x'' = x') (hy' : y'' = y') :
363+
(γ.cast hx hy).cast hx' hy' = γ.cast (hx'.trans hx) (hy'.trans hy) := by
364+
induction γ using Quotient.ind with | mk γ =>
365+
rfl
366+
281367
/-- The composition of path homotopy classes. This is `Path.trans` descended to the quotient. -/
282-
def Quotient.comp (P₀ : Path.Homotopic.Quotient x₀ x₁) (P₁ : Path.Homotopic.Quotient x₁ x₂) :
368+
def trans (P₀ : Path.Homotopic.Quotient x₀ x₁) (P₁ : Path.Homotopic.Quotient x₁ x₂) :
283369
Path.Homotopic.Quotient x₀ x₂ :=
284370
Quotient.map₂ Path.trans (fun (_ : Path x₀ x₁) _ hp (_ : Path x₁ x₂) _ hq => hcomp hp hq) P₀ P₁
285371

286-
theorem comp_lift (P₀ : Path x₀ x₁) (P₁ : Path x₁ x₂) : ⟦P₀.trans P₁⟧ = Quotient.comp ⟦P₀⟧ ⟦P₁⟧ :=
372+
@[deprecated (since := "2025-11-13")]
373+
noncomputable alias _root_.Path.Homotopic.comp := Quotient.trans
374+
375+
@[simp, grind =]
376+
theorem mk_trans (P₀ : Path x₀ x₁) (P₁ : Path x₁ x₂) :
377+
mk (P₀.trans P₁) = Quotient.trans (mk P₀) (mk P₁) :=
287378
rfl
288379

380+
@[deprecated (since := "2025-11-13")]
381+
noncomputable alias _root_.Path.Homotopic.comp_lift := Quotient.mk_trans
382+
289383
/-- The image of a path homotopy class `P₀` under a map `f`.
290384
This is `Path.map` descended to the quotient. -/
291-
def Quotient.mapFn (P₀ : Path.Homotopic.Quotient x₀ x₁) (f : C(X, Y)) :
385+
def map (P₀ : Path.Homotopic.Quotient x₀ x₁) (f : C(X, Y)) :
292386
Path.Homotopic.Quotient (f x₀) (f x₁) :=
293-
Quotient.map (fun q : Path x₀ x₁ => q.map f.continuous) (fun _ _ h => Path.Homotopic.map h f) P₀
387+
_root_.Quotient.map
388+
(fun q : Path x₀ x₁ => q.map f.continuous) (fun _ _ h => Path.Homotopic.map h f) P₀
294389

295-
theorem map_lift (P₀ : Path x₀ x₁) (f : C(X, Y)) : ⟦P₀.map f.continuous⟧ = Quotient.mapFn ⟦P₀⟧ f :=
390+
@[deprecated (since := "2025-11-13")]
391+
noncomputable alias _root_.Path.Homotopic.mapFn := Quotient.map
392+
393+
theorem mk_map (P₀ : Path x₀ x₁) (f : C(X, Y)) : mk (P₀.map f.continuous) = map (mk P₀) f :=
296394
rfl
297395

396+
@[deprecated (since := "2025-11-13")]
397+
noncomputable alias _root_.Path.Homotopic.map_lift := Quotient.mk_map
398+
399+
end Quotient
400+
298401
-- Porting note: we didn't previously need the `α := ...` and `β := ...` hints.
299402
theorem hpath_hext {p₁ : Path x₀ x₁} {p₂ : Path x₂ x₃} (hp : ∀ t, p₁ t = p₂ t) :
300403
HEq (α := Path.Homotopic.Quotient _ _) ⟦p₁⟧ (β := Path.Homotopic.Quotient _ _) ⟦p₂⟧ := by

Mathlib/Topology/Homotopy/Product.lean

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ end ContinuousMap
9898

9999
namespace Path.Homotopic
100100

101-
local infixl:70 " ⬝ " => Quotient.comp
101+
local infixl:70 " ⬝ " => Quotient.trans
102102

103103
section Pi
104104

@@ -111,38 +111,40 @@ def piHomotopy (γ₀ γ₁ : ∀ i, Path (as i) (bs i)) (H : ∀ i, Path.Homoto
111111

112112
/-- The product of a family of path homotopy classes. -/
113113
def pi (γ : ∀ i, Path.Homotopic.Quotient (as i) (bs i)) : Path.Homotopic.Quotient as bs :=
114-
(Quotient.map Path.pi fun x y hxy =>
114+
(_root_.Quotient.map Path.pi fun x y hxy =>
115115
Nonempty.map (piHomotopy x y) (Classical.nonempty_pi.mpr hxy)) (Quotient.choice γ)
116116

117117
theorem pi_lift (γ : ∀ i, Path (as i) (bs i)) :
118-
(Path.Homotopic.pi fun i => ⟦γ i⟧) = ⟦Path.pi γ⟧ := by unfold pi; simp
118+
(Path.Homotopic.pi fun i => (Quotient.mk (γ i))) = Quotient.mk (Path.pi γ) := by
119+
simp_rw [← Quotient.mk'_eq_mk, Quotient.mk', pi, Quotient.choice_eq, Quotient.map_mk]
119120

120121
/-- Composition and products commute.
121122
This is `Path.trans_pi_eq_pi_trans` descended to path homotopy classes. -/
122123
theorem comp_pi_eq_pi_comp (γ₀ : ∀ i, Path.Homotopic.Quotient (as i) (bs i))
123124
(γ₁ : ∀ i, Path.Homotopic.Quotient (bs i) (cs i)) : pi γ₀ ⬝ pi γ₁ = pi fun i ↦ γ₀ i ⬝ γ₁ i := by
124125
induction γ₁ using Quotient.induction_on_pi with | _ a =>
125126
induction γ₀ using Quotient.induction_on_pi
126-
simp only [pi_lift]
127-
rw [← Path.Homotopic.comp_lift, Path.trans_pi_eq_pi_trans, ← pi_lift]
127+
simp only [Quotient.mk''_eq_mk, pi_lift]
128+
rw [← Path.Homotopic.Quotient.mk_trans, Path.trans_pi_eq_pi_trans, ← pi_lift]
128129
rfl
129130

130131
/-- Abbreviation for projection onto the ith coordinate. -/
131132
abbrev proj (i : ι) (p : Path.Homotopic.Quotient as bs) : Path.Homotopic.Quotient (as i) (bs i) :=
132-
p.mapFn ⟨_, continuous_apply i⟩
133+
p.map ⟨_, continuous_apply i⟩
133134

134135
/-- Lemmas showing projection is the inverse of pi. -/
135136
@[simp]
136137
theorem proj_pi (i : ι) (paths : ∀ i, Path.Homotopic.Quotient (as i) (bs i)) :
137138
proj i (pi paths) = paths i := by
138139
induction paths using Quotient.induction_on_pi
139-
rw [proj, pi_lift, ← Path.Homotopic.map_lift]
140+
simp only [Quotient.mk''_eq_mk]
141+
rw [proj, pi_lift]
140142
congr
141143

142144
@[simp]
143145
theorem pi_proj (p : Path.Homotopic.Quotient as bs) : (pi fun i => proj i p) = p := by
144146
induction p using Quotient.inductionOn
145-
simp_rw [proj, ← Path.Homotopic.map_lift]
147+
simp_rw [Quotient.mk''_eq_mk, proj, ← Path.Homotopic.Quotient.mk_map]
146148
erw [pi_lift]
147149
congr
148150

@@ -167,46 +169,46 @@ def prod (q₁ : Path.Homotopic.Quotient a₁ a₂) (q₂ : Path.Homotopic.Quoti
167169

168170
variable (p₁ p₁' p₂ p₂')
169171

170-
theorem prod_lift : prod ⟦p₁⟧ ⟦p₂⟧ = p₁.prod p₂ :=
172+
theorem prod_lift : prod (Quotient.mk p₁) (Quotient.mk p₂) = Quotient.mk (p₁.prod p₂) :=
171173
rfl
172174

173175
variable (r₁ : Path.Homotopic.Quotient a₂ a₃) (r₂ : Path.Homotopic.Quotient b₂ b₃)
174176

175177
/-- Products commute with path composition.
176178
This is `trans_prod_eq_prod_trans` descended to the quotient. -/
177179
theorem comp_prod_eq_prod_comp : prod q₁ q₂ ⬝ prod r₁ r₂ = prod (q₁ ⬝ r₁) (q₂ ⬝ r₂) := by
178-
induction q₁, q₂ using Quotient.inductionOn
179-
induction r₁, r₂ using Quotient.inductionOn
180-
simp only [prod_lift, ← Path.Homotopic.comp_lift, Path.trans_prod_eq_prod_trans]
180+
induction q₁, q₂ using Path.Homotopic.Quotient.ind
181+
induction r₁, r₂ using Path.Homotopic.Quotient.ind
182+
simp only [prod_lift, ← Path.Homotopic.Quotient.mk_trans, Path.trans_prod_eq_prod_trans]
181183

182184
variable {c₁ c₂ : α × β}
183185

184186
/-- Abbreviation for projection onto the left coordinate of a path class. -/
185187
abbrev projLeft (p : Path.Homotopic.Quotient c₁ c₂) : Path.Homotopic.Quotient c₁.1 c₂.1 :=
186-
p.mapFn ⟨_, continuous_fst⟩
188+
p.map ⟨_, continuous_fst⟩
187189

188190
/-- Abbreviation for projection onto the right coordinate of a path class. -/
189191
abbrev projRight (p : Path.Homotopic.Quotient c₁ c₂) : Path.Homotopic.Quotient c₁.2 c₂.2 :=
190-
p.mapFn ⟨_, continuous_snd⟩
192+
p.map ⟨_, continuous_snd⟩
191193

192194
/-- Lemmas showing projection is the inverse of product. -/
193195
@[simp]
194196
theorem projLeft_prod : projLeft (prod q₁ q₂) = q₁ := by
195-
induction q₁, q₂ using Quotient.inductionOn
196-
rw [projLeft, prod_lift, ← Path.Homotopic.map_lift]
197+
induction q₁, q₂ using Path.Homotopic.Quotient.ind
198+
rw [projLeft, prod_lift, ← Path.Homotopic.Quotient.mk_map]
197199
congr
198200

199201
@[simp]
200202
theorem projRight_prod : projRight (prod q₁ q₂) = q₂ := by
201-
induction q₁, q₂ using Quotient.inductionOn
202-
rw [projRight, prod_lift, ← Path.Homotopic.map_lift]
203+
induction q₁, q₂ using Path.Homotopic.Quotient.ind
204+
rw [projRight, prod_lift, ← Path.Homotopic.Quotient.mk_map]
203205
congr
204206

205207
@[simp]
206208
theorem prod_projLeft_projRight (p : Path.Homotopic.Quotient (a₁, b₁) (a₂, b₂)) :
207209
prod (projLeft p) (projRight p) = p := by
208-
induction p using Quotient.inductionOn
209-
simp only [projLeft, projRight, ← Path.Homotopic.map_lift]
210+
induction p using Path.Homotopic.Quotient.ind
211+
simp only [projLeft, projRight, ← Path.Homotopic.Quotient.mk_map]
210212
congr
211213

212214
end Prod

0 commit comments

Comments
 (0)