Skip to content

Commit ef02d66

Browse files
committed
feat port/CategoryTheory.EqToHom (#2207)
1 parent 21ba590 commit ef02d66

File tree

2 files changed

+313
-0
lines changed

2 files changed

+313
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ import Mathlib.CategoryTheory.Category.Basic
220220
import Mathlib.CategoryTheory.Category.KleisliCat
221221
import Mathlib.CategoryTheory.Category.RelCat
222222
import Mathlib.CategoryTheory.ConcreteCategory.Bundled
223+
import Mathlib.CategoryTheory.EqToHom
223224
import Mathlib.CategoryTheory.Equivalence
224225
import Mathlib.CategoryTheory.EssentialImage
225226
import Mathlib.CategoryTheory.FullSubcategory
Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
/-
2+
Copyright (c) 2018 Reid Barton. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Reid Barton, Scott Morrison
5+
6+
! This file was ported from Lean 3 source module category_theory.eq_to_hom
7+
! leanprover-community/mathlib commit dc6c365e751e34d100e80fe6e314c3c3e0fd2988
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.CategoryTheory.Opposites
12+
13+
/-!
14+
# Morphisms from equations between objects.
15+
16+
When working categorically, sometimes one encounters an equation `h : X = Y` between objects.
17+
18+
Your initial aversion to this is natural and appropriate:
19+
you're in for some trouble, and if there is another way to approach the problem that won't
20+
rely on this equality, it may be worth pursuing.
21+
22+
You have two options:
23+
1. Use the equality `h` as one normally would in Lean (e.g. using `rw` and `subst`).
24+
This may immediately cause difficulties, because in category theory everything is dependently
25+
typed, and equations between objects quickly lead to nasty goals with `eq.rec`.
26+
2. Promote `h` to a morphism using `eqToHom h : X ⟶ Y`, or `eqToIso h : X ≅ Y`.
27+
28+
This file introduces various `simp` lemmas which in favourable circumstances
29+
result in the various `eqToHom` morphisms to drop out at the appropriate moment!
30+
-/
31+
32+
33+
universe v₁ v₂ v₃ u₁ u₂ u₃
34+
35+
-- morphism levels before object levels. See note [category_theory universes].
36+
namespace CategoryTheory
37+
38+
open Opposite
39+
40+
variable {C : Type u₁} [Category.{v₁} C]
41+
42+
/-- An equality `X = Y` gives us a morphism `X ⟶ Y`.
43+
44+
It is typically better to use this, rather than rewriting by the equality then using `𝟙 _`
45+
which usually leads to dependent type theory hell.
46+
-/
47+
def eqToHom {X Y : C} (p : X = Y) : X ⟶ Y := by rw [p]; exact 𝟙 _
48+
#align category_theory.eq_to_hom CategoryTheory.eqToHom
49+
50+
@[simp]
51+
theorem eqToHom_refl (X : C) (p : X = X) : eqToHom p = 𝟙 X :=
52+
rfl
53+
#align category_theory.eq_to_hom_refl CategoryTheory.eqToHom_refl
54+
55+
@[reassoc (attr := simp)]
56+
theorem eqToHom_trans {X Y Z : C} (p : X = Y) (q : Y = Z) :
57+
eqToHom p ≫ eqToHom q = eqToHom (p.trans q) :=
58+
by
59+
cases p
60+
cases q
61+
simp
62+
#align category_theory.eq_to_hom_trans CategoryTheory.eqToHom_trans
63+
64+
theorem comp_eqToHom_iff {X Y Y' : C} (p : Y = Y') (f : X ⟶ Y) (g : X ⟶ Y') :
65+
f ≫ eqToHom p = g ↔ f = g ≫ eqToHom p.symm :=
66+
{ mp := fun h => h ▸ by simp
67+
mpr := fun h => by simp [eq_whisker h (eqToHom p)] }
68+
#align category_theory.comp_eq_to_hom_iff CategoryTheory.comp_eqToHom_iff
69+
70+
theorem eqToHom_comp_iff {X X' Y : C} (p : X = X') (f : X ⟶ Y) (g : X' ⟶ Y) :
71+
eqToHom p ≫ g = f ↔ g = eqToHom p.symm ≫ f :=
72+
{ mp := fun h => h ▸ by simp
73+
mpr := fun h => h ▸ by simp [whisker_eq _ h] }
74+
#align category_theory.eq_to_hom_comp_iff CategoryTheory.eqToHom_comp_iff
75+
76+
/- Porting note: simpNF complains about thsi not reducing but it is clearly used
77+
in `congrArg_mrp_hom_left`. It has been no-linted. -/
78+
/-- Reducible form of congrArg_mpr_hom_left -/
79+
@[simp, nolint simpNF]
80+
theorem congrArg_cast_hom_left {X Y Z : C} (p : X = Y) (q : Y ⟶ Z) :
81+
cast (congrArg (fun W : C => W ⟶ Z) p.symm) q = eqToHom p ≫ q := by
82+
cases p
83+
simp
84+
85+
/-- If we (perhaps unintentionally) perform equational rewriting on
86+
the source object of a morphism,
87+
we can replace the resulting `_.mpr f` term by a composition with an `eqToHom`.
88+
89+
It may be advisable to introduce any necessary `eqToHom` morphisms manually,
90+
rather than relying on this lemma firing.
91+
-/
92+
theorem congrArg_mpr_hom_left {X Y Z : C} (p : X = Y) (q : Y ⟶ Z) :
93+
(congrArg (fun W : C => W ⟶ Z) p).mpr q = eqToHom p ≫ q :=
94+
by
95+
cases p
96+
simp
97+
#align category_theory.congr_arg_mpr_hom_left CategoryTheory.congrArg_mpr_hom_left
98+
99+
/- Porting note: simpNF complains about thsi not reducing but it is clearly used
100+
in `congrArg_mrp_hom_right`. It has been no-linted. -/
101+
/-- Reducible form of `congrArg_mpr_hom_right` -/
102+
@[simp, nolint simpNF]
103+
theorem congrArg_cast_hom_right {X Y Z : C} (p : X ⟶ Y) (q : Z = Y) :
104+
cast (congrArg (fun W : C => X ⟶ W) q.symm) p = p ≫ eqToHom q.symm := by
105+
cases q
106+
simp
107+
108+
/-- If we (perhaps unintentionally) perform equational rewriting on
109+
the target object of a morphism,
110+
we can replace the resulting `_.mpr f` term by a composition with an `eqToHom`.
111+
112+
It may be advisable to introduce any necessary `eqToHom` morphisms manually,
113+
rather than relying on this lemma firing.
114+
-/
115+
theorem congrArg_mpr_hom_right {X Y Z : C} (p : X ⟶ Y) (q : Z = Y) :
116+
(congrArg (fun W : C => X ⟶ W) q).mpr p = p ≫ eqToHom q.symm :=
117+
by
118+
cases q
119+
simp
120+
#align category_theory.congr_arg_mpr_hom_right CategoryTheory.congrArg_mpr_hom_right
121+
122+
/-- An equality `X = Y` gives us an isomorphism `X ≅ Y`.
123+
124+
It is typically better to use this, rather than rewriting by the equality then using `Iso.refl _`
125+
which usually leads to dependent type theory hell.
126+
-/
127+
def eqToIso {X Y : C} (p : X = Y) : X ≅ Y :=
128+
⟨eqToHom p, eqToHom p.symm, by simp, by simp⟩
129+
#align category_theory.eq_to_iso CategoryTheory.eqToIso
130+
131+
@[simp]
132+
theorem eqToIso.hom {X Y : C} (p : X = Y) : (eqToIso p).hom = eqToHom p :=
133+
rfl
134+
#align category_theory.eq_to_iso.hom CategoryTheory.eqToIso.hom
135+
136+
@[simp]
137+
theorem eqToIso.inv {X Y : C} (p : X = Y) : (eqToIso p).inv = eqToHom p.symm :=
138+
rfl
139+
#align category_theory.eq_to_iso.inv CategoryTheory.eqToIso.inv
140+
141+
@[simp]
142+
theorem eqToIso_refl {X : C} (p : X = X) : eqToIso p = Iso.refl X :=
143+
rfl
144+
#align category_theory.eq_to_iso_refl CategoryTheory.eqToIso_refl
145+
146+
@[simp]
147+
theorem eqToIso_trans {X Y Z : C} (p : X = Y) (q : Y = Z) :
148+
eqToIso p ≪≫ eqToIso q = eqToIso (p.trans q) := by ext; simp
149+
#align category_theory.eq_to_iso_trans CategoryTheory.eqToIso_trans
150+
151+
@[simp]
152+
theorem eqToHom_op {X Y : C} (h : X = Y) : (eqToHom h).op = eqToHom (congr_arg op h.symm) :=
153+
by
154+
cases h
155+
rfl
156+
#align category_theory.eq_to_hom_op CategoryTheory.eqToHom_op
157+
158+
@[simp]
159+
theorem eqToHom_unop {X Y : Cᵒᵖ} (h : X = Y) : (eqToHom h).unop = eqToHom (congr_arg unop h.symm) :=
160+
by
161+
cases h
162+
rfl
163+
#align category_theory.eq_to_hom_unop CategoryTheory.eqToHom_unop
164+
165+
instance {X Y : C} (h : X = Y) : IsIso (eqToHom h) :=
166+
IsIso.of_iso (eqToIso h)
167+
168+
@[simp]
169+
theorem inv_eqToHom {X Y : C} (h : X = Y) : inv (eqToHom h) = eqToHom h.symm :=
170+
by
171+
aesop_cat
172+
#align category_theory.inv_eq_to_hom CategoryTheory.inv_eqToHom
173+
174+
variable {D : Type u₂} [Category.{v₂} D]
175+
176+
namespace Functor
177+
178+
/-- Proving equality between functors. This isn't an extensionality lemma,
179+
because usually you don't really want to do this. -/
180+
theorem ext {F G : C ⥤ D} (h_obj : ∀ X, F.obj X = G.obj X)
181+
(h_map : ∀ X Y f, F.map f = eqToHom (h_obj X) ≫ G.map f ≫ eqToHom (h_obj Y).symm) : F = G :=
182+
by
183+
match F, G with
184+
| mk F_pre _ _ , mk G_pre _ _ =>
185+
match F_pre, G_pre with -- Porting note: did not unfold the Prefunctor unlike Lean3
186+
| Prefunctor.mk F_obj _ , Prefunctor.mk G_obj _ =>
187+
obtain rfl : F_obj = G_obj := by
188+
ext X
189+
apply h_obj
190+
congr
191+
funext X Y f
192+
simpa using h_map X Y f
193+
#align category_theory.functor.ext CategoryTheory.Functor.ext
194+
195+
/-- Two morphisms are conjugate via eqToHom if and only if they are heterogeneously equal. -/
196+
theorem conj_eqToHom_iff_hEq {W X Y Z : C} (f : W ⟶ X) (g : Y ⟶ Z) (h : W = Y) (h' : X = Z) :
197+
f = eqToHom h ≫ g ≫ eqToHom h'.symm ↔ HEq f g :=
198+
by
199+
cases h
200+
cases h'
201+
simp
202+
#align category_theory.functor.conj_eq_to_hom_iff_heq CategoryTheory.Functor.conj_eqToHom_iff_hEq
203+
204+
/-- Proving equality between functors using heterogeneous equality. -/
205+
theorem hext {F G : C ⥤ D} (h_obj : ∀ X, F.obj X = G.obj X)
206+
(h_map : ∀ (X Y) (f : X ⟶ Y), HEq (F.map f) (G.map f)) : F = G :=
207+
Functor.ext h_obj fun _ _ f => (conj_eqToHom_iff_hEq _ _ (h_obj _) (h_obj _)).2 <| h_map _ _ f
208+
#align category_theory.functor.hext CategoryTheory.Functor.hext
209+
210+
-- Using equalities between functors.
211+
theorem congr_obj {F G : C ⥤ D} (h : F = G) (X) : F.obj X = G.obj X := by rw [h]
212+
#align category_theory.functor.congr_obj CategoryTheory.Functor.congr_obj
213+
214+
theorem congr_hom {F G : C ⥤ D} (h : F = G) {X Y} (f : X ⟶ Y) :
215+
F.map f = eqToHom (congr_obj h X) ≫ G.map f ≫ eqToHom (congr_obj h Y).symm := by
216+
subst h; simp
217+
#align category_theory.functor.congr_hom CategoryTheory.Functor.congr_hom
218+
219+
theorem congr_inv_of_congr_hom (F G : C ⥤ D) {X Y : C} (e : X ≅ Y) (hX : F.obj X = G.obj X)
220+
(hY : F.obj Y = G.obj Y)
221+
(h₂ : F.map e.hom = eqToHom (by rw [hX]) ≫ G.map e.hom ≫ eqToHom (by rw [hY])) :
222+
F.map e.inv = eqToHom (by rw [hY]) ≫ G.map e.inv ≫ eqToHom (by rw [hX]) := by
223+
simp only [← IsIso.Iso.inv_hom e, Functor.map_inv, h₂, IsIso.inv_comp, inv_eqToHom,
224+
Category.assoc]
225+
#align category_theory.functor.congr_inv_of_congr_hom CategoryTheory.Functor.congr_inv_of_congr_hom
226+
227+
theorem congr_map (F : C ⥤ D) {X Y : C} {f g : X ⟶ Y} (h : f = g) : F.map f = F.map g := by rw [h]
228+
#align category_theory.functor.congr_map CategoryTheory.Functor.congr_map
229+
230+
section HEq
231+
232+
-- Composition of functors and maps w.r.t. heq
233+
variable {E : Type u₃} [Category.{v₃} E] {F G : C ⥤ D} {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z}
234+
235+
theorem map_comp_hEq (hx : F.obj X = G.obj X) (hy : F.obj Y = G.obj Y) (hz : F.obj Z = G.obj Z)
236+
(hf : HEq (F.map f) (G.map f)) (hg : HEq (F.map g) (G.map g)) :
237+
HEq (F.map (f ≫ g)) (G.map (f ≫ g)) :=
238+
by
239+
rw [F.map_comp, G.map_comp]
240+
congr
241+
#align category_theory.functor.map_comp_heq CategoryTheory.Functor.map_comp_hEq
242+
243+
theorem map_comp_heq' (hobj : ∀ X : C, F.obj X = G.obj X)
244+
(hmap : ∀ {X Y} (f : X ⟶ Y), HEq (F.map f) (G.map f)) : HEq (F.map (f ≫ g)) (G.map (f ≫ g)) :=
245+
by rw [Functor.hext hobj fun _ _ => hmap]
246+
#align category_theory.functor.map_comp_heq' CategoryTheory.Functor.map_comp_heq'
247+
248+
theorem precomp_map_hEq (H : E ⥤ C) (hmap : ∀ {X Y} (f : X ⟶ Y), HEq (F.map f) (G.map f)) {X Y : E}
249+
(f : X ⟶ Y) : HEq ((H ⋙ F).map f) ((H ⋙ G).map f) :=
250+
hmap _
251+
#align category_theory.functor.precomp_map_heq CategoryTheory.Functor.precomp_map_hEq
252+
253+
theorem postcomp_map_hEq (H : D ⥤ E) (hx : F.obj X = G.obj X) (hy : F.obj Y = G.obj Y)
254+
(hmap : HEq (F.map f) (G.map f)) : HEq ((F ⋙ H).map f) ((G ⋙ H).map f) :=
255+
by
256+
dsimp
257+
congr
258+
#align category_theory.functor.postcomp_map_heq CategoryTheory.Functor.postcomp_map_hEq
259+
260+
theorem postcomp_map_heq' (H : D ⥤ E) (hobj : ∀ X : C, F.obj X = G.obj X)
261+
(hmap : ∀ {X Y} (f : X ⟶ Y), HEq (F.map f) (G.map f)) : HEq ((F ⋙ H).map f) ((G ⋙ H).map f) :=
262+
by rw [Functor.hext hobj fun _ _ => hmap]
263+
#align category_theory.functor.postcomp_map_heq' CategoryTheory.Functor.postcomp_map_heq'
264+
265+
theorem hcongr_hom {F G : C ⥤ D} (h : F = G) {X Y} (f : X ⟶ Y) : HEq (F.map f) (G.map f) := by
266+
rw [h]
267+
#align category_theory.functor.hcongr_hom CategoryTheory.Functor.hcongr_hom
268+
269+
end HEq
270+
271+
end Functor
272+
273+
/-- This is not always a good idea as a `@[simp]` lemma,
274+
as we lose the ability to use results that interact with `F`,
275+
e.g. the naturality of a natural transformation.
276+
277+
In some files it may be appropriate to use `local attribute [simp] eqToHom_map`, however.
278+
-/
279+
theorem eqToHom_map (F : C ⥤ D) {X Y : C} (p : X = Y) :
280+
F.map (eqToHom p) = eqToHom (congr_arg F.obj p) := by cases p; simp
281+
#align category_theory.eq_to_hom_map CategoryTheory.eqToHom_map
282+
283+
/-- See the note on `eqToHom_map` regarding using this as a `simp` lemma.
284+
-/
285+
theorem eqToIso_map (F : C ⥤ D) {X Y : C} (p : X = Y) :
286+
F.mapIso (eqToIso p) = eqToIso (congr_arg F.obj p) := by ext; cases p; simp
287+
#align category_theory.eq_to_iso_map CategoryTheory.eqToIso_map
288+
289+
@[simp]
290+
theorem eqToHom_app {F G : C ⥤ D} (h : F = G) (X : C) :
291+
(eqToHom h : F ⟶ G).app X = eqToHom (Functor.congr_obj h X) := by subst h; rfl
292+
#align category_theory.eq_to_hom_app CategoryTheory.eqToHom_app
293+
294+
theorem NatTrans.congr {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (h : X = Y) :
295+
α.app X = F.map (eqToHom h) ≫ α.app Y ≫ G.map (eqToHom h.symm) :=
296+
by
297+
rw [α.naturality_assoc]
298+
simp [eqToHom_map]
299+
#align category_theory.nat_trans.congr CategoryTheory.NatTrans.congr
300+
301+
theorem eq_conj_eqToHom {X Y : C} (f : X ⟶ Y) : f = eqToHom rfl ≫ f ≫ eqToHom rfl := by
302+
simp only [Category.id_comp, eqToHom_refl, Category.comp_id]
303+
#align category_theory.eq_conj_eq_to_hom CategoryTheory.eq_conj_eqToHom
304+
305+
theorem dcongr_arg {ι : Type _} {F G : ι → C} (α : ∀ i, F i ⟶ G i) {i j : ι} (h : i = j) :
306+
α i = eqToHom (congr_arg F h) ≫ α j ≫ eqToHom (congr_arg G h.symm) :=
307+
by
308+
subst h
309+
simp
310+
#align category_theory.dcongr_arg CategoryTheory.dcongr_arg
311+
312+
end CategoryTheory

0 commit comments

Comments
 (0)