module Cat.Displayed.Comprehension.Coproduct {ob βb od βd oe βe} {B : Precategory ob βb} {D : Displayed B od βd} {E : Displayed B oe βe} (D-fib : Cartesian-fibration D) (E-fib : Cartesian-fibration E) (P : Comprehension E) where
private open Cat.Reasoning B module E = Displayed E module D = Displayed D module Dβ {Ξ} = Cat.Reasoning (Fibre D Ξ) module Dr = Cat.Displayed.Reasoning D module D-fib {x y} (f : Hom x y) (y' : D.Ob[ y ]) = Cartesian-lift (Cartesian-fibration.has-lift D-fib f y') open Comprehension E E-fib P module D* {Ξ Ξ : Ob} (Ο : Hom Ξ Ξ) = Functor (base-change D D-fib Ο) module Ο* {Ξ : Ob} (x : E.Ob[ Ξ ]) = Functor (base-change D D-fib (ΟαΆ {x = x})) open Functor open _=>_
Coproducts in comprehension categoriesπ
Let be a comprehension category and a fibration over the same base. We say that has when:
For every and there exists an object
Every projection induces a cocartesian map
For every cubical diagram as below, if is cartesian in and are cartesian in and is cocartesian in then is cocartesian in
From a type-theoretic perspective, the first two conditions are rather straightforward. The first condition establishes that we have a type former that can quantify over objects of The second condition defines an introduction rule of the following form:
The elimination rule comes from each being cocartesian, as cocartesian maps satisfy a mapping-out universal property, exactly like a coproduct should!
However, at a glance, the last condition is somewhat mysterious. It says that cocartesian maps over projections are stable: but what does that have to do with coproducts? This, like many other questions in category theory, is elucidated by thinking type-theoretically: A cartesian map in a comprehension category is essentially a substitution: the stability condition says that the introduction rule for coproducts is actually type-theoretic: stable under substitution.
record has-comprehension-coproducts : Type (ob β βb β od β βd β oe β βe) where no-eta-equality field β : β {Ξ} β (x : E.Ob[ Ξ ]) (a : D.Ob[ Ξ β¨Ύ x ]) β D.Ob[ Ξ ] β¨_,_β© : β {Ξ} β (x : E.Ob[ Ξ ]) (a : D.Ob[ Ξ β¨Ύ x ]) β D.Hom[ ΟαΆ ] a (β x a) β¨β©-cocartesian : β {Ξ} β (x : E.Ob[ Ξ ]) (a : D.Ob[ Ξ β¨Ύ x ]) β is-cocartesian D ΟαΆ β¨ x , a β© cocartesian-stable : β {Ξ Ξ x y a a' b b'} {Ο : Hom Ξ Ξ} {f : E.Hom[ Ο ] x y} β {r : D.Hom[ ΟαΆ ] a a'} {h : D.Hom[ Ο ] a' b'} β {g : D.Hom[ Ο β¨ΎΛ’ f ] a b} {s : D.Hom[ ΟαΆ ] b b'} β is-cartesian E Ο f β s D.β' g D.β‘[ sub-proj f ] h D.β' r β is-cocartesian D ΟαΆ s β is-cartesian D (Ο β¨ΎΛ’ f) g β is-cartesian D Ο h β is-cocartesian D ΟαΆ r module β¨β©-cocartesian {Ξ} (x : E.Ob[ Ξ ]) (a : D.Ob[ Ξ β¨Ύ x ]) = is-cocartesian (β¨β©-cocartesian x a)
Now, some general facts about coproducts. To start, note that forming coproducts is a functorial operation. The proof is very routine β if youβve seen one functoriality argument, youβve seen them all β so weβve hidden it from the page.1
opaque β[_] : β {Ξ} {x : E.Ob[ Ξ ]} {a b : D.Ob[ Ξ β¨Ύ x ]} β D.Hom[ id ] a b β D.Hom[ id ] (β x a) (β x b) β[_] {Ξ} {x} {a} {b} f = β¨β©-cocartesian.universal' x a id-comm-sym (β¨ x , b β© D.β' f) β[]-id : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} β β[ D.id' {x = a} ] β‘ D.id' β[]-β : β {Ξ} {x : E.Ob[ Ξ ]} {a b c : D.Ob[ Ξ β¨Ύ x ]} β (f : D.Hom[ id ] b c) (g : D.Hom[ id ] a b) β β[ f Dβ.β g ] D.β‘[ sym (idl _) ] β[ f ] D.β' β[ g ]
β[]-natural : β {Ξ} {x : E.Ob[ Ξ ]} {a b : D.Ob[ Ξ β¨Ύ x ]} β (f : D.Hom[ id ] a b) β β[ f ] D.β' β¨ x , a β© D.β‘[ id-comm-sym ] β¨ x , b β© D.β' f β[]-natural {x = x} {a} {b} f = β¨β©-cocartesian.commutesp x a _ _ β[]-id {x = x} {a = a} = sym $ β¨β©-cocartesian.unique _ _ _ $ from-pathpβ» $ Dr.cast[] $ D.id' D.β' β¨ x , a β© D.β‘[]β¨ D.idl' _ β©D.β‘[] β¨ x , a β© D.β‘[]β¨ symP (D.idr' _ ) β©D.β‘[] β¨ x , a β© D.β' D.id' β β[]-β {x = x} {a = a} {b = b} {c = c} f g = symP $ β¨β©-cocartesian.uniquep x a _ _ _ _ $ (β[ f ] D.β' β[ g ]) D.β' β¨ x , a β© D.β‘[]β¨ Dr.pullr[] _ (β[]-natural g) β©D.β‘[] β[ f ] D.β' β¨ x , b β© D.β' g D.β‘[]β¨ Dr.extendl[] _ (β[]-natural f) β©D.β‘[] β¨ x , c β© D.β' f D.β' g D.β‘[]β¨ to-pathp (Dr.unwhisker-r (ap (ΟαΆ β_) (idl _)) (idl _)) β©D.β‘[] β¨ x , c β© D.β' (f Dβ.β g) β
We can also re-package the cocartesianness of to give a method for constructing morphisms given morphisms Type theoretically, this gives a much more familiar presentation of the elimination rule.
opaque β-elim : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} {b : D.Ob[ Ξ ]} β D.Hom[ id ] a (Ο*.Fβ x b) β D.Hom[ id ] (β x a) b β-elim {x = x} {a = a} {b = b} f = β¨β©-cocartesian.universal' x a id-comm-sym (D-fib.lifting ΟαΆ b D.β' f) β-elim-Ξ² : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} {b : D.Ob[ Ξ ]} β (f : D.Hom[ id ] a (Ο*.Fβ x b)) β β-elim f D.β' β¨ x , a β© D.β‘[ id-comm-sym ] D-fib.lifting ΟαΆ b D.β' f β-elim-Ξ² f = β¨β©-cocartesian.commutesp _ _ _ _
Putting on our type-theorist goggles, weβre still missing one thing to call this a proper elimination rule: stability under substitution. In the categorical world, thatβs satisfied by the proof that the operation we just constructed is natural, given below.
β-elim-natural : β {Ξ} {x : E.Ob[ Ξ ]} {a b : D.Ob[ Ξ β¨Ύ x ]} {c : D.Ob[ Ξ ]} β (f : D.Hom[ id ] b (Ο*.β x c)) (g : D.Hom[ id ] a b) β β-elim f D.β' β[ g ] D.β‘[ idl _ ] β-elim (f Dβ.β g) β-elim-natural {x = x} {a = a} {b = b} {c = c} f g = β¨β©-cocartesian.uniquep x a _ _ _ (β-elim f D.β' β[ g ]) $ ((β-elim f) D.β' β[ g ]) D.β' β¨ x , a β© D.β‘[]β¨ Dr.pullr[] _ (β[]-natural g) β©D.β‘[] β-elim f D.β' β¨ x , b β© D.β' g D.β‘[]β¨ Dr.extendl[] id-comm-sym (β¨β©-cocartesian.commutesp x b _ _) β©D.β‘[] D-fib.lifting ΟαΆ c D.β' f D.β' g D.β‘[]β¨ to-pathp (Dr.unwhisker-r (ap (ΟαΆ β_) (idl _)) (idl _)) β©D.β‘[] D-fib.lifting ΟαΆ c D.β' Dr.hom[] (f D.β' g) β
Conversely, we can make maps given maps This isnβt quite, type-theoretically, as the elimination principle: itβs a weird mash-up of the introduction rule for coproducts, followed by substitution.
opaque β-transpose : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} {b : D.Ob[ Ξ ]} β D.Hom[ id ] (β x a) b β D.Hom[ id ] a (Ο*.β x b) β-transpose {x = x} {a = a} {b = b} f = D-fib.universal' ΟαΆ b id-comm (f D.β' β¨ x , a β©)
opaque unfolding β-transpose β-transpose-weaken : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} {b : D.Ob[ Ξ ]} β (f : D.Hom[ id ] (β x a) b) β D-fib.lifting ΟαΆ b D.β' β-transpose f D.β‘[ id-comm ] f D.β' β¨ x , a β© β-transpose-weaken f = D-fib.commutesp ΟαΆ _ id-comm _
While β-transpose
may not play an
obvious type-theoretic role, it is extremely important categorically,
since it is an inverse of β-elim
! Moreover, itβs
also natural, but that proof is also hidden from the page for
brevity.
opaque unfolding β-elim β-transpose β-elim-transpose : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} {b : D.Ob[ Ξ ]} β (f : D.Hom[ id ] (β x a) b) β β-elim (β-transpose f) β‘ f β-elim-transpose {x = x} {a = a} {b = b} f = sym $ β¨β©-cocartesian.uniquep x a _ _ _ f $ symP $ D-fib.commutesp ΟαΆ b id-comm (f D.β' β¨ x , a β©) β-transpose-elim : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} {b : D.Ob[ Ξ ]} β (f : D.Hom[ id ] a (Ο*.Fβ x b)) β β-transpose (β-elim f) β‘ f β-transpose-elim {x = x} {a = a} {b = b} f = sym $ D-fib.uniquep ΟαΆ b _ _ _ f $ symP $ β¨β©-cocartesian.commutesp x a id-comm-sym (D-fib.lifting ΟαΆ b D.β' f)
β-transpose-equiv : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} {b : D.Ob[ Ξ ]} β is-equiv (β-transpose {a = a} {b = b}) β-transpose-equiv = is-isoβis-equiv $ iso β-elim β-transpose-elim β-elim-transpose opaque unfolding β-transpose β-transpose-naturall : β {Ξ} {x : E.Ob[ Ξ ]} {a b : D.Ob[ Ξ β¨Ύ x ]} {c : D.Ob[ Ξ ]} β (f : D.Hom[ id ] (β x b) c) (g : D.Hom[ id ] a b) β β-transpose f D.β' g D.β‘[ idl _ ] β-transpose (f Dβ.β β[ g ]) β-transpose-naturall {x = x} {a = a} {b = b} {c = c} f g = D-fib.uniquep ΟαΆ c _ _ _ (β-transpose f D.β' g) $ D-fib.lifting ΟαΆ c D.β' β-transpose f D.β' g D.β‘[]β¨ Dr.pulll[] id-comm (D-fib.commutesp ΟαΆ c _ _) β©D.β‘[] (f D.β' β¨ x , b β©) D.β' g D.β‘[]β¨ Dr.extendr[] _ (symP (β[]-natural g)) β©D.β‘[] (f D.β' β[ g ]) D.β' β¨ x , a β© D.β‘[ ap (_β ΟαΆ) (idl _) ]β¨ to-pathp (Dr.unwhisker-l (ap (_β ΟαΆ) (idl _)) (idl _)) β©] (f Dβ.β β[ g ]) D.β' β¨ x , a β© β β-transpose-naturalr : β {Ξ} {x : E.Ob[ Ξ ]} {a : D.Ob[ Ξ β¨Ύ x ]} {b c : D.Ob[ Ξ ]} β (f : D.Hom[ id ] b c) (g : D.Hom[ id ] (β x a) b) β Ο*.β x f D.β' β-transpose g D.β‘[ idl _ ] β-transpose (f Dβ.β g) β-transpose-naturalr {x = x} {a = a} {b = b} {c = c} f g = D-fib.uniquep ΟαΆ c _ _ _ (Ο*.Fβ x f D.β' β-transpose g) $ D-fib.lifting ΟαΆ c D.β' Ο*.β x f D.β' β-transpose g D.β‘[]β¨ Dr.pulll[] _ (D-fib.commutesp ΟαΆ c id-comm _) β©D.β‘[] (f D.β' D-fib.lifting ΟαΆ b) D.β' β-transpose g D.β‘[]β¨ Dr.extendr[] id-comm (D-fib.commutesp ΟαΆ b _ _) β©D.β‘[] (f D.β' g) D.β' β¨ x , a β© D.β‘[ ap (_β ΟαΆ) (idl _) ]β¨ to-pathp (Dr.unwhisker-l (ap (_β ΟαΆ) (idl _)) (idl _)) β©] Dr.hom[ idl id ] (f D.β' g) D.β' β¨ x , a β© β
Next, we define an introduction rule for coproducts that also lets us apply a mediating substitution:
opaque β¨_β¨Ύ_β© : β {Ξ Ξ x y} {Ο : Hom Ξ Ξ} β (f : E.Hom[ Ο ] x y) (a : D.Ob[ Ξ β¨Ύ y ]) β D.Hom[ ΟαΆ ] (D*.β (Ο β¨ΎΛ’ f) a) (D*.β Ο (β y a)) β¨_β¨Ύ_β© {x = x} {y = y} {Ο = Ο} f a = D-fib.universal' Ο (β y a) (sym (sub-proj f)) $ β¨ y , a β© D.β' D-fib.lifting (Ο β¨ΎΛ’ f) a β¨β¨Ύβ©-weaken : β {Ξ Ξ x y} {Ο : Hom Ξ Ξ} β (f : E.Hom[ Ο ] x y) (a : D.Ob[ Ξ β¨Ύ y ]) β D-fib.lifting Ο (β y a) D.β' β¨ f β¨Ύ a β© D.β‘[ sym (sub-proj f) ] β¨ y , a β© D.β' D-fib.lifting (Ο β¨ΎΛ’ f) a β¨β¨Ύβ©-weaken {y = y} {Ο = Ο} f a = D-fib.commutesp Ο (β y a) (symP (sub-proj f)) _
Because we have assumed that cocartesian maps are stable when pulled back along cartesian maps over projections2, this map is also cocartesian β and, you guessed it β the spiced-up introduction rule is also natural.
opaque β¨β¨Ύβ©-cocartesian : β {Ξ Ξ x y} {Ο : Hom Ξ Ξ} β {f : E.Hom[ Ο ] x y} β is-cartesian E Ο f β (a : D.Ob[ Ξ β¨Ύ y ]) β is-cocartesian D ΟαΆ β¨ f β¨Ύ a β© β¨β¨Ύβ©-cocartesian {x = x} {y = y} {Ο = Ο} {f = f} cart a = cocartesian-stable cart (symP (β¨β¨Ύβ©-weaken f a)) (β¨β©-cocartesian y a) (D-fib.cartesian (Ο β¨ΎΛ’ f) a) (D-fib.cartesian Ο (β y a)) module β¨β¨Ύβ©-cocartesian {Ξ Ξ x y} {Ο : Hom Ξ Ξ} {f : E.Hom[ Ο ] x y} (cart : is-cartesian E Ο f) (a : D.Ob[ Ξ β¨Ύ y ]) = is-cocartesian (β¨β¨Ύβ©-cocartesian cart a)
opaque unfolding β¨_β¨Ύ_β© β¨β¨Ύβ©-natural : β {Ξ Ξ x y} {Ο : Hom Ξ Ξ} β {a b : D.Ob[ Ξ β¨Ύ y ]} β (f : D.Hom[ id ] a b) (g : E.Hom[ Ο ] x y) β β¨ g β¨Ύ b β© D.β' D*.β (Ο β¨ΎΛ’ g) f D.β‘[ id-comm ] D*.β Ο β[ f ] D.β' β¨ g β¨Ύ a β© β¨β¨Ύβ©-natural {x = x} {y = y} {Ο = Ο} {a = a} {b = b} f g = D-fib.uniquepβ Ο (β y b) _ _ _ _ _ (Dr.pulll[] _ (D-fib.commutesp Ο (β y b) (sym (sub-proj g)) _) D.β[] Dr.pullr[] _ (D-fib.commutesp (Ο β¨ΎΛ’ g) b id-comm _)) (Dr.pulll[] _ (D-fib.commutesp Ο (β y b) id-comm _) D.β[] Dr.pullr[] _ (β¨β¨Ύβ©-weaken g a) D.β[] Dr.extendl[] _ (β[]-natural f))
This lets us extend a substitution into a substitution
opaque β-sub : β {Ξ Ξ x y} {Ο : Hom Ξ Ξ} {f : E.Hom[ Ο ] x y} β is-cartesian E Ο f β (a : D.Ob[ Ξ β¨Ύ y ]) β D.Hom[ id ] (D*.β Ο (β y a)) (β x (D*.β (Ο β¨ΎΛ’ f) a)) β-sub {x = x} {Ο = Ο} {f = f} cart a = β¨β¨Ύβ©-cocartesian.universalv cart a β¨ x , (D*.β (Ο β¨ΎΛ’ f) a) β© β-sub-β¨β¨Ύβ© : β {Ξ Ξ x y} {Ο : Hom Ξ Ξ} {f : E.Hom[ Ο ] x y} β (cart : is-cartesian E Ο f) β (a : D.Ob[ Ξ β¨Ύ y ]) β β-sub cart a D.β' β¨ f β¨Ύ a β© D.β‘[ idl _ ] β¨ x , (D*.β (Ο β¨ΎΛ’ f) a) β© β-sub-β¨β¨Ύβ© cart a = β¨β¨Ύβ©-cocartesian.commutesv cart a _ β-sub-natural : β {Ξ Ξ x y} {Ο : Hom Ξ Ξ} {f : E.Hom[ Ο ] x y} β {a b : D.Ob[ Ξ β¨Ύ y ]} β (cart : is-cartesian E Ο f) β (g : D.Hom[ id ] a b) β β-sub cart b D.β' D*.β Ο β[ g ] β‘ β[ D*.β (Ο β¨ΎΛ’ f) g ] D.β' β-sub cart a β-sub-natural {x = x} {y = y} {Ο = Ο} {f = f} {a = a} {b = b} cart g = β¨β¨Ύβ©-cocartesian.uniquepβ cart a _ _ _ _ _ (Dr.pullr[] _ (symP (β¨β¨Ύβ©-natural g f)) D.β[] Dr.pulll[] _ (β¨β¨Ύβ©-cocartesian.commutesv cart b _)) (Dr.pullr[] _ (β¨β¨Ύβ©-cocartesian.commutesv cart a _) D.β[] β[]-natural (D*.β (Ο β¨ΎΛ’ f) g))