open import Cat.Diagram.Colimit.Base open import Cat.Instances.Functor open import Cat.Instances.Product open import Cat.Diagram.Initial open import Cat.Functor.Base open import Cat.Prelude import Cat.Instances.Elements as El import Cat.Reasoning module Cat.Functor.Hom {o h} (C : Precategory o h) where
The Hom functorπ
We prove that the assignment of -sets in a Precategory is a functor
, specifically a bifunctor from to . The action of on a morphism is given by ; Since is acting by precomposition, the first coordinate is contravariant ().
Hom[-,-] : Functor ((C ^op) ΓCat C) (Sets h) Hom[-,-] .Fβ (a , b) = Hom a b , Hom-set a b Hom[-,-] .Fβ (f , h) g = h β g β f Hom[-,-] .F-id = funext Ξ» x β ap (_ β_) (idr _) β idl _ Hom[-,-] .F-β (f , h) (f' , h') = funext Ξ» where g β (h β h') β g β f' β f β‘β¨ solve C β©β‘ h β (h' β g β f') β f βWe also can define βpartially appliedβ versions of the hom functor:
Hom[_,-] : Ob β Functor C (Sets h) Hom[ x ,-] .Fβ y = Hom x y , Hom-set x y Hom[ x ,-] .Fβ f g = f β g Hom[ x ,-] .F-id = funext (Ξ» f β idl f) Hom[ x ,-] .F-β f g = funext Ξ» h β sym (assoc f g h)
The Yoneda embeddingπ
Abstractly and nonsensically, one could say that the Yoneda embedding γ is the exponential transpose of flipping the Hom[-,-] bifunctor. However, this construction generates awful terms, so in the interest of computational efficiency we build up the functor explicitly.
module _ where private γ : Functor C (Cat[ C ^op , Sets h ]) γ = Curry Flip where open import Cat.Functor.Bifunctor {C = C ^op} {D = C} {E = Sets h} Hom[-,-]
We can describe the object part of this functor as taking an object to the functor of map into , with the transformation given by precomposition.
γβ : Ob β Functor (C ^op) (Sets h) γβ c .Fβ x = Hom x c , Hom-set _ _ γβ c .Fβ f = _β f γβ c .F-id = funext idr γβ c .F-β f g = funext Ξ» h β assoc _ _ _
We also define a synonym for γβ to better line up with the covariant direction.
Hom[-,_] : Ob β Functor (C ^op) (Sets h) Hom[-,_] x = γβ x
The morphism part takes a map to the transformation given by postcomposition; This is natural because we must show , which is given by associativity in .
γβ : Hom a b β γβ a => γβ b γβ f .Ξ· _ g = f β g γβ f .is-natural x y g = funext Ξ» x β assoc f x g
The other category laws from ensure that this assigment of natural transformations is indeed functorial:
γ : Functor C Cat[ C ^op , Sets h ] γ .Fβ = γβ γ .Fβ = γβ γ .F-id = Nat-path Ξ» _ i g β idl g i γ .F-β f g = Nat-path Ξ» _ i h β assoc f g h (~ i)
The morphism mapping γβ has an inverse, given by evaluating the natural transformation with the identity map; Hence, the Yoneda embedding functor is fully faithful.
γ-is-fully-faithful : is-fully-faithful γ γ-is-fully-faithful = is-isoβis-equiv isom where open is-iso isom : is-iso γβ isom .inv nt = nt .Ξ· _ id isom .rinv nt = Nat-path Ξ» c β funext Ξ» g β happly (sym (nt .is-natural _ _ _)) _ β ap (nt .Ξ· c) (idl g) isom .linv _ = idr _
The Coyoneda Lemmaπ
The Coyoneda lemma is, like its dual, a statement about presheaves. It states that βevery presheaf is a colimit of representablesβ, which, in less abstract terms, means that every presheaf arises as some way of gluing together a bunch of (things isomorphic to) hom functors!
module _ (P : Functor (C ^op) (Sets h)) where private module P = Functor P open El C P open Element open Element-hom
We start by fixing some presheaf , and constructing a Cocone whose coapex is . This involves a clever choice of diagram category: specifically, the category of elements of . This may seem like a somewhat odd choice, but recall that the data contained in is the same data as , just melted into a soup of points. The cocone we construct will then glue all those points back together into .
This is done by projecting out of into via the canonical projection, and then embedding into the category of presheaves over via the yoneda embedding. Concretely, what this diagram gives us is a bunch of copies of the hom functor, one for each . Then, to construct the injection map, we can just use the (contravariant) functorial action of to take a and a to a . This map is natural by functoriality of .
Reassemble : Cocone (γ Fβ Οβ) Reassemble .Cocone.coapex = P Reassemble .Cocone.Ο x .Ξ· y f = P.Fβ f (x .section) Reassemble .Cocone.Ο x .is-natural y z f = funext (Ξ» g β happly (P.F-β f g) (x .section)) Reassemble .Cocone.commutes {x = x} {y = y} f = Nat-path Ξ» z β funext Ξ» g β P.Fβ (f .hom β g) (y .section) β‘β¨ happly (P.F-β g (f .hom)) (y .section) β©β‘ P.Fβ g (P.Fβ (f .hom) (y .section)) β‘β¨ ap (P.Fβ g) (f .commute) β©β‘ P.Fβ g (x .section) β
Now that weβve constructed a cocone, all that remains is to see that this is a colimiting cocone. Intuitively, it makes sense that Reassemble should be colimiting: all weβve done is taken all the data associated with and glued it back together. However, proving this does involve futzing about with various naturality + cocone commuting conditions.
coyoneda : is-colimit (γ Fβ Οβ) Reassemble coyoneda K = contr (cocone-hom universal factors) unique where module K = Cocone K module β« = Precategory β« module Reassemble = Cocone Reassemble open Cocone-hom
We start by constructing the universal map from into the coapex of some other cocone . The components of this natural transformation are obtained in a similar manner to the yoneda lemma; we bundle up the data to construct an object of , and then apply the function we construct to the identity morphism. Naturality follows from the fact that is a cocone, and the components of are natural.
universal : P => K.coapex universal .Ξ· x px = K.Ο (elem x px) .Ξ· x id universal .is-natural x y f = funext Ξ» px β K.Ο (elem y (P.Fβ f px)) .Ξ· y id β‘Λβ¨ (Ξ» i β K.commutes (induce f px) i .Ξ· y id) β©β‘Λ K.Ο (elem x px) .Ξ· y (f β id) β‘β¨ ap (K.Ο (elem x px) .Ξ· y) id-comm β©β‘ K.Ο (elem x px) .Ξ· y (id β f) β‘β¨ happly (K.Ο (elem x px) .is-natural x y f) id β©β‘ Fβ K.coapex f (K.Ο (elem x px) .Ξ· x id) β
Next, we need to show that this morphism factors each of the components of . The tricky bit of the proof here is that we need to use induce to regard f
as a morphism in the category of elements.
factors : β o β universal βnt Reassemble.Ο o β‘ K.Ο o factors o = Nat-path Ξ» x β funext Ξ» f β K.Ο (elem x (P.Fβ f (o .section))) .Ξ· x id β‘Λβ¨ (Ξ» i β K.commutes (induce f (o .section)) i .Ξ· x id) β©β‘Λ K.Ο o .Ξ· x (f β id) β‘β¨ ap (K.Ο o .Ξ· x) (idr f) β©β‘ K.Ο o .Ξ· x f β
Finally, uniqueness: This just follows by the commuting conditions on Ξ±
.
unique : (Ξ± : Cocone-hom (γ Fβ Οβ) Reassemble K) β cocone-hom universal factors β‘ Ξ± unique Ξ± = Cocone-hom-path (γ Fβ Οβ) $ Nat-path Ξ» x β funext Ξ» px β K.Ο (elem x px) .Ξ· x id β‘Λβ¨ (Ξ» i β Ξ± .commutes (elem x px) i .Ξ· x id) β©β‘Λ Ξ± .hom .Ξ· x (Reassemble.Ο (elem x px) .Ξ· x id) β‘β¨ ap (Ξ± .hom .Ξ· x) (happly (P.F-id) px) β©β‘ Ξ± .hom .Ξ· x px β
And thatβs it! The important takeaway here is not the shuffling around of natural transformations required to prove this lemma, but rather the idea that, unlike Humpty Dumpty, if a presheaf falls off a wall, we can put it back together again.
An important consequence of being able to disassemble presheaves into colimits of representables is that representables generate , in that if a pair of natural transformations that agrees on all representables, then all along.
module _ {Y} (f : P => Y) where private module Y = Functor Y open Cocone
The first thing we prove is that any map of presheaves expresses as a cocone over . The special case Reassemble above is this procedure for the identity map β whence we see that coyoneda is essentially a restatement of the fact that is initial the coslice category under .
Mapβcocone-under : Cocone (γ Fβ Οβ) Mapβcocone-under .coapex = Y Mapβcocone-under .Ο (elem ob sect) .Ξ· x i = f .Ξ· x (P.β i sect) Mapβcocone-under .Ο (elem ob sect) .is-natural x y h = funext Ξ» a β f .Ξ· _ (P.β (a β h) sect) β‘β¨ happly (f .is-natural _ _ _) _ β©β‘ Y.β (a β h) (f .Ξ· _ sect) β‘β¨ happly (Y.F-β _ _) _ β©β‘ Y.β h (Y.β a (f .Ξ· _ sect)) β‘Λβ¨ ap (Y .Fβ h) (happly (f .is-natural _ _ _) _) β©β‘Λ Y.β h (f .Ξ· _ (P.β a sect)) β Mapβcocone-under .commutes {x} {y} o = Nat-path Ξ» i β funext Ξ» a β ap (f .Ξ· _) $ P.β (o .hom β a) (y .section) β‘β¨ happly (P.F-β _ _) _ β©β‘ P.β a (P.β (o .hom) (y .section)) β‘β¨ ap (P.Fβ _) (o .commute) β©β‘ P.β a (x .section) β
We can now prove that, if are two maps such that, for every map with representable domain , , then . The quantifier structure of this sentence is a bit funky, so watch out for the formalisation below:
Representables-generate-presheaf : {f g : X => Y} β ( β {A : Ob} (h : γβ A => X) β f PSh.β h β‘ g PSh.β h ) β f β‘ g
A map can be seen as a βgeneralised elementβ of , so that the precondition for can be read as β and agree for all generalised elements with domain any representableβ. The proof is deceptively simple: Since is a colimit, it is an initial object in the category of cocones under .
The construction Mapβcocone-under lets us express as a cocone under in a way that becomes a cocone homomorphism ; The condition that agrees with on all generalised elements with representable domains ensures that is also a cocone homomorphism ; But is initial, so !
Representables-generate-presheaf {f} {g} sep = ap hom $ is-contrβis-prop (coyoneda X (Mapβcocone-under X f)) fβ² gβ² where fβ² : Cocone-hom (γ Fβ El.Οβ C X) (Reassemble X) (Mapβcocone-under X f) fβ² .hom = f fβ² .commutes o = Nat-path (Ξ» _ β refl) gβ² : Cocone-hom (γ Fβ El.Οβ C X) (Reassemble X) (Mapβcocone-under X f) gβ² .hom = g gβ² .commutes o = Nat-path Ξ» x β ap (Ξ» e β e .Ξ· x) $ sym $ sep $ NT (Ξ» i a β P.β a (o .section)) Ξ» x y h β funext Ξ» _ β happly (P.F-β _ _) _
An immediate consequence is that, since any pair of maps in extend to maps , and the functor is fully faithful, two maps in are equal iff. they agree on all generalised elements:
private module _ where private γ-cancelr : β {X Y : Ob} {f g : Hom X Y} β (β {Z} (h : Hom Z X) β f β h β‘ g β h) β f β‘ g γ-cancelr sep = fully-faithfulβfaithful {F = γ} γ-is-fully-faithful $ Representables-generate-presheaf Ξ» h β Nat-path Ξ» x β funext Ξ» a β sep (h .Ξ· x a)
However note that we have eliminated a mosquito using a low-orbit ion cannon:
γ-cancelr : β {X Y : Ob} {f g : Hom X Y} β (β {Z} (h : Hom Z X) β f β h β‘ g β h) β f β‘ g γ-cancelr sep = sym (idr _) β sep id β idr _