module Cat.Displayed.Cartesian.Indexing {o β o' β'} {B : Precategory o β} (E : Displayed B o' β') (cartesian : Cartesian-fibration E) where
open Cartesian-fibration cartesian open Cat.Displayed.Reasoning E open Cat.Reasoning B open Cartesian-lift open Displayed E open is-cartesian open Functor private module Fib = Cat.Displayed.Fibre.Reasoning E _^*_ : β {a b} (f : Hom a b) β Ob[ b ] β Ob[ a ] f ^* x = has-lift.x' f x
Reindexing for cartesian fibrationsπ
A cartesian fibration can be thought of as a displayed category whose fibre categories depend (pseudo)functorially on the object from the base category. A canonical example is the canonical self-indexing: If is a category with pullbacks, then each gives rise to a functor the change of base along
module _ {πΆ π·} (f : Hom πΆ π·) where base-change : Functor (Fibre E π·) (Fibre E πΆ) base-change .Fβ ob = has-lift f ob .x' base-change .Fβ {x} {y} vert = rebase f vert
base-change .F-id {x} = sym $ has-lift.uniquep f x _ _ _ _ $ idr' _ β[] symP (idl' _) base-change .F-β {x} {y} {z} f' g' = sym $ has-lift.uniquep f z _ _ _ _ $ Fib.pulllf (has-lift.commutesp f z id-comm _) β[] pullr[] _ (has-lift.commutesp f y id-comm _) β[] pulll[] _ Fib.to-fibre
Moreover, this assignment is itself functorial in Along the identity morphism, itβs the same thing as not changing bases at all.
module _ {πΆ} where private module FC = Cat.Reasoning (Cat[ Fibre E πΆ , Fibre E πΆ ]) module Fa = Cat.Reasoning (Fibre E πΆ) base-change-id : base-change id FC.β Id
Iβll warn you in advance that this proof is not for the faint of heart.
base-change-id = to-natural-iso mi where open make-natural-iso mi : make-natural-iso (base-change id) Id mi .eta x = has-lift.lifting id x mi .inv x = has-lift.universalv id x id' mi .etaβinv x = cancel _ _ (has-lift.commutesv _ _ _) mi .invβeta x = sym $ has-lift.uniquepβ id x _ _ _ _ _ (idr' _) (Fib.cancellf (has-lift.commutesv _ _ _)) mi .natural x y f = sym $ from-pathp $ cast[] $ has-lift.commutesp id y id-comm _ β[] Fib.to-fibre
And similarly, composing changes of base is the same thing as changing base along a composite.
^*-id-to : β {x} β Hom[ id {πΆ} ] (id ^* x) x ^*-id-to = has-lift.lifting id _ ^*-id-from : β {x} β Hom[ id {πΆ} ] x (id ^* x) ^*-id-from = has-lift.universalv id _ id' ^*-comp-from : β {a b c} {z} {f : Hom b c} {g : Hom a b} β Hom[ id ] (g ^* (f ^* z)) ((f β g) ^* z) ^*-comp-from = has-lift.universalv _ _ (has-lift.lifting _ _ β' has-lift.lifting _ _) ^*-comp-to : β {a b c} {z} {f : Hom b c} {g : Hom a b} β Hom[ id ] ((f β g) ^* z) (g ^* (f ^* z)) ^*-comp-to = has-lift.universalv _ _ (has-lift.universal _ _ _ (has-lift.lifting _ _)) ^*-comp : β {a b c} {z} {f : Hom b c} {g : Hom a b} β ((f β g) ^* z) Fib.β (g ^* (f ^* z)) ^*-comp = Fib.make-iso ^*-comp-to ^*-comp-from (has-lift.uniquepβ _ _ _ _ _ _ _ (Fib.pulllf (has-lift.commutesv _ _ _) β[] has-lift.uniquepβ _ _ _ (idr _) refl _ _ (pulll[] _ (has-lift.commutes _ _ _ _) β[] has-lift.commutesv _ _ _) refl) (idr' _)) (has-lift.uniquepβ _ _ _ _ _ _ _ (Fib.pulllf (has-lift.commutesv _ _ _) β[] pullr[] _ (has-lift.commutesv _ _ _) β[] has-lift.commutes _ _ _ _) (idr' _)) ^*-comp-to-natural : β {a b c} {f : Hom b c} {g : Hom a b} {x y : Ob[ c ]} (f' : Hom[ id ] x y) β rebase g (rebase f f') Fib.β ^*-comp-to β‘ ^*-comp-to Fib.β rebase (f β g) f' ^*-comp-to-natural {f = f} {g = g} f' = ap hom[] $ cartesianβweak-monic E (has-lift.cartesian g _) _ _ $ cast[] $ pulll[] _ (has-lift.commutesp g _ id-comm _) β[] pullr[] _ (has-lift.commutesv g _ _) β[] has-lift.uniquepβ _ _ _ id-comm-sym _ _ _ (pulll[] _ (has-lift.commutesp _ _ id-comm _) β[] pullr[] _ (has-lift.commutes _ _ _ _)) (pulll[] _ (has-lift.commutes _ _ _ _) β[] has-lift.commutesp _ _ id-comm _) β[] pushl[] _ (symP (has-lift.commutesv g _ _))
module _ {πΆ} {π·} {πΈ} (f : Hom π· πΈ) (g : Hom πΆ π·) where private module FC = Cat.Reasoning (Cat[ Fibre E πΈ , Fibre E πΆ ]) module Fa = Cat.Reasoning (Fibre E πΆ) base-change-comp : base-change (f β g) FC.β (base-change g Fβ base-change f)
This proof is a truly nightmarish application of universal properties and I recommend that nobody look at it, ever.
.
base-change-comp = to-natural-iso mi where open make-natural-iso mi : make-natural-iso (base-change (f β g)) (base-change g Fβ base-change f) mi .eta x = ^*-comp-to mi .inv x = ^*-comp-from mi .etaβinv x = ^*-comp .Fib.invl mi .invβeta x = ^*-comp .Fib.invr mi .natural x y f' = ^*-comp-to-natural f'
In order to assemble this into a pseudofunctor out of (seen as a locally discrete bicategory) into we start by bundling up all the base changes into a functor between categories. We also prove a lemma that will be useful later, relating base changes along equal morphisms.
base-changes : β {a b} β Functor (Locally-discrete (B ^op) .Prebicategory.Hom a b) Cat[ Fibre E a , Fibre E b ] base-changes = Disc-adjunct base-change base-change-coherence : β {a b} {b' : Ob[ b ]} {f g : Hom a b} (p : f β‘ g) β has-lift.lifting g b' β' base-changes .Fβ p .Ξ· b' β‘[ idr _ β sym p ] has-lift.lifting f b' base-change-coherence {b' = b'} {f} = J (Ξ» g p β has-lift.lifting g b' β' base-changes .Fβ p .Ξ· b' β‘[ idr _ β sym p ] has-lift.lifting f b') (elimr' refl Regularity.reduce!)
We have enough data to start defining our pseudofunctor:
Fibres : Pseudofunctor (Locally-discrete (B ^op)) (Cat o' β') Fibres .lax .Pβ = Fibre E Fibres .lax .Pβ = base-changes Fibres .lax .compositor = Disc-naturalβ Ξ» (f , g) β base-change-comp g f .Mor.from Fibres .lax .unitor = base-change-id .Mor.from Fibres .unitor-inv = FC.isoβinvertible (base-change-id FC.Isoβ»ΒΉ) Fibres .compositor-inv f g = FC.isoβinvertible (base-change-comp g f FC.Isoβ»ΒΉ)
It remains to verify that this data is coherent, which is so tedious that it serves as a decent self-contained motivation for displayed categories.
Youβve been warned.
We start with the left-unit
. In the diagram below,
we have to show that the composite vertical morphism over
is equal to the identity over
By the uniqueness property of cartesian lifts, it suffices to show that
the composites with the lift of
are equal, which is witnessed by the commutativity of the whole
diagram.
The bottom triangle is our base-change-coherence
lemma,
the middle square is by definition of the compositor and the top
triangle is by definition of the unitor.
Fibres .lax .left-unit f = ext Ξ» a' β has-lift.uniquepβ f a' _ refl refl _ _ (Fib.pulllf (base-change-coherence (idr f)) β[] Fib.pulllf (has-lift.commutesv (f β id) a' _) β[] (reflβ©β'β¨ Fib.eliml (base-change id .F-id)) β[] pullr[] _ (has-lift.commutesv id _ id')) refl
For the right-unit
, we proceed similarly.
The diagram below shows that the composite on the left, composed with
the lift of
is equal to the lift of
The bottom triangle is base-change-coherence
, the
middle square is by definition of the compositor, the outer triangle is
by definition of the unitor, and the top square is by definition of
rebase
(the action of
on morphisms).
Fibres .lax .right-unit f = ext Ξ» a' β has-lift.uniquepβ f a' _ refl _ _ _ (Fib.pulllf (base-change-coherence (idl f)) β[] Fib.pulllf (has-lift.commutesv (id β f) a' _) β[] (reflβ©β'β¨ Fib.idr _) β[] extendr[] id-comm (has-lift.commutesp f _ _ _) β[] (has-lift.commutesv id _ id' β©β'β¨refl)) (idr' _ β[] symP (idl' _))
Last but definitely not least, the hexagon
witnessing the coherence
of associativity follows again by uniqueness of cartesian lifts, by the
commutativity of the following diagram.
Fibres .lax .hexagon f g h = ext Ξ» a' β has-lift.uniquepβ ((h β g) β f) a' _ refl _ _ _ (Fib.pulllf (base-change-coherence (assoc h g f)) β[] Fib.pulllf (has-lift.commutesv (h β (g β f)) a' _) β[] (reflβ©β'β¨ Fib.eliml (base-change (g β f) .F-id)) β[] extendr[] _ (has-lift.commutesv (g β f) _ _)) (Fib.pulllf (has-lift.commutesv ((h β g) β f) a' _) β[] (reflβ©β'β¨ Fib.idr _) β[] (reflβ©β'β¨ Fib.idr _) β[] extendr[] id-comm (has-lift.commutesp f _ _ _) β[] (has-lift.commutesv (h β g) a' _ β©β'β¨refl))
-- Optimized natural iso, avoids a bunch of junk from composition. opaque base-change-square : β {Ξ Ξ Ξ Ξ¨ : Ob} β {Ο : Hom Ξ Ξ} {Ξ΄ : Hom Ξ Ξ} {Ξ³ : Hom Ξ Ξ¨} {Ο : Hom Ξ Ξ¨} β Ξ³ β Ο β‘ Ο β Ξ΄ β β x' β Hom[ id ] (base-change Ο .Fβ (base-change Ξ³ .Fβ x')) (base-change Ξ΄ .Fβ (base-change Ο .Fβ x')) base-change-square {Ο = Ο} {Ξ΄ = Ξ΄} {Ξ³ = Ξ³} {Ο = Ο} p x' = has-lift.universalv Ξ΄ _ $ has-lift.universal' Ο _ (sym p) $ has-lift.lifting Ξ³ x' β' has-lift.lifting Ο _ base-change-square-lifting : β {Ξ Ξ Ξ Ξ¨ : Ob} β {Ο : Hom Ξ Ξ} {Ξ΄ : Hom Ξ Ξ} {Ξ³ : Hom Ξ Ξ¨} {Ο : Hom Ξ Ξ¨} β (p : Ξ³ β Ο β‘ Ο β Ξ΄) (x' : Ob[ Ξ¨ ]) β has-lift.lifting Ο x' β' has-lift.lifting Ξ΄ (base-change Ο .Fβ x') β' base-change-square p x' β‘[ ap (Ο β_) (idr _) β sym p ] has-lift.lifting Ξ³ x' β' has-lift.lifting Ο _ base-change-square-lifting {Ο = Ο} {Ξ΄ = Ξ΄} {Ξ³ = Ξ³} {Ο = Ο} p x' = cast[] $ apd (Ξ» _ β has-lift.lifting Ο x' β'_) (has-lift.commutesv _ _ _) β[] has-lift.commutesp Ο x' (sym p) _ base-change-square-natural : β {Ξ Ξ Ξ Ξ¨ : Ob} β {Ο : Hom Ξ Ξ} {Ξ΄ : Hom Ξ Ξ} {Ξ³ : Hom Ξ Ξ¨} {Ο : Hom Ξ Ξ¨} β (p : Ξ³ β Ο β‘ Ο β Ξ΄) β β {x' y'} (f' : Hom[ id ] x' y') β base-change-square p y' β' base-change Ο .Fβ (base-change Ξ³ .Fβ f') β‘ base-change Ξ΄ .Fβ (base-change Ο .Fβ f') β' base-change-square p x' base-change-square-natural {Ο = Ο} {Ξ΄ = Ξ΄} {Ξ³ = Ξ³} {Ο = Ο} p f' = has-lift.uniquepβ Ξ΄ _ _ _ _ _ _ (pulll[] _ (has-lift.commutesv Ξ΄ _ _) β[] has-lift.uniquepβ Ο _ _ (idr _) _ _ _ (pulll[] _ (has-lift.commutesp Ο _ (sym p) _) β[] pullr[] _ (has-lift.commutesp Ο _ id-comm _) β[] extendl[] _ (has-lift.commutesp Ξ³ _ id-comm _)) (has-lift.commutesp Ο _ (sym p β sym (idl _ )) _)) (pulll[] _ (has-lift.commutesp Ξ΄ _ id-comm _) β[] pullr[] _ (has-lift.commutesv Ξ΄ _ _) β[] has-lift.uniquep Ο _ _ (idl _) (sym p β sym (idl _)) _ (pulll[] _ (has-lift.commutesp _ _ id-comm _ ) β[] pullr[] _ (has-lift.commutesp _ _ (sym p) _))) base-change-square-inv : β {Ξ Ξ Ξ Ξ¨ : Ob} β {Ο : Hom Ξ Ξ} {Ξ΄ : Hom Ξ Ξ} {Ξ³ : Hom Ξ Ξ¨} {Ο : Hom Ξ Ξ¨} β (p : Ξ³ β Ο β‘ Ο β Ξ΄) β β x' β base-change-square p x' β' base-change-square (sym p) x' β‘[ idl _ ] id' base-change-square-inv {Ο = Ο} {Ξ΄ = Ξ΄} {Ξ³ = Ξ³} {Ο = Ο} p x' = has-lift.uniquepβ _ _ _ _ _ _ _ (pulll[] _ (has-lift.commutesv Ξ΄ _ _) β[] has-lift.uniquepβ Ο _ _ (idr _) refl _ _ (pulll[] _ (has-lift.commutesp Ο _ (sym p) _) β[] pullr[] _ (has-lift.commutesv Ο _ _) β[] has-lift.commutesp Ξ³ _ p _) refl) (idr' _) base-change-square-ni : β {Ξ Ξ Ξ Ξ¨ : Ob} β {Ο : Hom Ξ Ξ} {Ξ΄ : Hom Ξ Ξ} {Ξ³ : Hom Ξ Ξ¨} {Ο : Hom Ξ Ξ¨} β Ξ³ β Ο β‘ Ο β Ξ΄ β (base-change Ο Fβ base-change Ξ³) β βΏ (base-change Ξ΄ Fβ base-change Ο) base-change-square-ni {Ο = Ο} {Ξ΄ = Ξ΄} {Ξ³ = Ξ³} {Ο = Ο} p = to-natural-iso ni where open make-natural-iso ni : make-natural-iso _ _ ni .eta = base-change-square p ni .inv = base-change-square (sym p) ni .etaβinv x = from-pathp $ base-change-square-inv p x ni .invβeta x = from-pathp $ base-change-square-inv (sym p) x ni .natural x y f = sym $ Fib.over-fibre (base-change-square-natural p f)