open import 1Lab.Path.Cartesian

open import Cat.Prelude

import Cat.Reasoning

module Cat.Functor.Base where


# Functor precategoriesπ

Fix a pair of (completely arbitrary!) precategories and Weβll show how to make the type of functors into a precategory on its own right, with the natural transformations as the morphisms. First, given we construct the identity natural transformation by having every component be the identity:

private variable
o oβ oβ β ββ ββ : Level
B C D E : Precategory o β
F G : Functor C D

private module Pc = Precategory
open Functor
open _=>_

module _ {C : Precategory o β} {D : Precategory oβ ββ} where
private
module C = Cat.Reasoning C
module D = Cat.Reasoning D

  idnt : {F : Functor C D} β F => F
idnt .Ξ· _              = D.id
idnt .is-natural _ _ _ = D.id-comm-sym


Moreover, if we have a pair of composable-looking natural transformations and then we can indeed make their pointwise composite into a natural transformation:

  _βnt_ : β {F G H : Functor C D} β G => H β F => G β F => H
(f βnt g) .Ξ· x = f .Ξ· x D.β g .Ξ· x
_βnt_ {F} {G} {H} f g .is-natural x y h =
(f .Ξ· y D.β g .Ξ· y) D.β F .Fβ h β‘β¨ D.pullr (g .is-natural x y h) β©β‘
f .Ξ· y D.β G .Fβ h D.β g .Ξ· x   β‘β¨ D.extendl (f .is-natural x y h) β©β‘
H .Fβ h D.β f .Ξ· x D.β g .Ξ· x   β

infixr 40 _βnt_


Since we already know that identity of natural transformations is determined by identity of the underlying family of morphisms, and the identities and composition weβve just defined are componentwise just identity and composition in then the category laws we have to prove are, once again, those of

Cat[_,_]
: Precategory o β β Precategory oβ ββ
β Precategory (o β β β oβ β ββ) (o β β β ββ)
Cat[ C , D ] .Pc.Ob          = Functor C D
Cat[ C , D ] .Pc.Hom         = _=>_
Cat[ C , D ] .Pc.Hom-set F G = hlevel 2

Cat[ C , D ] .Pc.id  = idnt
Cat[ C , D ] .Pc._β_ = _βnt_

Cat[ C , D ] .Pc.idr f       = ext Ξ» x β D .Pc.idr _
Cat[ C , D ] .Pc.idl f       = ext Ξ» x β D .Pc.idl _
Cat[ C , D ] .Pc.assoc f g h = ext Ξ» x β D .Pc.assoc _ _ _


Weβll also need the following foundational tool, characterising paths between functors. It says that, given a homotopy between the object-parts of functors and, over this, an identification between the actions of and on morphisms, we can construct a path

## Paths between functorsπ

Functor-path
: {F G : Functor C D}
β (p0 : β x β F .Fβ x β‘ G .Fβ x)
β (p1 : β {x y} (f : C .Pc.Hom x y)
β PathP (Ξ» i β D .Pc.Hom (p0 x i) (p0 y i)) (F .Fβ f) (G .Fβ f))
β F β‘ G


Note that this lemma is a bit unusual: weβre characterising the identity type of the objects of a precategory, rather than, as is more common, the morphisms of a precategory. However, this characterisation will let us swiftly establish necessary conditions for univalence of functor categories.

Functor-pathp
: {C : I β Precategory o β} {D : I β Precategory oβ ββ}
{F : Functor (C i0) (D i0)} {G : Functor (C i1) (D i1)}
β (p0 : β (p : β i β C i .Pc.Ob) β PathP (Ξ» i β D i .Pc.Ob) (F .Fβ (p i0)) (G .Fβ (p i1)))
β (p1 : β {x y : β i β _}
β (r : β i β C i .Pc.Hom (x i) (y i))
β PathP (Ξ» i β D i .Pc.Hom (p0 x i) (p0 y i))
(F .Fβ (r i0)) (G .Fβ (r i1)))
β PathP (Ξ» i β Functor (C i) (D i)) F G
Functor-pathp {C = C} {D} {F} {G} p0 p1 = fn where
open Pc
cob : I β Type _
cob = Ξ» i β C i .Ob

exth
: β i j (x y : C i .Ob) (f : C i .Hom x y)
β C i .Hom (coe cob i i x) (coe cob i i y)
exth i j x y f =
comp (Ξ» j β C i .Hom (coeiβi cob i x (~ j β¨ i)) (coeiβi cob i y (~ j β¨ i)))
((~ i β§ ~ j) β¨ (i β§ j))
Ξ» where
k (k = i0) β f
k (i = i0) (j = i0) β f
k (i = i1) (j = i1) β f

actm
: β i (x y : C i .Ob) f
β D i .Hom (p0 (Ξ» j β coe cob i j x) i) (p0 (Ξ» j β coe cob i j y) i)
actm i x y f =
p1 {Ξ» j β coe cob i j x} {Ξ» j β coe cob i j y}
(Ξ» j β coe (Ξ» j β C j .Hom (coe cob i j x) (coe cob i j y)) i j (exth i j x y f))
i

