Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 05550ea

Browse files
kim-emmergify[bot]
authored andcommitted
feat(category_theory/limits): equivalences create limits (#1175)
* feat(category_theory/limits): equivalences create limits * equivalence lemma * add @[simp] * use right_adjoint_preserves_limits * undo weird changes in topology files * formatting * do colimits too
1 parent 27ae77c commit 05550ea

File tree

5 files changed

+95
-10
lines changed

5 files changed

+95
-10
lines changed

src/category_theory/adjunction/basic.lean

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ mk_of_hom_equiv
281281

282282
end construct_right
283283

284+
end adjunction
285+
286+
open adjunction
287+
284288
namespace equivalence
285289

286290
def to_adjunction (e : C ≌ D) : e.functor ⊣ e.inverse :=
@@ -289,6 +293,11 @@ mk_of_unit_counit ⟨e.unit, e.counit, by { ext, exact e.functor_unit_comp X },
289293

290294
end equivalence
291295

292-
end adjunction
296+
namespace functor
297+
298+
def adjunction (E : C ⥤ D) [is_equivalence E] : E ⊣ E.inv :=
299+
(E.as_equivalence).to_adjunction
300+
301+
end functor
293302

294303
end category_theory

src/category_theory/adjunction/limits.lean

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,38 @@ def functoriality_is_left_adjoint :
3333
counit := { app := λ c, { hom := adj.counit.app c.X } } } }
3434

3535
/-- A left adjoint preserves colimits. -/
36-
def left_adjoint_preserves_colimits : preserves_colimits F :=
36+
instance left_adjoint_preserves_colimits : preserves_colimits F :=
3737
{ preserves_colimits_of_shape := λ J 𝒥,
3838
{ preserves_colimit := λ F,
3939
by resetI; exact
4040
{ preserves := λ c hc, is_colimit_iso_unique_cocone_morphism.inv
4141
(λ s, (((adj.functoriality_is_left_adjoint _).adj).hom_equiv _ _).unique_of_equiv $
42-
is_colimit_iso_unique_cocone_morphism.hom hc _ ) } } }
42+
is_colimit_iso_unique_cocone_morphism.hom hc _ ) } } }.
43+
44+
omit adj
45+
46+
-- TODO the implicit arguments make preserves_colimit* quite hard to use.
47+
-- This should be refactored at some point. (Possibly including making `is_colimit` a class.)
48+
def is_colimit_map_cocone (E : C ⥤ D) [is_equivalence E]
49+
(c : cocone K) (h : is_colimit c) : is_colimit (E.map_cocone c) :=
50+
begin
51+
have P : preserves_colimits E := adjunction.left_adjoint_preserves_colimits E.adjunction,
52+
have P' := P.preserves_colimits_of_shape,
53+
have P'' := P'.preserves_colimit,
54+
have P''' := P''.preserves,
55+
exact P''' h,
56+
end
57+
58+
instance has_colimit_comp_equivalence (E : C ⥤ D) [is_equivalence E] [has_colimit K] :
59+
has_colimit (K ⋙ E) :=
60+
{ cocone := E.map_cocone (colimit.cocone K),
61+
is_colimit := is_colimit_map_cocone _ _ _ (colimit.is_colimit K) }
62+
63+
def has_colimit_of_comp_equivalence (E : C ⥤ D) [is_equivalence E] [has_colimit (K ⋙ E)] :
64+
has_colimit K :=
65+
@has_colimit_of_iso _ _ _ _ (K ⋙ E ⋙ inv E) K
66+
(@adjunction.has_colimit_comp_equivalence _ _ _ _ _ _ (K ⋙ E) (inv E) _ _)
67+
((functor.right_unitor _).symm ≪≫ (iso_whisker_left K (fun_inv_id E)).symm)
4368

4469
end preservation_colimits
4570

@@ -55,13 +80,38 @@ def functoriality_is_right_adjoint :
5580
counit := { app := λ c, { hom := adj.counit.app c.X, } } } }
5681

