module Cat.Instances.Elements.Covariant {o β s} (C : Precategory o β)
  (P : Functor C (Sets s)) whereThe covariant category of elementsπ
While the category of elements comes up most often in the context of presheaves (i.e., contravariant functors into ), the construction makes sense for covariant functors as well.
Sadly, we cannot simply reuse the contravariant construction, instantiating as : the resulting category would be the opposite of what we want. Indeed, in both the covariant and contravariant cases, we want the projection to be covariant.
Thus we proceed to dualise the whole construction.
record Element : Type (o β s) where
  constructor elem
  field
    ob : Ob
    section : β£ P.β ob β£
open Element
record Element-hom (x y : Element) : Type (β β s) where
  constructor elem-hom
  no-eta-equality
  field
    hom : Hom (x .ob) (y .ob)
    commute : P.β hom (x .section) β‘ y .section
open Element-hom
Element-hom-path : {x y : Element} {f g : Element-hom x y} β f .hom β‘ g .hom β f β‘ g
Element-hom-path p i .hom = p i
Element-hom-path {x = x} {y = y} {f = f} {g = g} p i .commute =
  is-propβpathp (Ξ» j β P.β (y .ob) .is-tr (P.β (p j) (x .section)) (y .section))
    (f .commute)
    (g .commute) i
private unquoteDecl eqv = declare-record-iso eqv (quote Element-hom)
Element-hom-is-set : β (x y : Element) β is-set (Element-hom x y)
Element-hom-is-set x y = Isoβis-hlevel 2 eqv T-is-set where
  T-is-set : is-set _
  T-is-set = hlevel!
β« : Precategory (o β s) (β β s)
β« .Precategory.Ob = Element
β« .Precategory.Hom = Element-hom
β« .Precategory.Hom-set = Element-hom-is-set
β« .Precategory.id {x = x} = elem-hom id Ξ» i β P.F-id i (x .section)
β« .Precategory._β_ {x = x} {y = y} {z = z} f g = elem-hom (f .hom β g .hom) comm
  where
    abstract
      comm : P.β (f .hom β g .hom) (x .section) β‘ z .section
      comm =
        P.β (f .hom β g .hom) (x .section)       β‘β¨ happly (P.F-β (f .hom) (g .hom)) (x .section) β©
        P.β (f .hom) (P.β (g .hom) (x .section)) β‘β¨ ap (P.Fβ (f .hom)) (g .commute)  β©
        P.β (f .hom) (y .section)                β‘β¨ f .commute β©
        z .section β
β« .Precategory.idr f = Element-hom-path (idr (f .hom))
β« .Precategory.idl f = Element-hom-path (idl (f .hom))
β« .Precategory.assoc f g h = Element-hom-path (assoc (f .hom) (g .hom) (h .hom))
Οβ : Functor β« C
Οβ .Fβ x = x .ob
Οβ .Fβ f = f .hom
Οβ .F-id = refl
Οβ .F-β f g = reflWe can now relate the two constructions: the covariant category of elements of is the opposite of the contravariant category of elements of seen as a contravariant functor on (thus a functor ).
co-β« : β« β‘ Contra.β« (C ^op) P ^op
co-β« = Precategory-path F F-is-precat-iso where
  F : Functor β« (Contra.β« (C ^op) P ^op)
  F .Fβ e = Contra.elem (e .ob) (e .section)
  F .Fβ h = Contra.elem-hom (h .hom) (h .commute)
  F .F-id = refl
  F .F-β _ _ = Contra.Element-hom-path _ _ refl
  F-is-precat-iso : is-precat-iso F
  F-is-precat-iso .is-precat-iso.has-is-iso = is-isoβis-equiv Ξ» where
    .is-iso.inv e β elem (e .Contra.Element.ob) (e .Contra.Element.section)
    .is-iso.rinv e β refl
    .is-iso.linv e β refl
  F-is-precat-iso .is-precat-iso.has-is-ff = is-isoβis-equiv Ξ» where
    .is-iso.inv h β elem-hom (h .Contra.Element-hom.hom) (h .Contra.Element-hom.commute)
    .is-iso.rinv h β Contra.Element-hom-path _ _ refl
    .is-iso.linv h β Element-hom-path refl