fn : PathP (Ξ» i β Functor (C i) (D i)) F G
fn i .Fβ x =
p0 (Ξ» j β coe cob i j x)
i
fn i .Fβ {x} {y} f = actm i x y f
fn i .F-id {x} =
hcomp (β i) Ξ» where
j (i = i0) β D i .Hom-set (F .Fβ x) (F .Fβ x) (F .Fβ (C i .id)) (D i .id) base (F .F-id) j
j (i = i1) β D i .Hom-set (G .Fβ x) (G .Fβ x) (G .Fβ (C i .id)) (D i .id) base (G .F-id) j
j (j = i0) β base
where
base = coe0βi (Ξ» i β (x : C i .Ob) β actm i x x (C i .id) β‘ D i .id) i
(Ξ» _ β F .F-id) x
fn i .F-β {x} {y} {z} f g =
hcomp (β i) Ξ» where
j (i = i0) β D i .Hom-set (F .Fβ x) (F .Fβ z) _ _ base (F .F-β f g) j
j (i = i1) β D i .Hom-set (G .Fβ x) (G .Fβ z) _ _ base (G .F-β f g) j
j (j = i0) β base
where
base = coe0βi (Ξ» i β (x y z : C i .Ob) (f : C i .Hom y z) (g : C i .Hom x y)
β actm i x z (C i ._β_ f g)
β‘ D i ._β_ (actm i y z f) (actm i x y g)) i
(Ξ» _ _ _ β F .F-β) x y z f g

Functor-path p0 p1 i .Fβ x = p0 x i
Functor-path p0 p1 i .Fβ f = p1 f i
Functor-path {C = C} {D = D} {F = F} {G = G} p0 p1 i .F-id =
is-propβpathp (Ξ» j β D .Pc.Hom-set _ _ (p1 (C .Pc.id) j) (D .Pc.id))
(F .F-id) (G .F-id) i
Functor-path {C = C} {D = D} {F = F} {G = G} p0 p1 i .F-β f g =
is-propβpathp (Ξ» i β D .Pc.Hom-set _ _ (p1 (C .Pc._β_ f g) i) (D .Pc._β_ (p1 f i) (p1 g i)))
(F .F-β f g) (G .F-β f g) i


## Action on isomorphismsπ

module F-iso {C : Precategory o β} {D : Precategory oβ ββ} (F : Functor C D) where
private module _ where
module C = Cat.Reasoning C
module D = Cat.Reasoning D
open Cat.Reasoning using (_β_ ; Inverses)
open _β_ public
open Inverses public


We have also to make note of the following fact: absolutely all functors preserve isomorphisms, and, more generally, preserve invertibility.

  F-map-iso : β {x y} β x C.β y β F # x D.β F # y
F-map-iso x .to       = F .Fβ (x .to)
F-map-iso x .from     = F .Fβ (x .from)
F-map-iso x .inverses =
record { invl = sym (F .F-β _ _) β ap (F .Fβ) (x .invl) β F .F-id
; invr = sym (F .F-β _ _) β ap (F .Fβ) (x .invr) β F .F-id
}
where module x = C._β_ x

F-map-invertible : β {x y} {f : C.Hom x y} β C.is-invertible f β D.is-invertible (F .Fβ f)
F-map-invertible inv =
D.make-invertible (F .Fβ _)
(sym (F .F-β _ _) Β·Β· ap (F .Fβ) x.invl Β·Β· F .F-id)
(sym (F .F-β _ _) Β·Β· ap (F .Fβ) x.invr Β·Β· F .F-id)
where module x = C.is-invertible inv


If the categories the functor maps between are univalent, there is a competing notion of preserving isomorphisms: the action on paths of the object-part of the functor. We first turn the isomorphism into a path (using univalence of the domain), run it through the functor, then turn the resulting path back into an isomorphism. Fortunately, functors are already coherent enough to ensure that these actions agree:

  F-map-path
: (ccat : is-category C) (dcat : is-category D)
β β {x y} (i : x C.β y)
β ap# F (Univalent.isoβpath ccat i) β‘ Univalent.isoβpath dcat (F-map-iso i)
F-map-path ccat dcat {x} = Univalent.J-iso ccat P pr where
P : (b : C.Ob) β C.Isomorphism x b β Type _
P b im = ap# F (Univalent.isoβpath ccat im)
β‘ Univalent.isoβpath dcat (F-map-iso im)

pr : P x C.id-iso
pr =
ap# F (Univalent.isoβpath ccat C.id-iso) β‘β¨ ap (ap# F) (Univalent.isoβpath-id ccat) β©β‘
ap# F refl                               β‘Λβ¨ Univalent.isoβpath-id dcat β©β‘Λ
dcat .to-path D.id-iso                   β‘β¨ ap (dcat .to-path) (ext (sym (F .F-id))) β©β‘
dcat .to-path (F-map-iso C.id-iso)       β

  ap-Fβ-to-iso
: β {y z}
β (p : y β‘ z) β pathβiso (ap# F p) β‘ F-map-iso (pathβiso p)
ap-Fβ-to-iso {y} =
J (Ξ» _ p β pathβiso (ap# F p) β‘ F-map-iso (pathβiso p))
(D.β-pathp (Ξ» _ β F .Fβ y) (Ξ» _ β F .Fβ y)
(Regularity.fast! (sym (F .F-id))))

ap-Fβ-iso
: β (cc : is-category C) {y z : C.Ob}
β (p : y C.β z) β pathβiso (ap# F (cc .to-path p)) β‘ F-map-iso p
ap-Fβ-iso cc p = ap-Fβ-to-iso (cc .to-path p)
β ap F-map-iso (Univalent.isoβpathβiso cc p)

open F-iso public


# Presheaf precategoriesπ

Of principal importance among the functor categories are those to the category these are the presheaf categories.

PSh : β ΞΊ {o β} β Precategory o β β Precategory _ _
PSh ΞΊ C = Cat[ C ^op , Sets ΞΊ ]