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

Commit ff84bf4

Browse files
feat(category_theory/monad/limits): forgetful creates colimits (#2138)
* forgetful creates colimits * tidy up proofs * add docs * suggestions from review Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 4aed862 commit ff84bf4

File tree

1 file changed

+115
-1
lines changed

1 file changed

+115
-1
lines changed

src/category_theory/monad/limits.lean

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ variables (D : J ⥤ algebra T) [has_limit.{v₁} (D ⋙ forget T)]
6262
end forget_creates_limits
6363

6464
-- Theorem 5.6.5 from [Riehl][riehl2017]
65-
def forget_creates_limits (D : J ⥤ algebra T) [has_limit.{v₁} (D ⋙ forget T)] : has_limit D :=
65+
/-- The forgetful functor from the Eilenberg-Moore category creates limits. -/
66+
def forget_creates_limits (D : J ⥤ algebra T) [has_limit (D ⋙ forget T)] : has_limit D :=
6667
{ cone :=
6768
{ X := forget_creates_limits.cone_point D,
6869
π :=
@@ -82,6 +83,118 @@ def forget_creates_limits (D : J ⥤ algebra T) [has_limit.{v₁} (D ⋙ forget
8283
end },
8384
uniq' := λ s m w, by { ext1, ext1, simpa using congr_arg algebra.hom.f (w j) } } }
8485

86+
namespace forget_creates_colimits
87+
-- Let's hide the implementation details in a namespace
88+
variables (D : J ⥤ algebra T)
89+
-- We have a diagram D of shape J in the category of algebras, and we assume that its image
90+
-- D ⋙ forget T under the forgetful functor has a colimit (written L).
91+
92+
-- We'll construct a colimiting coalgebra for D, whose carrier will also be L.
93+
-- To do this, we must find a map TL ⟶ L. Since T preserves colimits, TL is also a colimit.
94+
-- In particular, it is a colimit for the diagram `(D ⋙ forget T) ⋙ T`
95+
-- so to construct a map TL ⟶ L it suffices to show that L is the apex of a cocone for this diagram.
96+
-- In other words, we need a natural transformation from const L to `(D ⋙ forget T) ⋙ T`.
97+
-- But we already know that L is the apex of a cocone for the diagram `D ⋙ forget T`, so it
98+
-- suffices to give a natural transformation `((D ⋙ forget T) ⋙ T) ⟶ (D ⋙ forget T)`:
99+
100+
/--
101+
The natural transformation given by the algebra structure maps, used to construct a cocone `c` with
102+
apex `colimit (D ⋙ forget T)`.
103+
-/
104+
@[simps] def γ : ((D ⋙ forget T) ⋙ T) ⟶ (D ⋙ forget T) := { app := λ j, (D.obj j).a }
105+
106+
variable [has_colimit.{v₁} (D ⋙ forget T)]
107+
/--
108+
A cocone for the diagram `(D ⋙ forget T) ⋙ T` found by composing the natural transformation `γ`
109+
with the colimiting cocone for `D ⋙ forget T`.
110+
-/
111+
@[simps]
112+
def c : cocone ((D ⋙ forget T) ⋙ T) :=
113+
{ X := colimit (D ⋙ forget T),
114+
ι := γ D ≫ (colimit.cocone (D ⋙ forget T)).ι }
115+
116+
variable [preserves_colimits_of_shape J T]
117+
118+
/--
119+
Define the map `λ : TL ⟶ L`, which will serve as the structure of the coalgebra on `L`, and
120+
we will show is the colimiting object. We use the cocone constructed by `c` and the fact that
121+
`T` preserves colimits to produce this morphism.
122+
-/
123+
@[reducible]
124+
def lambda : (functor.map_cocone T (colimit.cocone (D ⋙ forget T))).X ⟶ colimit (D ⋙ forget T) :=
125+
(preserves_colimit.preserves T (colimit.is_colimit (D ⋙ forget T))).desc (c D)
126+
127+
/-- The key property defining the map `λ : TL ⟶ L`. -/
128+
lemma commuting (j : J) :
129+
T.map (colimit.ι (D ⋙ forget T) j) ≫ lambda D = (D.obj j).a ≫ colimit.ι (D ⋙ forget T) j :=
130+
is_colimit.fac (preserves_colimit.preserves T (colimit.is_colimit (D ⋙ forget T))) (c D) j
131+
132+
/--
133+
Construct the colimiting algebra from the map `λ : TL ⟶ L` given by `lambda`. We are required to
134+
show it satisfies the two algebra laws, which follow from the algebra laws for the image of `D` and
135+
our `commuting` lemma.
136+
-/
137+
@[simps] def cocone_point :
138+
algebra T :=
139+
{ A := colimit (D ⋙ forget T),
140+
a := lambda D,
141+
unit' :=
142+
begin
143+
ext1,
144+
erw [comp_id, ← category.assoc, (η_ T).naturality, category.assoc, commuting, ← category.assoc],
145+
erw algebra.unit, apply id_comp
146+
end,
147+
assoc' :=
148+
begin
149+
apply is_colimit.hom_ext (preserves_colimit.preserves T (preserves_colimit.preserves T (colimit.is_colimit (D ⋙ forget T)))),
150+
intro j,
151+
erw [← category.assoc, nat_trans.naturality (μ_ T), ← functor.map_cocone_ι, category.assoc,
152+
is_colimit.fac _ (c D) j],
153+
rw ← category.assoc,
154+
erw [← functor.map_comp, commuting],
155+
dsimp,
156+
erw [← category.assoc, algebra.assoc, category.assoc, functor.map_comp, category.assoc, commuting]
157+
end
158+
}
159+
160+
end forget_creates_colimits
161+
162+
-- TODO: the converse of this is true as well
163+
-- TODO: generalise to monadic functors, as for creating limits
164+
/--
165+
The forgetful functor from the Eilenberg-Moore category for a monad creates any colimit
166+
which the monad itself preserves.
167+
168+
The colimiting algebra itself has been constructed in `cocone_point`. We now must show it
169+
actually forms a cocone, and that this is colimiting.
170+
-/
171+
def forget_creates_colimits_of_monad_preserves
172+
[preserves_colimits_of_shape J T] (D : J ⥤ algebra T) [has_colimit (D ⋙ forget T)] :
173+
has_colimit D :=
174+
{ cocone :=
175+
{ X := forget_creates_colimits.cocone_point D,
176+
ι :=
177+
{ app := λ j, { f := colimit.ι (D ⋙ forget T) j,
178+
h' := forget_creates_colimits.commuting _ _ },
179+
naturality' := λ A B f, by { ext1, dsimp, erw [comp_id, colimit.w (D ⋙ forget T)] } } },
180+
is_colimit :=
181+
{ desc := λ s,
182+
{ f := colimit.desc _ ((forget T).map_cocone s),
183+
h' :=
184+
begin
185+
dsimp,
186+
apply is_colimit.hom_ext (preserves_colimit.preserves T (colimit.is_colimit (D ⋙ forget T))),
187+
intro j,
188+
rw ← category.assoc, erw ← functor.map_comp,
189+
erw colimit.ι_desc,
190+
rw ← category.assoc, erw forget_creates_colimits.commuting,
191+
rw category.assoc, rw colimit.ι_desc,
192+
apply algebra.hom.h
193+
end },
194+
uniq' := λ s m J, by { ext1, ext1, simpa using congr_arg algebra.hom.f (J j) }
195+
}
196+
}
197+
85198
end monad
86199

87200
variables {C : Type u₁} [𝒞 : category.{v₁} C] {D : Type u₁} [𝒟 : category.{v₁} D]
@@ -100,6 +213,7 @@ instance comp_comparison_has_limit
100213
has_limit (F ⋙ monad.comparison R) :=
101214
monad.forget_creates_limits (F ⋙ monad.comparison R)
102215

216+
/-- Any monadic functor creates limits. -/
103217
def monadic_creates_limits (F : J ⥤ D) (R : D ⥤ C) [monadic_right_adjoint R] [has_limit.{v₁} (F ⋙ R)] :
104218
has_limit F :=
105219
adjunction.has_limit_of_comp_equivalence _ (monad.comparison R)

0 commit comments

Comments
 (0)