module Cat.Functor.Final where

Final functorsπŸ”—

A final functor expresses an equivalence of diagram schemata for the purposes of computing colimits: if is final, then colimits for are equivalent to colimits for A terminological warning: in older literature (e.g. (Borceux 1994) and (Adamek and Rosicky 1994)), these functors are called cofinal, but we stick with terminology from the nLab here.

Finality has an elementary characterisation: we define a functor to be final if, for every the comma category is connected. That is, unpacking, the following data: for every object an object and a map and for every span

a finite zigzag of morphisms from to inducing a chain of commuting triangles from to For example, in the case of a β€œcospan” zigzag

  is-final : Type (o βŠ” β„“ βŠ” o' βŠ” β„“')
  is-final = βˆ€ d β†’ is-connected-cat (d ↙ F)

The utility of this definition comes, as mentioned, from the ability to move cocones back and forth between a diagram and its restriction to the domain category in a way that preserves the property of being a colimit. First, for any functor we can restrict cocones under to cocones under by precomposition.

    restrict-cocone : βˆ€ {coapex} β†’ D => Const coapex β†’ D F∘ F => Const coapex
    restrict-cocone K .Ξ· x = K .Ξ· (F.β‚€ x)
    restrict-cocone K .is-natural x y f = K .is-natural (F.β‚€ x) (F.β‚€ y) (F.₁ f)

    Restrict-cocone : Functor (Cocones D) (Cocones (D F∘ F))
    Restrict-cocone .F₀ K = cocone→Cocone _ (restrict-cocone (Cocone→cocone _ K))
    Restrict-cocone .F₁ f .map = f .map
    Restrict-cocone .F₁ f .com c = f .com (F.β‚€ c)
    Restrict-cocone .F-id = ext refl
    Restrict-cocone .F-∘ _ _ = ext refl

The point is now that, if is final, then the restriction functor thus defined is an equivalence of categories between the categories of cocones under and

