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

import Cat.Displayed.Reasoning as Dr
import Cat.Displayed.Solver as Ds

module Cat.Displayed.Fibre
{o ℓ o′ ℓ′} {B : Precategory o ℓ}
(E : Displayed B o′ ℓ′)
where

open Precategory B
open Displayed E
open Ds
open Dr E


## Fibre categories🔗

A displayed category can be thought of as representing data of a “family of categories”1. Given an object $x : \mathcal{B}$ of the base category, the morphisms in the fibre over x, or vertical morphisms, are those in the set $\mathbf{Hom}_{\operatorname{id}_{x}}(x, y)$ of morphisms over the identity map (on $x$).

The intuition from the term vertical comes from literally thinking of a category $E$ displayed over $\mathcal{B}$ as being a like a grab-bag of categories, admitting a map into $\mathcal{B}$ (the total category perspective), a situation examplified by the diagram below. Here, $\int E$ is the total space of a category $E$ displayed over $\mathcal{B}$, and $\pi$ is the corresponding projection functor.  In this diagram, the map $g$, which is displayed over the identity on $a$, is literally… vertical! A map such as $h$, between objects in two different fibres (hence displayed over a non-identity map $f$), is not drawn vertically. Additionally, the unwritten (displayed) identity morphisms on $a$, $b$, $c$, and $d$ are all vertical.

This last observation, coupled with the equation $\operatorname{id}_{}\circ\operatorname{id}_{}=\operatorname{id}_{}$ from the base category, implies that the set of vertical arrows over an object $x$ contain identities and are closed under composition, the fibre (pre)category over $x$.

Fibre′
: (X : Ob)
→ (fix : {x y : Ob[ X ]} → Hom[ id ∘ id ] x y → Hom[ id ] x y)
→ (coh : ∀ {x y} (f : Hom[ id ∘ id ] x y) → fix f ≡ hom[ idl id ] f)
→ Precategory _ _
Fibre′ X fix coh .Precategory.Ob = Ob[ X ]
Fibre′ X fix coh .Precategory.Hom = Hom[ id ]
Fibre′ X fix coh .Precategory.Hom-set = Hom[ id ]-set
Fibre′ X fix coh .Precategory.id = id′
Fibre′ X fix coh .Precategory._∘_ f g = fix (f ∘′ g)


The definition of Fibre′ has an extra degree of freedom: it is parametrised over how to reindex a morphism from lying over $\operatorname{id}_{} \circ \operatorname{id}_{}$ to lying over $\operatorname{id}_{}$. You don’t get that much freedom, however: there is a canonical way of doing this reindexing, which is to transport the composite morphism (since $\operatorname{id}_{} \circ \operatorname{id}_{}$ is equal to $\operatorname{id}_{}$), and the provided method must be homotopic to this canonical one — to guarantee that the resulting construction is a precategory.

It may seem that this extra freedom serves no purpose, then, but there are cases where it’s possible to transport without actually transporting: For example, if $\mathcal{E}$ is displayed over $\mathbf{Sets}$, then composition of morphisms is definitionally unital, so transporting is redundant; but without regularity, the transports along reflexivity would still pile up.

Fibre′ X fix coh .Precategory.idr f =
fix (f ∘′ id′)           ≡⟨ coh (f ∘′ id′) ⟩≡
hom[ idl id ] (f ∘′ id′) ≡⟨ Ds.disp! E ⟩≡
f                        ∎
Fibre′ X fix coh .Precategory.idl f =
fix (id′ ∘′ f)           ≡⟨ coh (id′ ∘′ f) ⟩≡
hom[ idl id ] (id′ ∘′ f) ≡⟨ from-pathp (idl′ f) ⟩≡
f                        ∎
Fibre′ X fix coh .Precategory.assoc f g h =
fix (f ∘′ fix (g ∘′ h))                     ≡⟨ ap (λ e → fix (f ∘′ e)) (coh _) ∙ coh _ ⟩≡
hom[ idl id ] (f ∘′ hom[ idl id ] (g ∘′ h)) ≡⟨ Ds.disp! E ⟩≡
hom[ idl id ] (hom[ idl id ] (f ∘′ g) ∘′ h) ≡⟨ sym (coh _) ∙ ap (λ e → fix (e ∘′ h)) (sym (coh _)) ⟩≡
fix (fix (f ∘′ g) ∘′ h)                     ∎

Fibre : Ob → Precategory _ _
Fibre X = Fibre′ X _ (λ f → refl)


1. Though note that unless the displayed category is a Cartesian fibration, this “family” might not be functorially-indexed↩︎