module Cat.Displayed.Base where

Displayed categoriesπŸ”—

Note

This section presents motivation for, and a conceptual introduction to, displayed categories. If you are already familiar with the idea, click here to skip ahead to the formalised definition.

Any functor can be thought of as decomposing the precategory into a family of categories indexed by the objects 1 where the objects of should be those objects of sent to by , in a situation analogous to how functions decompose their domain as a sum, namely of the fibres of over the points of

Indeed, a literal approach to this decomposition would define the type of objects of to be exactly the type-theoretic fibre In our setting, this interpretation is problematic for two complementary reasons. First, if is an arbitrary precategory, the path types of its type of objects should be regarded as a vestigial structure left over from the encoding of category theory into type theory, and not as an intrinsic property of the category.

This objection is addressed by considering only functors into univalent categories, which are precisely those where identity of objects corresponds coherently to isomorphism in the category. However, even when studying univalent categories, the non-univalent constructions of diagram shapes like the walking isomorphism are often more convenient to formalise with than their univalent versions.2

If we insist on talking about fibres, we might instead work with Street fibrations, or, in greater generality, an equivalent weakening of the notion of isofibration. Talking about essential fibres would be independent of the path types of a presentation of a given category, so our first objection is addressed. However, even this definition has a critical flaw, which is actually common to any definition based on fibres: it is extremely inconvenient to work with in intensional type theory.

