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

Commit cd0d8c0

Browse files
committed
chore(category_theory/limits/over): generalise, golf and document over limits (#5674)
- Show that the forgetful functor `over X => C` creates colimits, generalising what was already there - Golf the proofs using this new instance - Add module doc and duals of the above
1 parent 9f9f85e commit cd0d8c0

File tree

1 file changed

+58
-100
lines changed

1 file changed

+58
-100
lines changed

src/category_theory/limits/over.lean

Lines changed: 58 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,20 @@ Authors: Johan Commelin, Reid Barton, Bhavik Mehta
55
-/
66
import category_theory.over
77
import category_theory.limits.preserves.basic
8+
import category_theory.limits.creates
89

10+
/-!
11+
# Limits and colimits in the over and under categories
12+
13+
Show that the forgetful functor `forget X : over X ⥤ C` creates colimits, and hence `over X` has
14+
any colimits that `C` has (as well as the dual that `forget X : under X ⟶ C` creates limits).
15+
16+
Note that the folder `category_theory.limits.shapes.constructions.over` further shows that
17+
`forget X : over X ⥤ C` creates connected limits (so `over X` has connected limits), and that
18+
`over X` has `J`-indexed products if `C` has `J`-indexed wide pullbacks.
19+
20+
TODO: If `C` has binary products, then `forget X : over X ⥤ C` has a right adjoint.
21+
-/
922
noncomputable theory
1023

1124
universes v u -- declare the `v`'s first; see `category_theory.category` for an explanation
@@ -36,120 +49,69 @@ end category_theory.functor
3649

3750
namespace category_theory.over
3851

39-
/-- A colimit of `F ⋙ over.forget` induces a cocone over `F`. This is an implementation detail,
40-
use the `has_colimit` instance provided below. -/
41-
@[simps] def colimit (F : J ⥤ over X) [has_colimit (F ⋙ forget X)] : cocone F :=
42-
{ X := mk $ colimit.desc (F ⋙ forget X) F.to_cocone,
43-
ι :=
44-
{ app := λ j, hom_mk $ colimit.ι (F ⋙ forget X) j,
45-
naturality' :=
46-
begin
47-
intros j j' f,
48-
have := colimit.w (F ⋙ forget X) f,
49-
tidy
50-
end } }
51-
52-
/-- The cocone constructed from the colimit of `F ⋙ forget X` is a colimit. This is an
53-
implementation detail, use the `has_colimit` instance provided below. -/
54-
def forget_colimit_is_colimit (F : J ⥤ over X) [has_colimit (F ⋙ forget X)] :
55-
is_colimit ((forget X).map_cocone (colimit F)) :=
56-
is_colimit.of_iso_colimit (colimit.is_colimit (F ⋙ forget X)) (cocones.ext (iso.refl _) (by tidy))
57-
5852
instance : reflects_colimits (forget X) :=
59-
{ reflects_colimits_of_shape := λ J 𝒥,
53+
{ reflects_colimits_of_shape := λ J 𝒥,
6054
{ reflects_colimit := λ F,
61-
by constructor; exactI λ t ht,
62-
{ desc := λ s, hom_mk (ht.desc ((forget X).map_cocone s))
63-
begin
64-
apply ht.hom_ext, intro j,
65-
rw [←category.assoc, ht.fac],
66-
transitivity (F.obj j).hom,
67-
exact w (s.ι.app j), -- TODO: How to write (s.ι.app j).w?
68-
exact (w (t.ι.app j)).symm,
69-
end,
70-
fac' := begin
71-
intros s j, ext, exact ht.fac ((forget X).map_cocone s) j
72-
-- TODO: Ask Simon about multiple ext lemmas for defeq types (comma_morphism & over.category.hom)
73-
end,
74-
uniq' :=
75-
begin
76-
intros s m w,
77-
ext1 j,
78-
exact ht.uniq ((forget X).map_cocone s) m.left (λ j, congr_arg comma_morphism.left (w j))
79-
end } } }
55+
{ reflects := λ c t, by exactI
56+
{ desc := λ s, hom_mk (t.desc ((forget X).map_cocone s)) $ t.hom_ext $
57+
λ j, by { rw t.fac_assoc, exact ((s.ι.app j).w).trans (c.ι.app j).w.symm },
58+
fac' := λ s j, over_morphism.ext (t.fac _ j),
59+
uniq' :=
60+
λ s m w, over_morphism.ext $
61+
t.uniq ((forget X).map_cocone s) m.left (λ j, congr_arg comma_morphism.left (w j)) } } } }
62+
63+
instance : creates_colimits (forget X) :=
64+
{ creates_colimits_of_shape := λ J 𝒥₁, by exactI
65+
{ creates_colimit := λ K,
66+
{ lifts := λ c t,
67+
{ lifted_cocone :=
68+
{ X := mk (t.desc K.to_cocone),
69+
ι :=
70+
{ app := λ j, hom_mk (c.ι.app j),
71+
naturality' := λ j j' f, over_morphism.ext (c.ι.naturality f) } },
72+
valid_lift := cocones.ext (iso.refl _) (λ j, category.comp_id _) } } } }
8073

8174
instance has_colimit {F : J ⥤ over X} [has_colimit (F ⋙ forget X)] : has_colimit F :=
82-
has_colimit.mk { cocone := colimit F,
83-
is_colimit := reflects_colimit.reflects (forget_colimit_is_colimit F) }
75+
has_colimit_of_created _ (forget X)
8476

8577
instance has_colimits_of_shape [has_colimits_of_shape J C] :
8678
has_colimits_of_shape J (over X) :=
8779
{ has_colimit := λ F, by apply_instance }
8880