5782
/-- A right adjoint preserves limits. -/
58-
def right_adjoint_preserves_limits : preserves_limits G :=
83+
instance right_adjoint_preserves_limits : preserves_limits G :=
5984
{ preserves_limits_of_shape := λ J 𝒥,
6085
{ preserves_limit := λ K,
6186
by resetI; exact
6287
{ preserves := λ c hc, is_limit_iso_unique_cone_morphism.inv
6388
(λ s, (((adj.functoriality_is_right_adjoint _).adj).hom_equiv _ _).symm.unique_of_equiv $
64-
is_limit_iso_unique_cone_morphism.hom hc _) } } }
89+
is_limit_iso_unique_cone_morphism.hom hc _) } } }.
90+
91+
omit adj
92+
93+
-- TODO the implicit arguments make preserves_limit* quite hard to use.
94+
-- This should be refactored at some point. (Possibly including making `is_limit` a class.)
95+
def is_limit_map_cone (E : D ⥤ C) [is_equivalence E]
96+
(c : cone K) (h : is_limit c) : is_limit (E.map_cone c) :=
97+
begin
98+
have P : preserves_limits E := adjunction.right_adjoint_preserves_limits E.inv.adjunction,
99+
have P' := P.preserves_limits_of_shape,
100+
have P'' := P'.preserves_limit,
101+
have P''' := P''.preserves,
102+
exact P''' h,
103+
end
104+
105+
instance has_limit_comp_equivalence (E : D ⥤ C) [is_equivalence E] [has_limit K] :
106+
has_limit (K ⋙ E) :=
107+
{ cone := E.map_cone (limit.cone K),
108+
is_limit := is_limit_map_cone _ _ _ (limit.is_limit K) }
109+
110+
def has_limit_of_comp_equivalence (E : D ⥤ C) [is_equivalence E] [has_limit (K ⋙ E)] :
111+
has_limit K :=
112+
@has_limit_of_iso _ _ _ _ (K ⋙ E ⋙ inv E) K
113+
(@adjunction.has_limit_comp_equivalence _ _ _ _ _ _ (K ⋙ E) (inv E) _ _)
114+
((iso_whisker_left K (fun_inv_id E)) ≪≫ (functor.right_unitor _))
65115

66116
end preservation_limits
67117

src/category_theory/equivalence.lean

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ lemma counit_def (e : C ≌ D) : e.counit_iso.hom = e.counit := rfl
4848
lemma unit_inv_def (e : C ≌ D) : e.unit_iso.inv = e.unit_inv := rfl
4949
lemma counit_inv_def (e : C ≌ D) : e.counit_iso.inv = e.counit_inv := rfl
5050

51-
lemma functor_unit_comp (e : C ≌ D) (X : C) : e.functor.map (e.unit.app X) ≫
51+
@[simp] lemma functor_unit_comp (e : C ≌ D) (X : C) : e.functor.map (e.unit.app X) ≫
5252
e.counit.app (e.functor.obj X) = 𝟙 (e.functor.obj X) :=
5353
e.functor_unit_iso_comp X
5454