For example, the action of on morphisms has type-theoretic fibres only over maps so that if we have objects and to talk about maps lying over we must instead consider the fibres of the map where the elided term in the second map makes explicit reference to the identifications resp. witnessing that lies over (resp. over Any construction on an object lying over must regard the manner through which and were identified, regardless of whether this is a path or an isomorphism.

The gist of these two objections is that, even if we work with a suitably natural weakening of the fibres of the result is still impractical to formalise with. We would prefer to work with a notion of β€œdependent category” that is as convenient as the native notion of dependent type. Moving from fibrations to families prioritises the decomposition of over by making the notion of being defined over primitive.

A displayed category is an equivalent representation of the pair with one direction of the equivalence being the construction of total categories and the other being that of free isofibrations. Unlike starting with functors, displayed categories bake in the indexing by objects in the base category, so that β€œan object over an object ” is an atomic notion, needing no witness. Both the construction and study of displayed categories is often simpler than working with functors:

  • Every category3 whose objects are described in natural language as β€œan object of equipped with such-and-such structure”, and whose maps are β€œsuch-and-such preserving maps”, is naturally a displayed category, where the type of objects over is the type of β€œsuch-and-such structures” with carrier

    A fibre category of over has, as its type of objects, precisely the type of structures with carrier if we instead considered as a category-functor pair, the objects of would consist of nested triples where is a structure with carrier and

    Many properties of the forgetful functor, like being faithful, fully faithful, or amnestic, become simpler when phrased as properties of its generating displayed category. For example, it is faithful when each Hom[_] is a proposition, and amnestic when is displayed univalent.

The definitionπŸ”—

Fixing a category to serve as the base category, the data of a displayed category (over , written consists of

  • A type of objects over , for each
  • A set of morphisms (from to over for each map and objects
  • Identity morphisms id', assigning a to each and
  • A composition operation _∘'_, assigning to each

These must satisfy dependent analogues of the identity (idl', idr') and associativity (assoc') laws for a category, defined over the corresponding laws in

record Displayed (B : Precategory o β„“) o' β„“' : Type (lvl B o' β„“') where

A displayed category is specified in terms of a family Ob[_] of objects, indexed by those of we write for the value of the family at and if we may write if is understood. We then have a family of sets Hom[_], indexed by a map and objects and we write for its values.

  field
    Ob[_]  : ⌞ B ⌟ β†’ Type o'
    Hom[_] : βˆ€ {x y} β†’ Hom x y β†’ Ob[ x ] β†’ Ob[ y ] β†’ Type β„“'

A displayed category is also equipped with the algebraic operations of a category β€” identity and composition β€” where each is indexed by its corresponding operations in That is to say, the β€œidentity over”, id', is a map and, given composable and their β€œcomposite over”, _∘'_, lives in

    id' : βˆ€ {a} {x : Ob[ a ]} β†’ Hom[ id ] x x
    _∘'_
      : βˆ€ {a b c x y z} {f : Hom b c} {g : Hom a b}
      β†’ Hom[ f ] y z β†’ Hom[ g ] x y β†’ Hom[ f ∘ g ] x z

These operations are required to satisfy the laws analogous to those of a category. However, considering (e.g.) the left identity law, we run into a problem when stating them as equations: The composite is displayed over a map that is not definitionally equal to but only identical to it by a law of the base category. Therefore, the laws of a displayed category must be dependent on the corresponding laws in We introduce the notation _≑[_]_, which will be written when necessary, to compare maps and over an identification

  _≑[_]_
    : βˆ€ {a b x y} {f g : Hom a b} β†’ Hom[ f ] x y β†’ f ≑ g β†’ Hom[ g ] x y β†’ Type β„“'
  _≑[_]_ {a} {b} {x} {y} f' p g' = PathP (Ξ» i β†’ Hom[ p i ] x y) f' g'

This makes it straightforward to write down the three laws, though they remain quite wordy.

  field
    idr' : βˆ€ {a b x y} {f : Hom a b} (f' : Hom[ f ] x y) β†’ f' ∘' id' ≑[ idr f ] f'
    idl' : βˆ€ {a b x y} {f : Hom a b} (f' : Hom[ f ] x y) β†’ id' ∘' f' ≑[ idl f ] f'
    assoc'
      : βˆ€ {a b c d w x y z} {f : Hom c d} {g : Hom b c} {h : Hom a b}
      β†’ (f' : Hom[ f ] y z) (g' : Hom[ g ] x y) (h' : Hom[ h ] w x)
      β†’ f' ∘' (g' ∘' h') ≑[ assoc f g h ] ((f' ∘' g') ∘' h')

Finally, we can equip displayed categories with a distinguished transport operation for moving displayed morphisms between equal bases. While in general there may be many such, we can pair the β€œhomwise transport” hom[_] operation with a coherence datum coh[_], and this pair inhabits a contractible type (a centre of contraction being the native subst operation, paired with its filler). Therefore, these fields do not affect the β€œhomotopy type” of Displayed.

Their purpose is strictly as an aid in mechanisation: often (e.g.Β in the fundamental fibration the type consists of some β€œrelevant” data together with some β€œirrelevant” propositions, and, importantly, only the propositions mention the base morphism . This means that a β€œbespoke” hom[_] implementation can then choose to leave the data fields definitionally unchanged, whereas the native subst would surround them with reflexive transports.

Counterintuitively, this extra field actually increases reusability, despite nominally increasing the amount of data that goes into a displayed category: If another construction needs to transport morphisms in to work, e.g.Β the pullback fibration for sconing or Artin gluing, or fibre categories of subobjects, dealing with the leftover substs that arise in (e.g.) composition of morphisms can be quite annoying, and while cleaning them up can be automated, using the β€œbespoke” transport avoids introducing them in the first place.

  field
    hom[_]
      : βˆ€ {a b x y} {f g : Hom a b} (p : f ≑ g) (f' : Hom[ f ] x y)
      β†’ Hom[ g ] x y
    coh[_]
      : βˆ€ {a b x y} {f g : Hom a b} (p : f ≑ g) (f' : Hom[ f ] x y)
      β†’ f' ≑[ p ] hom[ p ] f'

Developer documentationπŸ”—

\ Warning

This section serves to document constructs derived from the definition of displayed categories that aid in the formalisation, and not necessarily interesting mathematical concepts.

Operators for composing paths-overπŸ”—

Since Mikan often struggles to infer the arguments to the generic displayed composition operator _βˆ™P_ in the setting of displayed categories, we provide variants which specify that the dependency is only on paths in the base category. One variant (βˆ™[-]-syntax) takes the path over which the left argument is displayed explicitly, and the other _βˆ™[]_ does this implicitly.

  βˆ™[-]-syntax
    : (p : f ≑ g) {q : g ≑ h}
    β†’ f' ≑[ p ] g' β†’ g' ≑[ q ] h' β†’ f' ≑[ p βˆ™ q ] h'
  βˆ™[-]-syntax p p' q' = _βˆ™P_ {B = Ξ» f β†’ Hom[ f ] _ _} p' q'

  syntax βˆ™[-]-syntax p p' q' = p' βˆ™[ p ] q'
  _βˆ™[]_ : {p : f ≑ g} {q : g ≑ h} β†’ f' ≑[ p ] g' β†’ g' ≑[ q ] h' β†’ f' ≑[ p βˆ™ q ] h'
  _βˆ™[]_ p' q' = p' βˆ™[ _ ] q'

  infixr 30 _βˆ™[]_ βˆ™[-]-syntax

Equational reasoning in displayed categoriesπŸ”—

Unlike non-dependent path composition, which elaborates to terms whose size is linear in the number of steps, iterated composition of dependent paths has a quadratic overhead. This comes from the composition operator having to be quantified over the paths over which its arguments are dependent:

    _ : p' βˆ™[] q' βˆ™[] r' βˆ™[] s' ≑
      _βˆ™[]_      {p = p} {q = q βˆ™ r βˆ™ s} p'
        (_βˆ™[]_   {p = q} {q = r βˆ™ s}     q'
          (_βˆ™[]_ {p = r} {q = s}         r'
            s'))
    _ = refl

Predictably, this is quite bad for performance: any part of the proof assistant implementation which needs to traverse terms will spend time going through this information.

Surprisingly, we can alleviate this without having to alter the proof assistant implementation, by working instead with paths in the total space of as a family over We introduce an auxiliary type _βˆ«β‰‘_, from which we can project a path in either over the constructed path between the base maps, or (because are sets) over an arbitrary path in the base.

  _βˆ«β‰‘_ : Hom[ f ] x y β†’ Hom[ g ] x y β†’ Type _
  f' βˆ«β‰‘ g' = Path (Ξ£ (Hom _ _) Ξ» f β†’ Hom[ f ] _ _) (_ , f') (_ , g')

  begin_ : (p : f' βˆ«β‰‘ g') β†’ f' ≑[ ap fst p ] g'
  begin_ = ap snd

  begin[]_ : f' βˆ«β‰‘ g' β†’ f' ≑[ p ] g'
  begin[]_ {f' = f'} {g' = g'} p = subst (f' ≑[_] g') prop! (ap snd p)

  infix 1 begin_ begin[]_

We can then provide combinators for composing a path in the total space with an ordinary dependent path, with variants for explicitly specifying the base path and for inverting the path to be composed.

  ≑[-]⟨⟩-syntax
    : (f' : Hom[ f ] x y) (p : f ≑ g) β†’ g' βˆ«β‰‘ h' β†’ f' ≑[ p ] g' β†’ f' βˆ«β‰‘ h'
  ≑[-]⟨⟩-syntax f' p q' p' = apβ‚‚ _,_ (p βˆ™ ap fst q') (p' βˆ™[] ap snd q')

  ≑[]⟨⟩-syntax : (f' : Hom[ f ] x y) β†’ g' βˆ«β‰‘ h' β†’ f' ≑[ p ] g' β†’ f' βˆ«β‰‘ h'
  ≑[]⟨⟩-syntax {p = p} f' q' p' = f' ≑[ _ ]⟨ p' ⟩] q'

  ≑[]˘⟨⟩-syntax : (f' : Hom[ f ] x y) β†’ g' βˆ«β‰‘ h' β†’ g' ≑[ p ] f' β†’ f' βˆ«β‰‘ h'
  ≑[]˘⟨⟩-syntax f' q' p' = f' ≑[]⟨ symP p' βŸ©β‰‘[] q'

  syntax ≑[-]⟨⟩-syntax f' p q' p' = f' ≑[ p ]⟨ p' ⟩ q'
  syntax ≑[]⟨⟩-syntax f' q' p' = f' ≑[]⟨ p' ⟩ q'
  syntax ≑[]˘⟨⟩-syntax f' q' p' = f' ≑[]˘⟨ p' ⟩ q'

  infixr 2 ≑[-]⟨⟩-syntax ≑[]⟨⟩-syntax ≑[]˘⟨⟩-syntax

Finally, for the final step, we must provide a slight variation on the reflexivity operator which pairs the given displayed map with its base.

  _∎[] : (f' : Hom[ f ] x y) β†’ f' βˆ«β‰‘ f'
  _∎[] _ = refl

  infix 3 _∎[]
record Trivially-graded {o β„“} (B : Precategory o β„“) (o' β„“' : Level) : Type (o βŠ” β„“ βŠ” lsuc o' βŠ” lsuc β„“') where
  open Precategory B
  field
    Ob[_]  : Ob β†’ Type o'
    Hom[_] : βˆ€ {x y} β†’ Hom x y β†’ Ob[ x ] β†’ Ob[ y ] β†’ Type β„“'

    instance
      ⦃ H-Level-Hom[_] ⦄
        : βˆ€ {a b} {f : Hom a b} {x : Ob[ a ]} {y : Ob[ b ]}
        β†’ H-Level (Hom[ f ] x y) 2

    id'  : βˆ€ {a} {x : Ob[ a ]} β†’ Hom[ id ] x x
    _∘'_ : βˆ€ {a b c x y z} {f : Hom b c} {g : Hom a b}
         β†’ Hom[ f ] y z β†’ Hom[ g ] x y β†’ Hom[ f ∘ g ] x z

  infixr 40 _∘'_

  _≑[_]_ : βˆ€ {a b x y} {f g : Hom a b} β†’ Hom[ f ] x y β†’ f ≑ g β†’ Hom[ g ] x y β†’ Type β„“'
  _≑[_]_ {a} {b} {x} {y} f' p g' = PathP (Ξ» i β†’ Hom[ p i ] x y) f' g'

  infix 30 _≑[_]_
  field
    idr' : βˆ€ {a b x y} {f : Hom a b} (f' : Hom[ f ] x y) β†’ (f' ∘' id') ≑[ idr f ] f'
    idl' : βˆ€ {a b x y} {f : Hom a b} (f' : Hom[ f ] x y) β†’ (id' ∘' f') ≑[ idl f ] f'
    assoc'
      : βˆ€ {a b c d w x y z} {f : Hom c d} {g : Hom b c} {h : Hom a b}
      β†’ (f' : Hom[ f ] y z) (g' : Hom[ g ] x y) (h' : Hom[ h ] w x)
      β†’ f' ∘' (g' ∘' h') ≑[ assoc f g h ] ((f' ∘' g') ∘' h')

{-# INLINE Displayed.constructor #-}

record Thinly-displayed {o β„“} (B : Precategory o β„“) (o' β„“' : Level) : Type (o βŠ” β„“ βŠ” lsuc o' βŠ” lsuc β„“') where
  open Precategory B
  field
    Ob[_]  : Ob β†’ Type o'
    Hom[_] : βˆ€ {x y} β†’ Hom x y β†’ Ob[ x ] β†’ Ob[ y ] β†’ Type β„“'

    instance
      ⦃ H-Level-Hom[_] ⦄
        : βˆ€ {a b} {f : Hom a b} {x : Ob[ a ]} {y : Ob[ b ]}
        β†’ H-Level (Hom[ f ] x y) 1

    id'  : βˆ€ {a} {x : Ob[ a ]} β†’ Hom[ id ] x x
    _∘'_ : βˆ€ {a b c x y z} {f : Hom b c} {g : Hom a b}
         β†’ Hom[ f ] y z β†’ Hom[ g ] x y β†’ Hom[ f ∘ g ] x z

Constructing displayed categoriesπŸ”—

We provide helpers for constructing displayed categories in two common cases.

The with-trivial-grading helper fills in the grading fields, hom[_] and coh[_], with their canonical implementations in terms of transport.

with-trivial-grading
  : βˆ€ {o β„“} {B : Precategory o β„“} {o' β„“' : Level} β†’ Trivially-graded B o' β„“'
  β†’ Displayed B o' β„“'
{-# INLINE with-trivial-grading #-}
with-trivial-grading triv = record
  { Trivially-graded triv
  ; Hom[_]-set = Ξ» f x y β†’ hlevel 2
  ; hom[_]     = subst (Ξ» e β†’ Hom[ e ] _ _)
  ; coh[_]     = Ξ» p β†’ transport-filler _
  }
  where open Trivially-graded triv using (Hom[_] ; H-Level-Hom[_])

The with-thin-display helper additionally automatically derives the displayed category laws from a mechanical proof that the given Hom[_] family is propositional.

with-thin-display
  : βˆ€ {o β„“} {B : Precategory o β„“} {o' β„“' : Level} β†’ Thinly-displayed B o' β„“'
  β†’ Displayed B o' β„“'
{-# INLINE with-thin-display #-}
with-thin-display triv = with-trivial-grading record where
  open Thinly-displayed triv
    using (Ob[_] ; Hom[_] ; id' ; _∘'_) renaming (H-Level-Hom[_] to i)
  H-Level-Hom[_] = basic-instance 2 $ is-prop→is-set (hlevel 1)
  idr'   f     = prop!
  idl'   f     = prop!
  assoc' f g h = prop!

  1. This idea is formalised in the page on free isofibrations.β†©οΈŽ

  2. To wit: the Rezk completion of the walking isomorphism is the terminal category.

    While it is still true that the category of functors is equivalent to the category of isomorphisms in sending an isomorphism along this equivalence results in

    If the equivalence is instead constructed in terms of the non-univalent construction of passing an isomorphism along in either direction is definitionally the identity.β†©οΈŽ

  3. Examples include the category of groups, monoids, rings, modules over a ring, and more generally every concrete category; but also examples not over e.g.Β algebras over a monad on arbitrary β†©οΈŽ