8981
instance has_colimits [has_colimits C] : has_colimits (over X) :=
90-
{ has_colimits_of_shape := λ J 𝒥, by resetI; apply_instance }
91-
92-
instance forget_preserves_colimit {X : C} {F : J ⥤ over X} [has_colimit (F ⋙ forget X)] :
93-
preserves_colimit F (forget X) :=
94-
preserves_colimit_of_preserves_colimit_cocone
95-
(reflects_colimit.reflects (forget_colimit_is_colimit F)) (forget_colimit_is_colimit F)
82+
{ has_colimits_of_shape := λ J 𝒥, by apply_instance }
9683

97-
instance forget_preserves_colimits_of_shape [has_colimits_of_shape J C] {X : C} :
98-
preserves_colimits_of_shape J (forget X) :=
99-
{ preserves_colimit := λ F, by apply_instance }
100-
101-
instance forget_preserves_colimits [has_colimits C] {X : C} :
102-
preserves_colimits (forget X) :=
103-
{ preserves_colimits_of_shape := λ J 𝒥, by apply_instance }
84+
-- We can automatically infer that the forgetful functor preserves colimits
85+
example [has_colimits C] : preserves_colimits (forget X) := infer_instance
10486

10587
end category_theory.over
10688

10789
namespace category_theory.under
10890

109-
/-- A limit of `F ⋙ under.forget` induces a cone over `F`. This is an implementation detail,
110-
use the `has_limit` instance provided below. -/
111-
@[simps] def limit (F : J ⥤ under X) [has_limit (F ⋙ forget X)] : cone F :=
112-
{ X := mk $ limit.lift (F ⋙ forget X) F.to_cone,
113-
π :=
114-
{ app := λ j, hom_mk $ limit.π (F ⋙ forget X) j,
115-
naturality' :=
116-
begin
117-
intros j j' f,
118-
have := (limit.w (F ⋙ forget X) f).symm,
119-
tidy
120-
end } }
121-
122-
/-- The cone constructed from the limit of `F ⋙ forget X` is a limit. This is an
123-
implementation detail, use the `has_limit` instance provided below. -/
124-
def forget_limit_is_limit (F : J ⥤ under X) [has_limit (F ⋙ forget X)] :
125-
is_limit ((forget X).map_cone (limit F)) :=
126-
is_limit.of_iso_limit (limit.is_limit (F ⋙ forget X)) (cones.ext (iso.refl _) (by tidy))
127-
12891
instance : reflects_limits (forget X) :=
129-
{ reflects_limits_of_shape := λ J 𝒥,
92+
{ reflects_limits_of_shape := λ J 𝒥,
13093
{ reflects_limit := λ F,
131-
by constructor; exactI λ t ht,
132-
{ lift := λ s, hom_mk (ht.lift ((forget X).map_cone s))
133-
begin
134-
apply ht.hom_ext, intro j,
135-
rw [category.assoc, ht.fac],
136-
transitivity (F.obj j).hom,
137-
exact w (s.π.app j),
138-
exact (w (t.π.app j)).symm,
139-
end,
140-
fac' := begin
141-
intros s j, ext, exact ht.fac ((forget X).map_cone s) j
142-
end,
143-
uniq' :=
144-
begin
145-
intros s m w,
146-
ext1 j,
147-
exact ht.uniq ((forget X).map_cone s) m.right (λ j, congr_arg comma_morphism.right (w j))
148-
end } } }
94+
{ reflects := λ c t, by exactI
95+
{ lift := λ s, hom_mk (t.lift ((forget X).map_cone s)) $ t.hom_ext $ λ j,
96+
by { rw [category.assoc, t.fac], exact (s.π.app j).w.symm.trans (c.π.app j).w },
97+
fac' := λ s j, under_morphism.ext (t.fac _ j),
98+
uniq' :=
99+
λ s m w, under_morphism.ext $
100+
t.uniq ((forget X).map_cone s) m.right (λ j, congr_arg comma_morphism.right (w j)) } } } }
101+
102+
instance : creates_limits (forget X) :=
103+
{ creates_limits_of_shape := λ J 𝒥₁, by exactI
104+
{ creates_limit := λ K,
105+
{ lifts := λ c t,
106+
{ lifted_cone :=
107+
{ X := mk (t.lift K.to_cone),
108+
π :=
109+
{ app := λ j, hom_mk (c.π.app j),
110+
naturality' := λ j j' f, under_morphism.ext (c.π.naturality f) } },
111+
valid_lift := cones.ext (iso.refl _) (λ j, (category.id_comp _).symm) } } } }
149112

150113
instance has_limit {F : J ⥤ under X} [has_limit (F ⋙ forget X)] : has_limit F :=
151-
has_limit.mk { cone := limit F,
152-
is_limit := reflects_limit.reflects (forget_limit_is_limit F) }
114+
has_limit_of_created F (forget X)
153115

154116
instance has_limits_of_shape [has_limits_of_shape J C] :
155117
has_limits_of_shape J (under X) :=
@@ -158,11 +120,7 @@ instance has_limits_of_shape [has_limits_of_shape J C] :
158120
instance has_limits [has_limits C] : has_limits (under X) :=
159121
{ has_limits_of_shape := λ J 𝒥, by resetI; apply_instance }
160122

161-
instance forget_preserves_limits [has_limits C] {X : C} :
162-
preserves_limits (forget X) :=
163-
{ preserves_limits_of_shape := λ J 𝒥,
164-
{ preserves_limit := λ F, by exactI
165-
preserves_limit_of_preserves_limit_cone
166-
(reflects_limit.reflects (forget_limit_is_limit F)) (forget_limit_is_limit F) } }
123+
-- We can automatically infer that the forgetful functor preserves limits
124+
example [has_limits C] : preserves_limits (forget X) := infer_instance
167125

168126
end category_theory.under

0 commit comments

Comments
 (0)