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

Commit ff66d92

Browse files
committed
chore(category_theory/limits): facts about opposites of limit cones (#4250)
Simple facts about limit cones and opposite categories. Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent da66bb8 commit ff66d92

File tree

6 files changed

+317
-33
lines changed

6 files changed

+317
-33
lines changed

src/category_theory/adjunction/opposites.lean

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,12 @@ nat_iso.of_components
8080
/-- If `F` and `F'` are both left adjoint to `G`, then they are naturally isomorphic. -/
8181
def left_adjoint_uniq {F F' : C ⥤ D} {G : D ⥤ C}
8282
(adj1 : F ⊣ G) (adj2 : F' ⊣ G) : F ≅ F' :=
83-
nat_iso.unop (fully_faithful_cancel_right _ (left_adjoints_coyoneda_equiv adj2 adj1))
83+
nat_iso.remove_op (fully_faithful_cancel_right _ (left_adjoints_coyoneda_equiv adj2 adj1))
8484

8585
/-- If `G` and `G'` are both right adjoint to `F`, then they are naturally isomorphic. -/
8686
def right_adjoint_uniq {F : C ⥤ D} {G G' : D ⥤ C}
8787
(adj1 : F ⊣ G) (adj2 : F ⊣ G') : G ≅ G' :=
88-
nat_iso.unop (left_adjoint_uniq (op_adjoint_op_of_adjoint _ F adj2) (op_adjoint_op_of_adjoint _ _ adj1))
88+
nat_iso.remove_op
89+
(left_adjoint_uniq (op_adjoint_op_of_adjoint _ F adj2) (op_adjoint_op_of_adjoint _ _ adj1))
8990

9091
end adjunction

src/category_theory/limits/cones.lean

Lines changed: 104 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,7 @@ begin
512512
dsimp,
513513
rw [comp_id, H.map_comp, is_equivalence.fun_inv_map H, assoc, nat_iso.cancel_nat_iso_hom_left,
514514
assoc, is_equivalence.inv_fun_id_inv_comp],
515-
apply comp_id,
516-
-- annoyingly `dsimp, simp` leaves it as `c.π.app j ≫ 𝟙 _ = c.π.app j` instead of closing...
515+
dsimp, simp,
517516
end
518517

519518
/-- `map_cone` is the right inverse to `map_cone_inv`. -/
@@ -527,14 +526,88 @@ end category_theory
527526

528527
namespace category_theory.limits
529528

529+
section
530+
variables {F : J ⥤ C}
531+
532+
/-- Change a `cocone F` into a `cone F.op`. -/
533+
@[simps] def cocone.op (c : cocone F) : cone F.op :=
534+
{ X := op c.X,
535+
π :=
536+
{ app := λ j, (c.ι.app (unop j)).op,
537+
naturality' := λ j j' f, has_hom.hom.unop_inj (by tidy) } }
538+
539+
/-- Change a `cone F` into a `cocone F.op`. -/
540+
@[simps] def cone.op (c : cone F) : cocone F.op :=
541+
{ X := op c.X,
542+
ι :=
543+
{ app := λ j, (c.π.app (unop j)).op,
544+
naturality' := λ j j' f, has_hom.hom.unop_inj (by tidy) } }
545+
546+
/-- Change a `cocone F.op` into a `cone F`. -/
547+
@[simps] def cocone.unop (c : cocone F.op) : cone F :=
548+
{ X := unop c.X,
549+
π :=
550+
{ app := λ j, (c.ι.app (op j)).unop,
551+
naturality' := λ j j' f, has_hom.hom.op_inj
552+
begin dsimp, simp only [comp_id], exact (c.w f.op).symm, end } }
553+
554+
/-- Change a `cone F.op` into a `cocone F`. -/
555+
@[simps] def cone.unop (c : cone F.op) : cocone F :=
556+
{ X := unop c.X,
557+
ι :=
558+
{ app := λ j, (c.π.app (op j)).unop,
559+
naturality' := λ j j' f, has_hom.hom.op_inj
560+
begin dsimp, simp only [id_comp], exact (c.w f.op), end } }
561+
562+
variables (F)
563+
564+
/--
565+
The category of cocones on `F`
566+
is equivalent to the opposite category of
567+
the category of cones on the opposite of `F`.
568+
-/
569+
@[simps]
570+
def cocone_equivalence_op_cone_op : cocone F ≌ (cone F.op)ᵒᵖ :=
571+
{ functor :=
572+
{ obj := λ c, op (cocone.op c),
573+
map := λ X Y f, has_hom.hom.op
574+
{ hom := f.hom.op,
575+
w' := λ j, by { apply has_hom.hom.unop_inj, dsimp, simp, }, } },
576+
inverse :=
577+
{ obj := λ c, cone.unop (unop c),
578+
map := λ X Y f,
579+
{ hom := f.unop.hom.unop,
580+
w' := λ j, by { apply has_hom.hom.op_inj, dsimp, simp, }, } },
581+
unit_iso := nat_iso.of_components (λ c, cocones.ext (iso.refl _) (by tidy)) (by tidy),
582+
counit_iso := nat_iso.of_components (λ c,
583+
by { op_induction c, dsimp, apply iso.op, exact cones.ext (iso.refl _) (by tidy), })
584+
begin
585+
intros,
586+
have hX : X = op (unop X) := rfl,
587+
revert hX,
588+
generalize : unop X = X',
589+
rintro rfl,
590+
have hY : Y = op (unop Y) := rfl,
591+
revert hY,
592+
generalize : unop Y = Y',
593+
rintro rfl,
594+
apply has_hom.hom.unop_inj,
595+
apply cone_morphism.ext,
596+
dsimp, simp,
597+
end,
598+
functor_unit_iso_comp' := λ c, begin apply has_hom.hom.unop_inj, ext, dsimp, simp, end }
599+
600+
end
601+
602+
section
530603
variables {F : J ⥤ Cᵒᵖ}
531604

532-
-- Here and below we only automatically generate the `@[simp]` lemma for the `X` field,
533-
-- as we can be a simpler `rfl` lemma for the components of the natural transformation by hand.
534605
/-- Change a cocone on `F.left_op : Jᵒᵖ ⥤ C` to a cocone on `F : J ⥤ Cᵒᵖ`. -/
606+
-- Here and below we only automatically generate the `@[simp]` lemma for the `X` field,
607+
-- as we can write a simpler `rfl` lemma for the components of the natural transformation by hand.
535608
@[simps X] def cone_of_cocone_left_op (c : cocone F.left_op) : cone F :=
536609
{ X := op c.X,
537-
π := nat_trans.right_op (c.ι ≫ (const.op_obj_unop (op c.X)).hom) }
610+
π := nat_trans.remove_left_op (c.ι ≫ (const.op_obj_unop (op c.X)).hom) }
538611

539612
@[simp] lemma cone_of_cocone_left_op_π_app (c : cocone F.left_op) (j) :
540613
(cone_of_cocone_left_op c).π.app j = (c.ι.app (op j)).op :=
@@ -552,7 +625,7 @@ by { dsimp [cocone_left_op_of_cone], simp }
552625
/-- Change a cone on `F.left_op : Jᵒᵖ ⥤ C` to a cocone on `F : J ⥤ Cᵒᵖ`. -/
553626
@[simps X] def cocone_of_cone_left_op (c : cone F.left_op) : cocone F :=
554627
{ X := op c.X,
555-
ι := nat_trans.right_op ((const.op_obj_unop (op c.X)).hom ≫ c.π) }
628+
ι := nat_trans.remove_left_op ((const.op_obj_unop (op c.X)).hom ≫ c.π) }
556629

557630
@[simp] lemma cocone_of_cone_left_op_ι_app (c : cone F.left_op) (j) :
558631
(cocone_of_cone_left_op c).ι.app j = (c.π.app (op j)).op :=
@@ -566,4 +639,29 @@ by { dsimp [cocone_of_cone_left_op], simp }
566639
@[simp] lemma cone_left_op_of_cocone_π_app (c : cocone F) (j) :
567640
(cone_left_op_of_cocone c).π.app j = (c.ι.app (unop j)).unop :=
568641
by { dsimp [cone_left_op_of_cocone], simp }
642+
643+
end
644+
569645
end category_theory.limits
646+
647+
namespace category_theory.functor
648+
649+
open category_theory.limits
650+
651+
variables {F : J ⥤ C}
652+
variables {D : Type u'} [category.{v} D]
653+
654+
section
655+
variables (G : C ⥤ D)
656+
657+
/-- The opposite cocone of the image of a cone is the image of the opposite cocone. -/
658+
def map_cone_op (t : cone F) : (G.map_cone t).op ≅ (G.op.map_cocone t.op) :=
659+
cocones.ext (iso.refl _) (by tidy)
660+
661+
/-- The opposite cone of the image of a cocone is the image of the opposite cone. -/
662+
def map_cocone_op {t : cocone F} : (G.map_cocone t).op ≅ (G.op.map_cone t.op) :=
663+
cones.ext (iso.refl _) (by tidy)
664+
665+
end
666+
667+
end category_theory.functor

src/category_theory/limits/limits.lean

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,4 +1706,74 @@ by { constructor, intro F, apply has_colimit_of_equivalence_comp e, apply_instan
17061706

17071707
end colimit
17081708

1709+
section opposite
1710+
1711+
/--
1712+
If `t : cone F` is a limit cone, then `t.op : cocone F.op` is a colimit cocone.
1713+
-/
1714+
def is_limit.op {t : cone F} (P : is_limit t) : is_colimit t.op :=
1715+
{ desc := λ s, (P.lift s.unop).op,
1716+
fac' := λ s j, congr_arg has_hom.hom.op (P.fac s.unop (unop j)),
1717+
uniq' := λ s m w,
1718+
begin
1719+
rw ← P.uniq s.unop m.unop,
1720+
{ refl, },
1721+
{ dsimp, intro j, rw ← w, refl, }
1722+
end }
1723+
1724+
/--
1725+
If `t : cocone F` is a colimit cocone, then `t.op : cone F.op` is a limit cone.
1726+
-/
1727+
def is_colimit.op {t : cocone F} (P : is_colimit t) : is_limit t.op :=
1728+
{ lift := λ s, (P.desc s.unop).op,
1729+
fac' := λ s j, congr_arg has_hom.hom.op (P.fac s.unop (unop j)),
1730+
uniq' := λ s m w,
1731+
begin
1732+
rw ← P.uniq s.unop m.unop,
1733+
{ refl, },
1734+
{ dsimp, intro j, rw ← w, refl, }
1735+
end }
1736+
1737+
/--
1738+
If `t : cone F.op` is a limit cone, then `t.unop : cocone F` is a colimit cocone.
1739+
-/
1740+
def is_limit.unop {t : cone F.op} (P : is_limit t) : is_colimit t.unop :=
1741+
{ desc := λ s, (P.lift s.op).unop,
1742+
fac' := λ s j, congr_arg has_hom.hom.unop (P.fac s.op (op j)),
1743+
uniq' := λ s m w,
1744+
begin
1745+
rw ← P.uniq s.op m.op,
1746+
{ refl, },
1747+
{ dsimp, intro j, rw ← w, refl, }
1748+
end }
1749+
1750+
/--
1751+
If `t : cocone F.op` is a colimit cocone, then `t.unop : cone F.` is a limit cone.
1752+
-/
1753+
def is_colimit.unop {t : cocone F.op} (P : is_colimit t) : is_limit t.unop :=
1754+
{ lift := λ s, (P.desc s.op).unop,
1755+
fac' := λ s j, congr_arg has_hom.hom.unop (P.fac s.op (op j)),
1756+
uniq' := λ s m w,
1757+
begin
1758+
rw ← P.uniq s.op m.op,
1759+
{ refl, },
1760+
{ dsimp, intro j, rw ← w, refl, }
1761+
end }
1762+
1763+
/--
1764+
`t : cone F` is a limit cone if and only is `t.op : cocone F.op` is a colimit cocone.
1765+
-/
1766+
def is_limit_equiv_is_colimit_op {t : cone F} : is_limit t ≃ is_colimit t.op :=
1767+
equiv_of_subsingleton_of_subsingleton
1768+
is_limit.op (λ P, P.unop.of_iso_limit (cones.ext (iso.refl _) (by tidy)))
1769+
1770+
/--
1771+
`t : cocone F` is a colimit cocone if and only is `t.op : cone F.op` is a limit cone.
1772+
-/
1773+
def is_colimit_equiv_is_limit_op {t : cocone F} : is_colimit t ≃ is_limit t.op :=
1774+
equiv_of_subsingleton_of_subsingleton
1775+
is_colimit.op (λ P, P.unop.of_iso_colimit (cocones.ext (iso.refl _) (by tidy)))
1776+
1777+
end opposite
1778+
17091779
end category_theory.limits

src/category_theory/monad/equiv_mon.lean

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,28 +87,43 @@ def Mon_to_Monad : Mon_ (C ⥤ C) ⥤ Monad C :=
8787
finish,
8888
end,
8989
..f.hom } }
90+
91+
namespace Monad_Mon_equiv
9092
variable {C}
9193

9294
/-- Isomorphism of functors used in `Monad_Mon_equiv` -/
9395
@[simps]
94-
def of_to_mon_end_iso : Mon_to_Monad C ⋙ Monad_to_Mon C ≅ 𝟭 _ :=
96+
def counit_iso : Mon_to_Monad C ⋙ Monad_to_Mon C ≅ 𝟭 _ :=
9597
{ hom := { app := λ _, { hom := 𝟙 _ } },
9698
inv := { app := λ _, { hom := 𝟙 _ } } }
9799

100+
/-- Auxilliary definition for `Monad_Mon_equiv` -/
101+
@[simps]
102+
def unit_iso_hom : 𝟭 _ ⟶ Monad_to_Mon C ⋙ Mon_to_Monad C :=
103+
{ app := λ _, { app := λ _, 𝟙 _ } }
104+
105+
/-- Auxilliary definition for `Monad_Mon_equiv` -/
106+
@[simps]
107+
def unit_iso_inv : Monad_to_Mon C ⋙ Mon_to_Monad C ⟶ 𝟭 _ :=
108+
{ app := λ _, { app := λ _, 𝟙 _ } }
109+
98110
/-- Isomorphism of functors used in `Monad_Mon_equiv` -/
99111
@[simps]
100-
def to_of_mon_end_iso : Monad_to_Mon C ⋙ Mon_to_Monad C ≅ 𝟭 _ :=
101-
{ hom := { app := λ _, { app := λ _, 𝟙 _ } },
102-
inv := { app := λ _, { app := λ _, 𝟙 _ } } }
112+
def unit_iso : 𝟭 _ ≅ Monad_to_Mon C ⋙ Mon_to_Monad C :=
113+
{ hom := unit_iso_hom,
114+
inv := unit_iso_inv }
115+
116+
end Monad_Mon_equiv
117+
118+
open Monad_Mon_equiv
103119

104-
variable (C)
105120
/-- Oh, monads are just monoids in the category of endofunctors (equivalence of categories). -/
106121
@[simps]
107122
def Monad_Mon_equiv : (Monad C) ≌ (Mon_ (C ⥤ C)) :=
108123
{ functor := Monad_to_Mon _,
109124
inverse := Mon_to_Monad _,
110-
unit_iso := to_of_mon_end_iso.symm,
111-
counit_iso := of_to_mon_end_iso }
125+
unit_iso := unit_iso,
126+
counit_iso := counit_iso }
112127

113128
-- Sanity check
114129
example (A : Monad C) {X : C} : ((Monad_Mon_equiv C).unit_iso.app A).hom.app X = 𝟙 _ := rfl

0 commit comments

Comments
 (0)