55-
lemma counit_inv_functor_comp (e : C ≌ D) (X : C) :
55+
@[simp] lemma counit_inv_functor_comp (e : C ≌ D) (X : C) :
5656
e.counit_inv.app (e.functor.obj X) ≫ e.functor.map (e.unit_inv.app X) = 𝟙 (e.functor.obj X) :=
5757
begin
5858
erw [iso.inv_eq_inv
@@ -70,7 +70,7 @@ by { erw [←iso.hom_comp_eq_id (e.functor.map_iso (e.unit_iso.app X)), functor_
7070

7171
/-- The other triangle equality. The proof follows the following proof in Globular:
7272
http://globular.science/1905.001 -/
73-
lemma unit_inverse_comp (e : C ≌ D) (Y : D) :
73+
@[simp] lemma unit_inverse_comp (e : C ≌ D) (Y : D) :
7474
e.unit.app (e.inverse.obj Y) ≫ e.inverse.map (e.counit.app Y) = 𝟙 (e.inverse.obj Y) :=
7575
begin
7676
rw [←id_comp _ (e.inverse.map _), ←map_id e.inverse, ←counit_inv_functor_comp, map_comp,
@@ -91,7 +91,7 @@ begin
9191
(e.counit_iso.app _).hom_inv_id, map_id] }, erw [id_comp, (e.unit_iso.app _).hom_inv_id], refl
9292
end
9393

94-
lemma inverse_counit_inv_comp (e : C ≌ D) (Y : D) :
94+
@[simp] lemma inverse_counit_inv_comp (e : C ≌ D) (Y : D) :
9595
e.inverse.map (e.counit_inv.app Y) ≫ e.unit_inv.app (e.inverse.obj Y) = 𝟙 (e.inverse.obj Y) :=
9696
begin
9797
erw [iso.inv_eq_inv
@@ -196,7 +196,7 @@ mk' ::
196196
(inverse : D ⥤ C)
197197
(unit_iso : 𝟭 C ≅ F ⋙ inverse)
198198
(counit_iso : inverse ⋙ F ≅ 𝟭 D)
199-
(functor_unit_iso_comp' : ∀(X : C), F.map ((unit_iso.hom : 𝟭 C ⟶ F ⋙ inverse).app X) ≫
199+
(functor_unit_iso_comp' : ∀ (X : C), F.map ((unit_iso.hom : 𝟭 C ⟶ F ⋙ inverse).app X) ≫
200200
counit_iso.hom.app (F.obj X) = 𝟙 (F.obj X) . obviously)
201201

202202
restate_axiom is_equivalence.functor_unit_iso_comp'
@@ -264,6 +264,16 @@ begin
264264
refl
265265
end
266266

267+
-- We should probably restate many of the lemmas about `equivalence` for `is_equivalence`,
268+
-- but these are the only ones I need for now.
269+
@[simp] lemma functor_unit_comp (E : C ⥤ D) [is_equivalence E] (Y) :
270+
E.map (((is_equivalence.unit_iso E).hom).app Y) ≫ ((is_equivalence.counit_iso E).hom).app (E.obj Y) = 𝟙 _ :=
271+
equivalence.functor_unit_comp (E.as_equivalence) Y
272+
273+
@[simp] lemma counit_inv_functor_comp (E : C ⥤ D) [is_equivalence E] (Y) :
274+
((is_equivalence.counit_iso E).inv).app (E.obj Y) ≫ E.map (((is_equivalence.unit_iso E).inv).app Y) = 𝟙 _ :=
275+
eq_of_inv_eq_inv (functor_unit_comp _ _)
276+
267277
end is_equivalence
268278

269279
class ess_surj (F : C ⥤ D) :=

src/category_theory/limits/cones.lean

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,19 @@ def map_cone (c : cone F) : cone (F ⋙ H) := (cones.functoriality H).obj
361361
/-- The image of a cocone in C under a functor G : C ⥤ D is a cocone in D. -/
362362
def map_cocone (c : cocone F) : cocone (F ⋙ H) := (cocones.functoriality H).obj c
363363

364+
@[simp] lemma map_cone_X (c : cone F) : (H.map_cone c).X = H.obj c.X := rfl
365+
@[simp] lemma map_cocone_X (c : cocone F) : (H.map_cocone c).X = H.obj c.X := rfl
366+
367+
def map_cone_inv [is_equivalence H]
368+
(c : cone (F ⋙ H)) : cone F :=
369+
let t := (inv H).map_cone c in
370+
let α : (F ⋙ H) ⋙ inv H ⟶ F :=
371+
((whisker_left F (is_equivalence.unit_iso H).inv) : F ⋙ (H ⋙ inv H) ⟶ _) ≫ (functor.right_unitor _).hom in
372+
{ X := t.X,
373+
π := ((category_theory.cones J C).map α).app (op t.X) t.π }
374+
375+
@[simp] lemma map_cone_inv_X [is_equivalence H] (c : cone (F ⋙ H)) : (H.map_cone_inv c).X = (inv H).obj c.X := rfl
376+
364377
def map_cone_morphism {c c' : cone F} (f : cone_morphism c c') :
365378
cone_morphism (H.map_cone c) (H.map_cone c') := (cones.functoriality H).map f
366379
def map_cocone_morphism {c c' : cocone F} (f : cocone_morphism c c') :

src/category_theory/limits/limits.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,9 @@ begin
418418
apply has_limit_of_iso (e.inv_fun_id_assoc F),
419419
end
420420

421+
-- `has_limit_comp_equivalence` and `has_limit_of_comp_equivalence`
422+
-- are proved in `category_theory/adjunction/limits.lean`.
423+
421424
section lim_functor
422425

423426
variables [has_limits_of_shape J C]

0 commit comments

Comments
 (0)