First, if we have a cocone then precomposition with the map (where comes from the finality of defines a cocone

However, since the comma category is merely inhabited, we need to make sure that this extension is independent of the choice of and This follows from naturality of the cocone and by connectedness of as expressed by the commutativity of the following diagram:

    module _ {coapex} (cocone : D F∘ F => Const coapex) where
      extend : βˆ€ d β†’ Ob (d ↙ F) β†’ β„°.Hom (D.β‚€ d) coapex
      extend d f = cocone .Ξ· (f .cod) β„°.∘ D.₁ (f .map)

      opaque
        extend-const1
          : βˆ€ d {f g : Ob (d ↙ F)} (h : ↓Hom _ _ f g)
          β†’ extend d f ≑ extend d g
        extend-const1 d {f} {g} h =
          cocone .Ξ· _ β„°.∘ D.₁ (f .map)                          β‰‘Λ˜βŸ¨ cocone .is-natural _ _ _ βˆ™ β„°.idl _ β„°.⟩∘⟨refl βŸ©β‰‘Λ˜
          (cocone .Ξ· _ β„°.∘ D.₁ (F.₁ (h .bot))) β„°.∘ D.₁ (f .map) β‰‘βŸ¨ D.pullr refl βŸ©β‰‘
          cocone .Ξ· _ β„°.∘ D.₁ ⌜ F.₁ (h .bot) π’Ÿ.∘ f .map ⌝       β‰‘βŸ¨ ap! (sym (h .com) βˆ™ π’Ÿ.idr _) βŸ©β‰‘
          cocone .Ξ· _ β„°.∘ D.₁ (g .map)                          ∎

      opaque
        extend-const
          : βˆ€ d (f g : Ob (d ↙ F))
          β†’ extend d f ≑ extend d g
        extend-const d f g = case fin.path d f g of
          Meander-rec-≑ (el! _) (extend d) (extend-const1 d)

      extend' : βˆ€ d β†’ βˆ₯ Ob (d ↙ F) βˆ₯ β†’ β„°.Hom (D.β‚€ d) coapex
      extend' d = βˆ₯-βˆ₯-rec-set (hlevel 2) (extend d) (extend-const d)

      extend-cocone : D => Const coapex
      extend-cocone .Ξ· d = extend' d (fin.point d)
      extend-cocone .is-natural x y f =
        case fin.point x , fin.point y return
          (Ξ» (x' , y') β†’ extend' y y' β„°.∘ D.₁ f ≑ β„°.id β„°.∘ extend' x x')
        of Ξ» x' y' β†’
          extend y y' β„°.∘ D.₁ f           β‰‘βŸ¨ D.pullr refl βŸ©β‰‘
          extend x (↓obj (y' .map π’Ÿ.∘ f)) β‰‘βŸ¨ extend-const x (↓obj _) x' βŸ©β‰‘
          extend x x'                     β‰‘βŸ¨ β„°.introl refl βŸ©β‰‘
          β„°.id β„°.∘ extend x x'            ∎

A few more computations show that restrict-cocone and extend-cocone are inverses (so that Restrict-cocone is an equivalence on objects), and that the restriction functor is fully faithful, which makes it an isomorphism of categories (and thus an equivalence).

    restrict-cocone-is-equiv : βˆ€ {coapex} β†’ is-equiv (restrict-cocone D {coapex = coapex})
    restrict-cocone-is-equiv = is-iso→is-equiv λ where
      .from K β†’ extend-cocone K
      .rinv K β†’ ext Ξ» c β†’
        case fin.point (F.β‚€ c) return
          (Ξ» c' β†’ extend' _ (F.β‚€ c) c' ≑ K .Ξ· c)
        of Ξ» c' β†’
          extend-const K (F.β‚€ c) c' (↓obj π’Ÿ.id) βˆ™ D.elimr refl
      .linv K β†’ ext Ξ» d β†’
        case fin.point d return
          (Ξ» d' β†’ extend' (restrict-cocone D K) d d' ≑ K .Ξ· d)
        of Ξ» d' β†’
          K .is-natural _ _ (d' .map) βˆ™ β„°.eliml refl

    restrict-cocone≃ : βˆ€ {coapex} β†’ (D => Const coapex) ≃ (D F∘ F => Const coapex)
    restrict-cocone≃ = _ , restrict-cocone-is-equiv

    Restrict-cocone-ff : is-fully-faithful (Restrict-cocone D)
    Restrict-cocone-ff {X} {Y} = is-iso→is-equiv λ where
      .is-iso.from f .map β†’ f .map
      .is-iso.from f .com d β†’ case fin.point d of Ξ» d' β†’
        f .map β„°.∘ X .ψ d                                 β‰‘βŸ¨ β„°.cdr (sym (X .commutes (d' .map))) βŸ©β‰‘
        f .map β„°.∘ X .ψ (F.β‚€ (d' .cod)) β„°.∘ D.₁ (d' .map) β‰‘βŸ¨ β„°.pulll (f .com (d' .cod)) βŸ©β‰‘
        Y .ψ (F.β‚€ (d' .cod)) β„°.∘ D.₁ (d' .map)            β‰‘βŸ¨ Y .commutes (d' .map) βŸ©β‰‘
        Y .ψ d                                            ∎
      .is-iso.rinv _ β†’ ext refl
      .is-iso.linv _ β†’ ext refl

    Restrict-cocone-is-precat-iso : is-precat-iso (Restrict-cocone D)
    Restrict-cocone-is-precat-iso .has-is-ff = Restrict-cocone-ff
    Restrict-cocone-is-precat-iso .has-is-iso = snd $
      Cocone≃cocone _ βˆ™e Ξ£-ap-snd (Ξ» _ β†’ restrict-cocone≃) βˆ™e Cocone≃cocone _ e⁻¹

    Restrict-cocone-is-equivalence : is-equivalence (Restrict-cocone D)
    Restrict-cocone-is-equivalence = is-precat-iso→is-equivalence Restrict-cocone-is-precat-iso

    module Restrict-cocone = is-equivalence Restrict-cocone-is-equivalence

Since Restrict-cocone is an equivalence, it preserves initial objects, i.e. colimiting cocones. In other words, if is a colimit of then its restriction is a colimit of

    restrict-is-colimit
      : βˆ€ {coapex}
      β†’ (K : D => Const coapex)
      β†’ is-colimit D coapex K
      β†’ is-colimit (D F∘ F) coapex (restrict-cocone D K)
    restrict-is-colimit {coapex} K colim =
      generalize-colimitp
        (is-initial-cocone→is-colimit _
          (left-adjointβ†’initial (Restrict-cocone.F⊣F⁻¹)
            (is-colimit→is-initial-cocone _ colim)))
        refl

But we can also go the other way: if is a colimit of then its extension is a colimit of

    extend-is-colimit
      : βˆ€ {coapex} (K : D F∘ F => Const coapex)
      β†’ is-colimit (D F∘ F) coapex K
      β†’ is-colimit D coapex (extend-cocone K)
    extend-is-colimit {coapex} K colim =
      generalize-colimitp
        (is-initial-cocone→is-colimit _
          (left-adjointβ†’initial Restrict-cocone.F⁻¹⊣F
            (is-colimit→is-initial-cocone _ colim)))
        Ξ» {d} β†’ case fin.point d return
          (Ξ» d' β†’ extend' _ d d' ≑ extend' K d d')
        of Ξ» d' β†’ refl

Finally, we summarise these results as a displayed equivalence between the property of being a colimit for cocones under and for cocones under

    finalβ†’is-colimit≃
      : βˆ€ {coapex}
      β†’ is-colimit D coapex ≃[ restrict-cocone≃ ] is-colimit (D F∘ F) coapex
    finalβ†’is-colimit≃ = prop-over-ext!
      restrict-cocone≃ restrict-is-colimit extend-is-colimit

ExamplesπŸ”—

Final functors between pregroupoids have a very simple characterisation: they are the full, essentially surjective functors. In this case, there is a direct connection with homotopy type theory: groupoids are 1-types, comma categories are fibres of over and so finality says that is a connected map.

Essential surjectivity on objects pretty much exactly says that each comma category is inhabited. To see that fullness implies the existence of zigzags, meditate on the following diagram:

  module _ (π’ž-grpd : is-pregroupoid π’ž) (π’Ÿ-grpd : is-pregroupoid π’Ÿ) where
    full+eso→final : is-full F → is-eso F → is-final
    full+eso→final full eso d .path f g = do
      z , p ← full (g .map π’Ÿ.∘ π’Ÿ-grpd (f .map) .inv)
      pure $ zig
        (↓hom {bot = z}
          (π’Ÿ.idr _ βˆ™ sym (π’Ÿ.rswizzle p (π’Ÿ-grpd (f .map) .invr))))
        []
      where open π’Ÿ.is-invertible
    full+eso→final full eso d .point =
      βˆ₯-βˆ₯-map (Ξ» e β†’ ↓obj (π’Ÿ.from (e .snd))) (eso d)

For the other direction, given observe that connectedness of the comma category gives us a zigzag between and but since is a pregroupoid we can evaluate this zigzag to a single morphism such that

    final→full+eso : is-final → is-full F × is-eso F
    final→full+eso fin .fst {x} {y} f = do
      zs ← fin (F.β‚€ x) .path (↓obj π’Ÿ.id) (↓obj f)
      let z = Free-groupoid-counit
            (↓-is-pregroupoid _ _ ⊀Cat-is-pregroupoid π’ž-grpd)
            .F₁ zs
      pure (z .bot , sym (π’Ÿ.idr _) βˆ™ sym (z .com) βˆ™ π’Ÿ.idr _)
    final→full+eso fin .snd d = do
      fd ← fin d .point
      pure (fd .cod , π’Ÿ.invertibleβ†’iso (fd .map) (π’Ÿ-grpd _) π’Ÿ.Iso⁻¹)

Another general class of final functors is given by right adjoint functors. This follows directly from the characterisation of right adjoints in terms of free objects: since the comma categories have initial objects, they are connected.

opaque
  right-adjoint-is-final
    : βˆ€ {o β„“ o' β„“'} {π’ž : Precategory o β„“} {π’Ÿ : Precategory o' β„“'}
    β†’ {L : Functor π’ž π’Ÿ} {R : Functor π’Ÿ π’ž} (L⊣R : L ⊣ R)
    β†’ is-final R
  right-adjoint-is-final L⊣R c =
    initialβ†’connected (left-adjointβ†’universal-maps L⊣R c)

In particular, the inclusion of a terminal object into a category is a final functor. This means that the colimit of any diagram over a shape category with a terminal object is simply the value of the diagram on the terminal object.

terminal→inclusion-is-final
  : βˆ€ {o β„“} {π’ž : Precategory o β„“}
  β†’ (top : π’ž .Ob) (term : is-terminal π’ž top)
  β†’ is-final (!Const {C = π’ž} top)
terminal→inclusion-is-final top term = right-adjoint-is-final
  (is-terminal→inclusion-is-right-adjoint _ top term)

Closure under compositionπŸ”—

We now prove that final functors are closed under composition.

First, given an object we get a map using the finality of and a map using the finality of which we can compose into an object of

  F∘-is-final : is-final (G F∘ F)
  F∘-is-final c .point = do
    g ← gf.point c
    f ← ff.point (g .cod)
    pure (g ↙> f)

Now, given a span finality of gives us a zigzag between and in but we need a zigzag between and in Thus we have to refine our zigzag step by step, using the finality of

  F∘-is-final c .path f g = do
    gz ← gf.path c (↓obj (f .map)) (↓obj (g .map))
    fz ← refine gz (↓obj π’Ÿ.id) (↓obj π’Ÿ.id)
    pure (substβ‚‚ (Meander (c ↙ G F∘ F)) ↙>-id ↙>-id fz)

We start by defining a congruence on the objects of whereby and are related if, for any extensions and there merely exists a zigzag between the corresponding objects of

    where
      R : Congruence (Ob (c ↙ G)) _
      R ._∼_ f g =
        βˆ€ (f' : Ob (f .cod ↙ F)) (g' : Ob (g .cod ↙ F))
        β†’ βˆ₯ Meander (c ↙ G F∘ F) (f ↙> f') (g ↙> g') βˆ₯
      R .has-is-prop _ _ = hlevel 1

That this is a congruence is easily checked using the finality of

      R .reflᢜ {f} f' g' =
        Free-groupoid-map (↙-compose f) .F₁ <$> ff.path (f .cod) f' g'
      R ._βˆ™αΆœ_ {f} {g} {h} fg gh f' h' = do
        g' ← ff.point (g .cod)
        βˆ₯-βˆ₯-mapβ‚‚ _++_ (gh g' h') (fg f' g')
      R .symᢜ fg g' f' = βˆ₯-βˆ₯-map (reverse _) (fg f' g')

Using the universal mapping property of the free groupoid into congruences, we conclude by showing that any two arrows connected by a morphism are related, which again involves the connectedness of

      refine1 : βˆ€ {f g} β†’ Hom (c ↙ G) f g β†’ R ._∼_ f g
      refine1 {f} {g} h f' g' = do
        z ← ff.path (f .cod) f' (↓obj (g' .map π’Ÿ.∘ h .bot))
        let
          z' : Meander (c ↙ G F∘ F) _ _
          z' = Free-groupoid-map (↙-compose f) .F₁ z
          fixup : f ↙> ↓obj (g' .map π’Ÿ.∘ h .bot) ≑ g ↙> g'
          fixup = ext $ refl ,β‚š G.pushl refl βˆ™ (β„°.refl⟩∘⟨ sym (h .com) βˆ™ β„°.idr _)
        pure (subst (Meander (c ↙ G F∘ F) (f ↙> f')) fixup z')

      refine : βˆ€ {f g} β†’ Meander (c ↙ G) f g β†’ R ._∼_ f g
      refine = Meander-rec-congruence R refine1

References