module Cat.Displayed.Cartesian.Joint
{o ℓ o' ℓ'}
{B : Precategory o ℓ} (E : Displayed B o' ℓ')
where
open Cat.Displayed.Cartesian E
open Cat.Displayed.Reasoning E
open Cat.Displayed.Morphism E
open Cat.Reasoning B
open Displayed E
Jointly cartesian families🔗
A family of morphisms over is jointly cartesian if it satisfies a familial version of the universal property of a cartesian map.
record is-jointly-cartesian
{ℓi} {Ix : Type ℓi}
{a : Ob} {bᵢ : Ix → Ob}
{a' : Ob[ a ]} {bᵢ' : (ix : Ix) → Ob[ bᵢ ix ]}
(uᵢ : (ix : Ix) → Hom a (bᵢ ix))
(fᵢ : (ix : Ix) → Hom[ uᵢ ix ] a' (bᵢ' ix))
: Type (o ⊔ ℓ ⊔ o' ⊔ ℓ' ⊔ ℓi) where
Explicitly, a family is jointly cartesian if for every map and family of morphisms there exists a unique universal map such that
no-eta-equality
field
universal: ∀ {x x'}
→ (v : Hom x a)
→ (∀ ix → Hom[ uᵢ ix ∘ v ] x' (bᵢ' ix))
→ Hom[ v ] x' a'
commutes: ∀ {x x'}
→ (v : Hom x a)
→ (hᵢ : ∀ ix → Hom[ uᵢ ix ∘ v ] x' (bᵢ' ix))
→ ∀ ix → fᵢ ix ∘' universal v hᵢ ≡ hᵢ ix
unique: ∀ {x x'}
→ {v : Hom x a}
→ {hᵢ : ∀ ix → Hom[ uᵢ ix ∘ v ] x' (bᵢ' ix)}
→ (other : Hom[ v ] x' a')
→ (∀ ix → fᵢ ix ∘' other ≡ hᵢ ix)
→ other ≡ universal v hᵢ
universal': ∀ {x x'}
→ {v : Hom x a} {wᵢ : ∀ ix → Hom x (bᵢ ix)}
→ (p : ∀ ix → uᵢ ix ∘ v ≡ wᵢ ix)
→ (∀ ix → Hom[ wᵢ ix ] x' (bᵢ' ix))
→ Hom[ v ] x' a'
{v = v} p hᵢ =
universal' λ ix → hom[ p ix ]⁻ (hᵢ ix)
universal v
commutesp: ∀ {x x'}
→ {v : Hom x a} {wᵢ : ∀ ix → Hom x (bᵢ ix)}
→ (p : ∀ ix → uᵢ ix ∘ v ≡ wᵢ ix)
→ (hᵢ : ∀ ix → Hom[ wᵢ ix ] x' (bᵢ' ix))
→ ∀ ix → fᵢ ix ∘' universal' p hᵢ ≡[ p ix ] hᵢ ix
=
commutesp p hᵢ ix (commutes _ (λ ix → hom[ p ix ]⁻ (hᵢ ix)) ix)
to-pathp⁻
universalp: ∀ {x x'}
→ {v₁ v₂ : Hom x a} {wᵢ : ∀ ix → Hom x (bᵢ ix)}
→ (p : ∀ ix → uᵢ ix ∘ v₁ ≡ wᵢ ix) (q : v₁ ≡ v₂) (r : ∀ ix → uᵢ ix ∘ v₂ ≡ wᵢ ix)
→ (hᵢ : ∀ ix → Hom[ wᵢ ix ] x' (bᵢ' ix))
→ universal' p hᵢ ≡[ q ] universal' r hᵢ
=
universalp p q r hᵢ (λ i ϕ → universal' ϕ hᵢ) prop!
apd
uniquep: ∀ {x x'}
→ {v₁ v₂ : Hom x a} {wᵢ : ∀ ix → Hom x (bᵢ ix)}
→ (p : ∀ ix → uᵢ ix ∘ v₁ ≡ wᵢ ix) (q : v₁ ≡ v₂) (r : ∀ ix → uᵢ ix ∘ v₂ ≡ wᵢ ix)
→ {hᵢ : ∀ ix → Hom[ wᵢ ix ] x' (bᵢ' ix)}
→ (other : Hom[ v₁ ] x' a')
→ (∀ ix → fᵢ ix ∘' other ≡[ p ix ] hᵢ ix)
→ other ≡[ q ] universal' r hᵢ
{hᵢ} other s =
uniquep p q r (unique other (λ ix → from-pathp⁻ (s ix)) ∙ from-pathp⁻ (universalp p q r hᵢ))
to-pathp⁻
uniquep₂: ∀ {x x'}
→ {v₁ v₂ : Hom x a} {wᵢ : ∀ ix → Hom x (bᵢ ix)}
→ (p : ∀ ix → uᵢ ix ∘ v₁ ≡ wᵢ ix) (q : v₁ ≡ v₂) (r : ∀ ix → uᵢ ix ∘ v₂ ≡ wᵢ ix)
→ {hᵢ : ∀ ix → Hom[ wᵢ ix ] x' (bᵢ' ix)}
→ (other₁ : Hom[ v₁ ] x' a')
→ (other₂ : Hom[ v₂ ] x' a')
→ (∀ ix → fᵢ ix ∘' other₁ ≡[ p ix ] hᵢ ix)
→ (∀ ix → fᵢ ix ∘' other₂ ≡[ r ix ] hᵢ ix)
→ other₁ ≡[ q ] other₂
{hᵢ = hᵢ} other₁ other₂ α β =
uniquep₂ p q r
cast[] $
other₁ ≡[]⟨ uniquep p refl p other₁ α ⟩(uniquep r (sym q) p other₂ β) ⟩
universal' p hᵢ ≡[]⟨ symP other₂ ∎
private variable
: Level
ℓi ℓi' ℓj : Type ℓi
Ix Ix' : Ix → Type ℓj
Jx : Ob
a b c : Ix → Ob
bᵢ cᵢ : (i : Ix) → Jx i → Ob
cᵢⱼ : Ob[ a ]
a' b' c' : (ix : Ix) → Ob[ bᵢ ix ]
bᵢ' cᵢ' : (i : Ix) → (j : Jx i) → Ob[ cᵢⱼ i j ]
cᵢⱼ' : Hom a b
u v : ∀ (ix : Ix) → Hom a (bᵢ ix)
uᵢ uⱼ vᵢ vⱼ : Hom[ u ] a' b'
f g : ∀ (ix : Ix) → Hom[ uᵢ ix ] a' (bᵢ' ix) fᵢ fⱼ fᵢ' gᵢ gⱼ
Some sources ((Adámek, Herrlich, and Strecker 2004), (Dubuc and Español 2006)) refer to jointly cartesian families as “initial families”. We opt to avoid this terminology, as it leads to unnecessary conflicts with initial objects.
At first glance, jointly cartesian families appear very similar to cartesian maps. However, replacing a single map with a family of maps has some very strong consequences: cartesian morphisms typically behave as witnesses to base change operations, whereas jointly cartesian families act more like a combination of base-change maps and projections out of a product. This can be seen by studying prototypical examples of jointly cartesian families:
If we view the category of topological spaces as a displayed category, then the jointly cartesian maps are precisely the initial topologies.
Jointly cartesian maps in the subobject fibration of arise from pulling back a family of subsets along maps and then taking their intersection.
When is considered as a displayed category over the terminal category, the jointly cartesian families are precisely the indexed products. In contrast, the cartesian maps are the invertible maps.
Relating cartesian maps and jointly cartesian families🔗
Every cartesian map can be regarded as a jointly cartesian family over a contractible type.
cartesian→jointly-cartesian: is-contr Ix
→ is-cartesian u f
→ is-jointly-cartesian {Ix = Ix} (λ _ → u) (λ _ → f)
{u = u} {f = f} ix-contr f-cart = f-joint-cart where
cartesian→jointly-cartesian module f = is-cartesian f-cart
open is-jointly-cartesian
: is-jointly-cartesian (λ _ → u) (λ _ → f)
f-joint-cart .universal v hᵢ =
f-joint-cart .universal v (hᵢ (ix-contr .centre))
f.commutes v hᵢ ix =
f-joint-cart .universal v (hᵢ (ix-contr .centre)) ≡⟨ f.commutes v (hᵢ (ix-contr .centre)) ⟩
f ∘' f(ix-contr .centre) ≡⟨ ap hᵢ (ix-contr .paths ix) ⟩
hᵢ
hᵢ ix ∎.unique other p =
f-joint-cart .unique other (p (ix-contr .centre)) f
Conversely, if the constant family is a jointly cartesian family over a merely inhabited type then is cartesian.
const-jointly-cartesian→cartesian: ∥ Ix ∥
→ is-jointly-cartesian {Ix = Ix} (λ _ → u) (λ _ → f)
→ is-cartesian u f
{Ix = Ix} {u = u} {f = f} ∥ix∥ f-joint-cart =
const-jointly-cartesian→cartesian
rec! f-cart ∥ix∥where
module f = is-jointly-cartesian f-joint-cart
open is-cartesian
: Ix → is-cartesian u f
f-cart .universal v h = f.universal v λ _ → h
f-cart ix .commutes v h = f.commutes v (λ _ → h) ix
f-cart ix .unique other p = f.unique other (λ _ → p) f-cart ix
Jointly cartesian families over empty types act more like codiscrete objects than pullbacks, as the space of maps into the shared domain of the family is unique for any and In the displayed category of topological spaces, such maps are precisely the discrete spaces.
empty-jointly-cartesian→codiscrete: ∀ {uᵢ : (ix : Ix) → Hom a (bᵢ ix)} {fᵢ : (ix : Ix) → Hom[ uᵢ ix ] a' (bᵢ' ix)}
→ ¬ Ix
→ is-jointly-cartesian uᵢ fᵢ
→ ∀ {x} (v : Hom x a) → (x' : Ob[ x ]) → is-contr (Hom[ v ] x' a')
=
empty-jointly-cartesian→codiscrete ¬ix fᵢ-cart v x' (fᵢ.universal v λ ix → absurd (¬ix ix)) λ other →
contr (fᵢ.unique other λ ix → absurd (¬ix ix))
sym where
module fᵢ = is-jointly-cartesian fᵢ-cart
In the other direction, let be some map. If the constant family is jointly cartesian as a family over the booleans, then the type of morphisms is a proposition for every and
const-pair-joint-cartesian→thin: ∀ {u : Hom a b} {f : Hom[ u ] a' b'}
→ is-jointly-cartesian {Ix = Bool} (λ _ → u) (λ _ → f)
→ ∀ {x} (v : Hom x a) → (x' : Ob[ x ]) → is-prop (Hom[ u ∘ v ] x' b')
Let
be a pair of parallel maps in
We can view the the pair
as a Bool
indexed family of maps
over
so by the universal property of jointly cartesian families, there must
be a universal map
such that
and
thus
{b' = b'} {u = u} {f = f} f-cart v x' g h =
const-pair-joint-cartesian→thin
cast[] $
g ≡[]˘⟨ commutes v gh true ⟩
f ∘' universal v gh ≡[]⟨ commutes v gh false ⟩
h ∎where
open is-jointly-cartesian f-cart
: Bool → Hom[ u ∘ v ] x' b'
gh = g
gh true = h gh false
As a corollary, if is a jointly cartesian family, then every hom set is a proposition.
id-pair-joint-cartesian→thin: is-jointly-cartesian {Ix = Bool} (λ _ → id {a}) (λ _ → id' {a} {a'})
→ ∀ {x} (u : Hom x a) → (x' : Ob[ x ]) → is-prop (Hom[ u ] x' a')
=
id-pair-joint-cartesian→thin id²-cart u x' f g
cast[] $(sym (idl u)) ⟩
f ≡[]⟨ wrap (hom[ idl u ]⁻ f) (hom[ idl u ]⁻ g) ⟩
hom[] f ≡[]⟨ const-pair-joint-cartesian→thin id²-cart u x' (sym (idl u)) ⟩
hom[] g ≡[]⟨ unwrap g ∎
Closure properties of jointly cartesian families🔗
If is an jointly cartesian family, and is an family of jointly cartesian families, then their composite is a jointly cartesian family.
jointly-cartesian-∘: {uᵢⱼ : (i : Ix) → (j : Jx i) → Hom (bᵢ i) (cᵢⱼ i j)}
→ {fᵢⱼ : (i : Ix) → (j : Jx i) → Hom[ uᵢⱼ i j ] (bᵢ' i) (cᵢⱼ' i j)}
→ {vᵢ : (i : Ix) → Hom a (bᵢ i)}
→ {gᵢ : (i : Ix) → Hom[ vᵢ i ] a' (bᵢ' i)}
→ (∀ i → is-jointly-cartesian (uᵢⱼ i) (fᵢⱼ i))
→ is-jointly-cartesian vᵢ gᵢ
→ is-jointly-cartesian
(λ ij → uᵢⱼ (ij .fst) (ij .snd) ∘ vᵢ (ij .fst))
(λ ij → fᵢⱼ (ij .fst) (ij .snd) ∘' gᵢ (ij .fst))
_ = cartesian-∘
Despite the high quantifier complexity of the statement, the proof
follows the exact same plan that we use to show that cartesian maps compose
.
{Ix = Ix} {uᵢⱼ = uᵢⱼ} {fᵢⱼ = fᵢⱼ} {vᵢ = vᵢ} {gᵢ = gᵢ} fᵢⱼ-cart gᵢ-cart =
jointly-cartesian-∘
fᵢⱼ∘gᵢ-cartwhere
module fᵢⱼ (i : Ix) = is-jointly-cartesian (fᵢⱼ-cart i)
module gᵢ = is-jointly-cartesian gᵢ-cart
open is-jointly-cartesian
fᵢⱼ∘gᵢ-cart: is-jointly-cartesian
(λ ij → uᵢⱼ (ij .fst) (ij .snd) ∘ vᵢ (ij .fst))
(λ ij → fᵢⱼ (ij .fst) (ij .snd) ∘' gᵢ (ij .fst))
.universal v hᵢⱼ =
fᵢⱼ∘gᵢ-cart .universal v λ i →
gᵢ.universal' i (λ j → assoc (uᵢⱼ i j) (vᵢ i) v) λ j →
fᵢⱼ(i , j)
hᵢⱼ .commutes w hᵢⱼ (i , j) =
fᵢⱼ∘gᵢ-cart
cast[] $(fᵢⱼ i j ∘' gᵢ i) ∘' gᵢ.universal _ (λ i → fᵢⱼ.universal' i _ (λ j → hᵢⱼ (i , j))) ≡[]⟨ pullr[] _ (gᵢ.commutes w _ i) ⟩
.universal' i _ (λ j → hᵢⱼ (i , j)) ≡[]⟨ fᵢⱼ.commutesp i _ _ j ⟩
fᵢⱼ i j ∘' fᵢⱼ(i , j) ∎
hᵢⱼ .unique {hᵢ = hᵢⱼ} other p =
fᵢⱼ∘gᵢ-cart .unique other $ λ i →
gᵢ.uniquep i _ _ _ (gᵢ i ∘' other) λ j →
fᵢⱼ(fᵢⱼ i j) (gᵢ i) other ⟩
fᵢⱼ i j ∘' gᵢ i ∘' other ≡[]⟨ assoc' (fᵢⱼ i j ∘' gᵢ i) ∘' other ≡[]⟨ p (i , j) ⟩
(i , j) ∎ hᵢⱼ
As a nice corollary, we get that jointly cartesian families compose with cartesian maps, as cartesian maps are precisely the singleton jointly cartesian families.
jointly-cartesian-cartesian-∘: is-jointly-cartesian uᵢ fᵢ
→ is-cartesian v g
→ is-jointly-cartesian (λ ix → uᵢ ix ∘ v) (λ ix → fᵢ ix ∘' g)
We actually opt to prove this corollary by hand to get nicer definitional behaviour of the resulting universal maps.
{uᵢ = uᵢ} {fᵢ = fᵢ} {v = v} {g = g} fᵢ-cart g-cart = fᵢ∘g-cart
jointly-cartesian-cartesian-∘ where
module fᵢ = is-jointly-cartesian fᵢ-cart
module g = is-cartesian g-cart
open is-jointly-cartesian
: is-jointly-cartesian (λ ix → uᵢ ix ∘ v) (λ ix → fᵢ ix ∘' g)
fᵢ∘g-cart .universal w hᵢ =
fᵢ∘g-cart .universal w $ fᵢ.universal' (λ ix → assoc (uᵢ ix) v w) hᵢ
g.commutes w hᵢ ix =
fᵢ∘g-cart
cast[] $(fᵢ ix ∘' g) ∘' universal fᵢ∘g-cart w hᵢ ≡[]⟨ pullr[] _ (g.commutes w _) ⟩
.universal' (λ ix → assoc (uᵢ ix) v w) hᵢ ≡[]⟨ fᵢ.commutesp _ hᵢ ix ⟩
fᵢ ix ∘' fᵢ
hᵢ ix ∎.unique other pᵢ =
fᵢ∘g-cart .unique other $
g.uniquep _ _ _ (g ∘' other) λ ix →
fᵢ(fᵢ ix) g other ∙[] pᵢ ix assoc'
Similarly, if is a family of maps with each individually cartesian, and is jointly cartesian, then the composite is jointly cartesian.
pointwise-cartesian-jointly-cartesian-∘: (∀ ix → is-cartesian (uᵢ ix) (fᵢ ix))
→ is-jointly-cartesian vᵢ gᵢ
→ is-jointly-cartesian (λ ix → uᵢ ix ∘ vᵢ ix) (λ ix → fᵢ ix ∘' gᵢ ix)
We again prove this by hand to get better definitional behaviour.
pointwise-cartesian-jointly-cartesian-∘{uᵢ = uᵢ} {fᵢ = fᵢ} {vᵢ = vᵢ} {gᵢ = gᵢ} fᵢ-cart gᵢ-cart = fᵢ∘gᵢ-cart where
module fᵢ ix = is-cartesian (fᵢ-cart ix)
module gᵢ = is-jointly-cartesian gᵢ-cart
open is-jointly-cartesian
: is-jointly-cartesian (λ ix → uᵢ ix ∘ vᵢ ix) (λ ix → fᵢ ix ∘' gᵢ ix)
fᵢ∘gᵢ-cart .universal v hᵢ =
fᵢ∘gᵢ-cart .universal v λ ix → fᵢ.universal' ix (assoc (uᵢ ix) (vᵢ ix) v) (hᵢ ix)
gᵢ.commutes v hᵢ ix =
fᵢ∘gᵢ-cart
cast[] $(fᵢ ix ∘' gᵢ ix) ∘' gᵢ.universal v (λ ix → fᵢ.universal' ix _ (hᵢ ix)) ≡[]⟨ pullr[] refl (gᵢ.commutes v _ ix) ⟩
.universal' ix _ (hᵢ ix) ≡[]⟨ fᵢ.commutesp ix (assoc (uᵢ ix) (vᵢ ix) v) (hᵢ ix) ⟩
fᵢ ix ∘' fᵢ
hᵢ ix ∎.unique other p =
fᵢ∘gᵢ-cart .unique other λ ix →
gᵢ.uniquep ix _ _ _ (gᵢ ix ∘' other)
fᵢ(assoc' (fᵢ ix) (gᵢ ix) other ∙[] p ix)
Like their non-familial counterparts, jointly cartesian maps are stable under vertical retractions.
jointly-cartesian-vertical-retraction-stable: ∀ {fᵢ : ∀ (ix : Ix) → Hom[ uᵢ ix ] a' (cᵢ' ix)}
→ {fᵢ' : ∀ (ix : Ix) → Hom[ uᵢ ix ] b' (cᵢ' ix)}
→ {ϕ : Hom[ id ] a' b'}
→ is-jointly-cartesian uᵢ fᵢ
→ has-section↓ ϕ
→ (∀ ix → fᵢ' ix ∘' ϕ ≡[ idr _ ] fᵢ ix)
→ is-jointly-cartesian uᵢ fᵢ'
_ = cartesian-vertical-retraction-stable
The proof is essentially the same as the non-joint case
,
so we omit the details.
jointly-cartesian-vertical-retraction-stable{uᵢ = uᵢ} {fᵢ = fᵢ} {fᵢ' = fᵢ'} {ϕ = ϕ} fᵢ-cart ϕ-sect factor
= fᵢ'-cart
where
module fᵢ = is-jointly-cartesian fᵢ-cart
module ϕ = has-section[_] ϕ-sect
: is-jointly-cartesian uᵢ fᵢ'
fᵢ'-cart .is-jointly-cartesian.universal v hᵢ =
fᵢ'-cart (ϕ ∘' fᵢ.universal v hᵢ)
hom[ idl v ] .is-jointly-cartesian.commutes v hᵢ ix =
fᵢ'-cart
cast[] $(ϕ ∘' fᵢ.universal v hᵢ) ≡[]⟨ unwrapr (idl v) ⟩
fᵢ' ix ∘' hom[] .universal v hᵢ ≡[]⟨ pulll[] (idr (uᵢ ix)) (factor ix) ⟩
fᵢ' ix ∘' ϕ ∘' fᵢ.universal v hᵢ ≡[]⟨ fᵢ.commutes v hᵢ ix ⟩
fᵢ ix ∘' fᵢ
hᵢ ix ∎.is-jointly-cartesian.unique {v = v} {hᵢ = hᵢ} other p =
fᵢ'-cart
cast[] $_ ϕ.is-section' ⟩
other ≡[]⟨ introl[] (ϕ ∘' ϕ.section') ∘' other ≡[]⟨ pullr[] _ (wrap (idl v) ∙[] fᵢ.unique _ unique-lemma) ⟩
.universal v hᵢ ≡[]⟨ wrap (idl v) ⟩
ϕ ∘' fᵢ(ϕ ∘' fᵢ.universal v hᵢ) ∎
hom[ idl v ]
where
: ∀ ix → fᵢ ix ∘' hom[ idl v ] (ϕ.section' ∘' other) ≡ hᵢ ix
unique-lemma =
unique-lemma ix
cast[] $(ϕ.section' ∘' other) ≡[]⟨ unwrapr (idl v) ⟩
fᵢ ix ∘' hom[ idl v ] .section' ∘' other ≡[]⟨ pulll[] _ (symP (pre-section[] ϕ-sect (factor ix))) ⟩
fᵢ ix ∘' ϕ
fᵢ' ix ∘' other ≡[]⟨ p ix ⟩ hᵢ ix ∎
Cancellation properties of jointly cartesian families🔗
Every jointly cartesian family is a jointly weak monic family; this follows immediately from the uniqueness portion of the universal property.
jointly-cartesian→jointly-weak-monic: is-jointly-cartesian uᵢ fᵢ
→ is-jointly-weak-monic fᵢ
{fᵢ = fᵢ} fᵢ-cart {g = w} g h p p' =
jointly-cartesian→jointly-weak-monic .uniquep₂ (λ _ → ap₂ _∘_ refl p) p (λ _ → refl) g h p' (λ _ → refl)
fᵢwhere module fᵢ = is-jointly-cartesian fᵢ-cart
If is an family of jointly weak monic families and is a jointly cartesian family, then must be a jointly cartesian family.
jointly-cartesian-weak-monic-cancell: {uᵢⱼ : (i : Ix) → (j : Jx i) → Hom (bᵢ i) (cᵢⱼ i j)}
→ {fᵢⱼ : (i : Ix) → (j : Jx i) → Hom[ uᵢⱼ i j ] (bᵢ' i) (cᵢⱼ' i j)}
→ {vᵢ : (i : Ix) → Hom a (bᵢ i)}
→ {gᵢ : (i : Ix) → Hom[ vᵢ i ] a' (bᵢ' i)}
→ (∀ i → is-jointly-weak-monic (fᵢⱼ i))
→ is-jointly-cartesian
(λ ij → uᵢⱼ (ij .fst) (ij .snd) ∘ vᵢ (ij .fst))
(λ ij → fᵢⱼ (ij .fst) (ij .snd) ∘' gᵢ (ij .fst))
→ is-jointly-cartesian vᵢ gᵢ
Like the general composition lemma for jointly cartesian families, the statement is more complicated than the proof, which follows from some short calculations.
jointly-cartesian-weak-monic-cancell{uᵢⱼ = uᵢⱼ} {fᵢⱼ} {vᵢ} {gᵢ} fᵢⱼ-weak-mono fᵢⱼ∘gᵢ-cart
= gᵢ-cart
where
module fᵢⱼ∘gᵢ = is-jointly-cartesian fᵢⱼ∘gᵢ-cart
open is-jointly-cartesian
: is-jointly-cartesian vᵢ gᵢ
gᵢ-cart .universal w hᵢ =
gᵢ-cart .universal' (λ (i , j) → sym (assoc (uᵢⱼ i j) (vᵢ i) w)) λ (i , j) →
fᵢⱼ∘gᵢ
fᵢⱼ i j ∘' hᵢ i.commutes w hᵢ i =
gᵢ-cart _ _ refl $ λ j →
fᵢⱼ-weak-mono i
cast[] $.universal' _ (λ (i , j) → fᵢⱼ i j ∘' hᵢ i) ≡[]⟨ assoc' _ _ _ ⟩
fᵢⱼ i j ∘' gᵢ i ∘' fᵢⱼ∘gᵢ(fᵢⱼ i j ∘' gᵢ i) ∘' fᵢⱼ∘gᵢ.universal' _ (λ (i , j) → fᵢⱼ i j ∘' hᵢ i) ≡[]⟨ fᵢⱼ∘gᵢ.commutesp _ _ (i , j) ⟩
fᵢⱼ i j ∘' hᵢ i ∎.unique other p =
gᵢ-cart .uniquep _ _ _ other λ (i , j) →
fᵢⱼ∘gᵢ_ (p i) pullr[]
As an immediate corollary, we get a left cancellation property for composites of joint cartesian families.
jointly-cartesian-cancell: {uᵢⱼ : (i : Ix) → (j : Jx i) → Hom (bᵢ i) (cᵢⱼ i j)}
→ {fᵢⱼ : (i : Ix) → (j : Jx i) → Hom[ uᵢⱼ i j ] (bᵢ' i) (cᵢⱼ' i j)}
→ {vᵢ : (i : Ix) → Hom a (bᵢ i)}
→ {gᵢ : (i : Ix) → Hom[ vᵢ i ] a' (bᵢ' i)}
→ (∀ i → is-jointly-cartesian (uᵢⱼ i) (fᵢⱼ i))
→ is-jointly-cartesian
(λ ij → uᵢⱼ (ij .fst) (ij .snd) ∘ vᵢ (ij .fst))
(λ ij → fᵢⱼ (ij .fst) (ij .snd) ∘' gᵢ (ij .fst))
→ is-jointly-cartesian vᵢ gᵢ
=
jointly-cartesian-cancell fᵢⱼ-cart fᵢⱼ∘gᵢ-cart
jointly-cartesian-weak-monic-cancell(λ i → jointly-cartesian→jointly-weak-monic (fᵢⱼ-cart i))
fᵢⱼ∘gᵢ-cart
We also obtain a further set of corollaries that describe some special cases of the general cancellation property.
jointly-cartesian-pointwise-weak-monic-cancell: (∀ ix → is-weak-monic (fᵢ ix))
→ is-jointly-cartesian (λ ix → uᵢ ix ∘ vᵢ ix) (λ ix → fᵢ ix ∘' gᵢ ix)
→ is-jointly-cartesian vᵢ gᵢ
jointly-cartesian-jointly-weak-monic-cancell: is-jointly-weak-monic fᵢ
→ is-jointly-cartesian (λ ix → uᵢ ix ∘ v) (λ ix → fᵢ ix ∘' g)
→ is-cartesian v g
jointly-cartesian-pointwise-cartesian-cancell: (∀ ix → is-cartesian (uᵢ ix) (fᵢ ix))
→ is-jointly-cartesian (λ ix → uᵢ ix ∘ vᵢ ix) (λ ix → fᵢ ix ∘' gᵢ ix)
→ is-jointly-cartesian vᵢ gᵢ
jointly-cartesian-cartesian-cancell: is-jointly-cartesian uᵢ fᵢ
→ is-jointly-cartesian (λ ix → uᵢ ix ∘ v) (λ ix → fᵢ ix ∘' g)
→ is-cartesian v g
As before, we opt to prove these results by hand to get nicer definitional behaviour.
jointly-cartesian-pointwise-weak-monic-cancell{uᵢ = uᵢ} {fᵢ = fᵢ} {vᵢ = vᵢ} {gᵢ = gᵢ} fᵢ-weak-monic fᵢ∘gᵢ-cart
= gᵢ-cart
where
module fᵢ∘gᵢ = is-jointly-cartesian fᵢ∘gᵢ-cart
open is-jointly-cartesian
: is-jointly-cartesian vᵢ gᵢ
gᵢ-cart .universal w hᵢ =
gᵢ-cart .universal' (λ ix → sym (assoc (uᵢ ix) (vᵢ ix) w))
fᵢ∘gᵢ(λ ix → fᵢ ix ∘' hᵢ ix)
.commutes w hᵢ ix =
gᵢ-cart _ _ refl $
fᵢ-weak-monic ix
cast[] $.universal' _ (λ ix → fᵢ ix ∘' hᵢ ix) ≡[]⟨ assoc' _ _ _ ⟩
fᵢ ix ∘' gᵢ ix ∘' fᵢ∘gᵢ(fᵢ ix ∘' gᵢ ix) ∘' fᵢ∘gᵢ.universal' _ (λ ix → fᵢ ix ∘' hᵢ ix) ≡[]⟨ fᵢ∘gᵢ.commutesp _ _ ix ⟩
fᵢ ix ∘' hᵢ ix ∎.unique other p =
gᵢ-cart .uniquep _ _ _ other (λ ix → pullr[] _ (p ix))
fᵢ∘gᵢ
jointly-cartesian-jointly-weak-monic-cancell{uᵢ = uᵢ} {fᵢ = fᵢ} {v = v} {g = g} fᵢ-weak-monic fᵢ∘g-cart
= g-cart
where
module fᵢ∘g = is-jointly-cartesian fᵢ∘g-cart
open is-cartesian
: is-cartesian v g
g-cart .universal w h =
g-cart .universal' (λ ix → sym (assoc (uᵢ ix) v w)) (λ ix → fᵢ ix ∘' h)
fᵢ∘g.commutes w h =
g-cart _ _ refl λ ix →
fᵢ-weak-monic
cast[] $.universal' _ (λ ix → fᵢ ix ∘' h) ≡[]⟨ assoc' _ _ _ ⟩
fᵢ ix ∘' g ∘' fᵢ∘g(fᵢ ix ∘' g) ∘' fᵢ∘g.universal' _ (λ ix → fᵢ ix ∘' h) ≡[]⟨ fᵢ∘g.commutesp _ _ ix ⟩
fᵢ ix ∘' h ∎.unique other p =
g-cart .uniquep _ _ _ other (λ ix → pullr[] _ p)
fᵢ∘g
=
jointly-cartesian-pointwise-cartesian-cancell fᵢ-cart fᵢ∘gᵢ-cart
jointly-cartesian-pointwise-weak-monic-cancell(λ ix → cartesian→weak-monic (fᵢ-cart ix))
fᵢ∘gᵢ-cart
=
jointly-cartesian-cartesian-cancell fᵢ-cart fᵢ∘g-cart
jointly-cartesian-jointly-weak-monic-cancell(jointly-cartesian→jointly-weak-monic fᵢ-cart)
fᵢ∘g-cart
Extending jointly cartesian families🔗
This section characterises when we can extend an jointly cartesian family to a cartesian family along a map Though seemingly innocent, being able to extend every family is equivalent to the displayed category being thin!
For the forward direction, let be a family such that the restriction of along a map thin. We can then easily extend the family along an arbitrary map by ignoring every single equality, as all hom sets involved are thin.
thin→jointly-cartesian-extend: ∀ {u : (i : Ix) → Hom a (bᵢ i)} {fᵢ : (i : Ix) → Hom[ uᵢ i ] a' (bᵢ' i)}
→ (∀ {x} (v : Hom x a) → (x' : Ob[ x ]) → ∀ (i : Ix) → is-prop (Hom[ uᵢ i ∘ v ] x' (bᵢ' i)))
→ (e : Ix' → Ix)
→ is-jointly-cartesian (λ i' → uᵢ (e i')) (λ i' → fᵢ (e i'))
→ is-jointly-cartesian (λ i → uᵢ i) (λ i → fᵢ i)
{uᵢ = uᵢ} {fᵢ = fᵢ} uᵢ∘v-thin e fₑᵢ-cart = fᵢ-cart where
thin→jointly-cartesian-extend module fₑᵢ = is-jointly-cartesian fₑᵢ-cart
open is-jointly-cartesian
: is-jointly-cartesian (λ i' → uᵢ i') (λ i' → fᵢ i')
fᵢ-cart .universal v hᵢ =
fᵢ-cart .universal v (λ i' → hᵢ (e i'))
fₑᵢ.commutes {x} {x'} v hᵢ i =
fᵢ-cart (fᵢ i ∘' fₑᵢ.universal v (λ i' → hᵢ (e i'))) (hᵢ i)
uᵢ∘v-thin v x' i .unique {x} {x'} {v} {hᵢ} other p =
fᵢ-cart .unique other λ i' → uᵢ∘v-thin v x' (e i') (fᵢ (e i') ∘' other) (hᵢ (e i')) fₑᵢ
For the reverse direction, suppose we could extend arbitrary families. In particular, this means that we can extend singleton families to constant families, which lets us transfer a proof that a morphism is cartesian to a proof that a constant family is jointly cartesian.
In particular, this means that the pair is jointly cartesian, which means that the hom set is thin!
jointly-cartesian-extend→thin: ∀ (extend
: ∀ {Ix' Ix : Type} {bᵢ : Ix → Ob} {bᵢ' : (i : Ix) → Ob[ bᵢ i ]}
→ {uᵢ : (i : Ix) → Hom a (bᵢ i)} {fᵢ : (i : Ix) → Hom[ uᵢ i ] a' (bᵢ' i)}
→ (e : Ix' → Ix)
→ is-jointly-cartesian (λ i' → uᵢ (e i')) (λ i' → fᵢ (e i'))
→ is-jointly-cartesian (λ i → uᵢ i) (λ i → fᵢ i))
→ ∀ {x} (v : Hom x a) → (x' : Ob[ x ]) → is-prop (Hom[ v ] x' a')
=
jointly-cartesian-extend→thin extend v x'
id-pair-joint-cartesian→thin(extend (λ _ → true)
(cartesian→jointly-cartesian ⊤-is-contr cartesian-id))
v x'
Universal properties🔗
Jointly cartesian families have an alternative presentation of their universal property: a family is jointly cartesian if and only if the joint postcomposition map
is an equivalence.
postcompose-equiv→jointly-cartesian: {uᵢ : ∀ ix → Hom a (bᵢ ix)}
→ (fᵢ : ∀ ix → Hom[ uᵢ ix ] a' (bᵢ' ix))
→ (∀ {x} (v : Hom x a) → (x' : Ob[ x ])
→ is-equiv {B = ∀ ix → Hom[ uᵢ ix ∘ v ] x' (bᵢ' ix)} (λ h ix → fᵢ ix ∘' h))
→ is-jointly-cartesian uᵢ fᵢ
jointly-cartesian→postcompose-equiv: {uᵢ : ∀ ix → Hom a (bᵢ ix)}
→ {fᵢ : ∀ ix → Hom[ uᵢ ix ] a' (bᵢ' ix)}
→ is-jointly-cartesian uᵢ fᵢ
→ ∀ {x} (v : Hom x a) → (x' : Ob[ x ])
→ is-equiv {B = ∀ ix → Hom[ uᵢ ix ∘ v ] x' (bᵢ' ix)} (λ h ix → fᵢ ix ∘' h)
The proofs are just shuffling about data, so we shall skip over the details.
{a = a} {uᵢ = uᵢ} fᵢ eqv = fᵢ-cart where
postcompose-equiv→jointly-cartesian module eqv {x} {v : Hom x a} {x' : Ob[ x ]} = Equiv (_ , eqv v x')
open is-jointly-cartesian
: is-jointly-cartesian uᵢ fᵢ
fᵢ-cart .universal v hᵢ =
fᵢ-cart .from hᵢ
eqv.commutes v hᵢ ix =
fᵢ-cart .ε hᵢ ·ₚ ix
eqv.unique {hᵢ = hᵢ} other p =
fᵢ-cart (eqv.η other) ∙ ap eqv.from (ext p)
sym
{uᵢ = uᵢ} {fᵢ = fᵢ} fᵢ-cart v x' .is-eqv hᵢ =
jointly-cartesian→postcompose-equiv (fᵢ.universal v hᵢ , ext (fᵢ.commutes v hᵢ)) λ fib →
contr (sym (fᵢ.unique (fib .fst) (λ ix → fib .snd ·ₚ ix)))
Σ-prop-pathp! where
module fᵢ = is-jointly-cartesian fᵢ-cart
Jointly cartesian lifts🔗
A jointly cartesian lift of a family of objects along a family of maps is an object equipped with a jointly cartesian family
record Joint-cartesian-lift
{ℓi : Level} {Ix : Type ℓi}
{x : Ob} {yᵢ : Ix → Ob}
(uᵢ : (ix : Ix) → Hom x (yᵢ ix))
(yᵢ' : (ix : Ix) → Ob[ yᵢ ix ])
: Type (o ⊔ ℓ ⊔ o' ⊔ ℓ' ⊔ ℓi)
where
no-eta-equality
field
{x'} : Ob[ x ]
: (ix : Ix) → Hom[ uᵢ ix ] x' (yᵢ' ix)
lifting : is-jointly-cartesian uᵢ lifting
jointly-cartesian
open is-jointly-cartesian jointly-cartesian public
A jointly cartesian fibration is a displayed category that joint cartesian lifts of all families.
: (κ : Level) → Type _
Jointly-cartesian-fibration =
Jointly-cartesian-fibration κ ∀ (Ix : Type κ)
→ {x : Ob} {yᵢ : Ix → Ob}
→ (uᵢ : (ix : Ix) → Hom x (yᵢ ix))
→ (yᵢ' : (ix : Ix) → Ob[ yᵢ ix ])
→ Joint-cartesian-lift uᵢ yᵢ'
module Jointly-cartesian-fibration {κ} (fib : Jointly-cartesian-fibration κ) where
The following section defines some nice notation for jointly cartesian fibrations, but is a bit verbose.
module _
(Ix : Type κ) {x : Ob} {yᵢ : Ix → Ob}
(uᵢ : (ix : Ix) → Hom x (yᵢ ix))
(yᵢ' : (ix : Ix) → Ob[ yᵢ ix ])
where
open Joint-cartesian-lift (fib Ix uᵢ yᵢ')
using ()
renaming (x' to ∏*)
public
module _
{Ix : Type κ} {x : Ob} {yᵢ : Ix → Ob}
(uᵢ : (ix : Ix) → Hom x (yᵢ ix))
(yᵢ' : (ix : Ix) → Ob[ yᵢ ix ])
where
open Joint-cartesian-lift (fib Ix uᵢ yᵢ')
using ()
renaming (lifting to π*)
public
module π*
{Ix : Type κ} {x : Ob} {yᵢ : Ix → Ob}
{uᵢ : (ix : Ix) → Hom x (yᵢ ix)}
{yᵢ' : (ix : Ix) → Ob[ yᵢ ix ]}
where
open Joint-cartesian-lift (fib Ix uᵢ yᵢ')
hiding (x'; lifting)
public
Every jointly cartesian fibration has objects that act like codiscrete spaces arising from lifts of empty families.
opaque: ∀ (x : Ob) → Ob[ x ]
Codisc* = ∏* (Lift _ ⊥) {yᵢ = λ ()} (λ ()) (λ ())
Codisc* x
codisc*: ∀ {x y : Ob}
→ (u : Hom x y) (x' : Ob[ x ])
→ Hom[ u ] x' (Codisc* y)
= π*.universal u (λ ())
codisc* u x'
codisc*-unique: ∀ {x y : Ob}
→ {u : Hom x y} {x' : Ob[ x ]}
→ (other : Hom[ u ] x' (Codisc* y))
→ other ≡ codisc* u x'
= π*.unique other (λ ()) codisc*-unique other
References
- Adámek, Jiří, Horst Herrlich, and George E. Strecker. 2004. Abstract and Concrete Categories: The Joy of Cats. Dover Books on Mathematics. Mineola, NY: Dover Publ.
- Dubuc, Eduardo J., and Luis Español. 2006. “Topological Functors as Familiarly-Fibrations,” no. arXiv:math/0611701 (November). https://doi.org/10.48550/arXiv.math/0611701.