open import Cat.Displayed.Base
open import Cat.Prelude

import Cat.Reasoning as CR

module Cat.Displayed.Instances.Slice {o β„“} (B : Precategory o β„“) where

open Displayed
open CR B

Slices as a Displayed CategoryπŸ”—

There is a canonical way of viewing any category as displayed over itself. Recall that the best way to think about displayed categories is adding extra structure over each of the objects of the base. Here, we only really have one natural choice of extra structure for objects: morphisms into that object!

record Slice (x : Ob) : Type (o βŠ” β„“) where
  constructor slice
  field
    over  : Ob
    index : Hom over x

open Slice

As a point of intuition: the name Slice should evoke the feeling of β€œslicing up” over. If we restrict ourselves to Set, we can view a map over β†’ x as a partition of over into x different fibres. In other words, this provides an x-indexed collection of sets. This view of viewing slices as means of indexing is a very fruitful one, and should be something that you keep in the back of your head.

Now, the morphisms:

record Slice-hom {x y} (f : Hom x y)
                (px : Slice x) (py : Slice y) : Type (o βŠ” β„“) where
  constructor slice-hom
  private
    module px = Slice px
    module py = Slice py
  field
    to     : Hom px.over py.over
    commute : f ∘ px.index ≑ py.index ∘ to

open Slice-hom

Going back to our intuition of β€œslices as a means of indexing,” a morphism of slices performs a sort of reindexing operation. The morphism in the base performs our re-indexing, and then we ensure that we have some morphism between the indexed collections that preserves indexing, relative to the re-indexing operation.

Slice LemmasπŸ”—

Before we show this thing is a displayed category, we need to prove some lemmas. These are extremely unenlightening, so the reader should feel free to skip these (and probably ought to!).

module _ {x y} {f g : Hom x y} {px : Slice x} {py : Slice y}
         {fβ€² : Slice-hom f px py} {gβ€² : Slice-hom g px py} where

Paths of slice morphisms are determined by paths between the base morphisms, and paths between the β€œupper” morphisms.

  Slice-pathp : (p : f ≑ g) β†’ (fβ€² .to ≑ gβ€² .to) β†’ PathP (Ξ» i β†’ Slice-hom (p i) px py) fβ€² gβ€²
  Slice-pathp p pβ€² i .to = pβ€² i
  Slice-pathp p pβ€² i .commute =
    is-prop→pathp
      (Ξ» i β†’ Hom-set _ _ (p i ∘ px .index) (py .index ∘ (pβ€² i)))
      (fβ€² .commute)
      (gβ€² .commute)
      i
module _ {x y} (f : Hom x y) (px : Slice x) (py : Slice y) where
  Slice-is-set : is-set (Slice-hom f px py)
  Slice-is-set = is-hlevel≃ 2 (Isoβ†’Equiv eqv e⁻¹) (hlevel 2)
    where open HLevel-instance

Pulling it all togetherπŸ”—

Now that we have all the ingredients, the proof that this is all a displayed category follows rather easily. It’s useful to reinforce what we’ve actually done here though! We can think of morphisms into some object x as β€œstructures on x,” and then commuting squares as β€œstructures over morphisms.”

Slices : Displayed B (o βŠ” β„“) (o βŠ” β„“)
Slices .Ob[_] = Slice
Slices .Hom[_] = Slice-hom
Slices .Hom[_]-set = Slice-is-set
Slices .idβ€² = slice-hom id id-comm-sym
Slices ._βˆ˜β€²_ {x = x} {y = y} {z = z} {f = f} {g = g} px py =
  slice-hom (px .to ∘ py .to) $
    (f ∘ g) ∘ x .index          β‰‘βŸ¨ pullr (py .commute) βŸ©β‰‘
    f ∘ (index y ∘ py .to)      β‰‘βŸ¨ extendl (px .commute) βŸ©β‰‘
    z .index ∘ (px .to ∘ py .to) ∎
Slices .idrβ€² {f = f} fβ€² = Slice-pathp (idr f) (idr (fβ€² .to))
Slices .idlβ€² {f = f} fβ€² = Slice-pathp (idl f) (idl (fβ€² .to))
Slices .assocβ€² {f = f} {g = g} {h = h} fβ€² gβ€² hβ€² =
  Slice-pathp (assoc f g h) (assoc (fβ€² .to) (gβ€² .to) (hβ€² .to))