module Cat.Displayed.Path where
open Precategory
open DisplayedPaths of displayed categories🔗
If you have a pair of displayed categories
and
over a line of precategories
it might be interesting — if you, like me, are a lunatic — to know when
they can be connected by a PathP
over
This module answers that! A path between displayed categories, over a
path of their corresponding bases, is a displayed functor
which is componentwise an equivalence.
private
module
_ {o ℓ o' ℓ'} {B : I → Precategory o ℓ}
{E : Displayed (B i0) o' ℓ'}
{F : Displayed (B i1) o' ℓ'}
where
private
module E = Displayed E
module F = Displayed FThe first step🔗
We write this proof in two steps: First, we write a helper function
which abstracts over the contentful part of the path (the displayed
object spaces, displayed Hom spaces, etc) and automatically fills in the
proofs that the laws are preserved. We have a record displayed-pathp-data which contains paths
for all the interesting components:
record displayed-pathp-data : Type (lsuc (o ⊔ ℓ ⊔ o' ⊔ ℓ')) where
no-eta-equality
field
obp : PathP (λ i → B i .Ob → Type o') E.Ob[_] F.Ob[_]
homp : PathP
(λ i → {x y : B i .Ob} (f : B i .Hom x y) → obp i x → obp i y → Type ℓ')
E.Hom[_] F.Hom[_]The types get increasingly unhinged as we go: The identification between displayed object spaces lies over the identification of objects of the underlying category; The identification between displayed Hom spaces lies over a path in the base category and the path of displayed object spaces we just defined.
The paths between the identity morphisms and composite morphisms lie over both of those, and they have to quantify over every implicit argument inside the path! That’s why this record is in a private helper module, you see.
idp : PathP (λ i → ∀ {x} {x' : obp i x} → homp i (B i .id) x' x') E.id' F.id'
compp : PathP
(λ i → ∀ {x y z} {f : B i .Hom y z} {g : B i .Hom x y}
→ ∀ {x' y' z'} (f' : homp i f y' z') (g' : homp i g x' y')
→ homp i (B i ._∘_ f g) x' z')
E._∘'_ F._∘'_An instance of this record determines a path of displayed categories,
displayed-pathp-worker
: displayed-pathp-data → PathP (λ i → Displayed (B i) o' ℓ') E F
displayed-pathp-worker input = go where
open displayed-pathp-data inputsuch that all the interesting components are literal, and the coherence components are, by definition, unimportant.
homp-set :
PathP
(λ i → (a b : B i .Ob) (f : B i .Hom a b) (x : obp i a) (y : obp i b) → is-set (homp i f x y))
(λ a b → E .Hom[_]-set) λ a b → F .Hom[_]-set
homp-set i a b f x y = is-prop→pathp
(λ i → Π-is-hlevel³ {A = B i .Ob} {B = λ _ → B i .Ob} {C = λ a b → B i .Hom a b} 1
λ a b f → Π-is-hlevel² {A = obp i a} {B = λ _ → obp i b} 1
λ x y → is-hlevel-is-prop {A = homp i f x y} 2)
(λ _ _ → E .Hom[_]-set) (λ _ _ → F .Hom[_]-set) i a b f x y go : PathP (λ i → Displayed (B i) o' ℓ') E F
Ob[ go i ] x = obp i x
Hom[ go i ] = homp i
Hom[ go i ]-set {a} {b} f x y = homp-set i a b f x y
go i .id' = idp i
go i ._∘'_ = compp i go i .idr' {a} {b} {x} {y} {f} f' j = is-set→squarep
(λ i j → Π-is-hlevel³ {A = B i .Ob} {B = λ _ → B i .Ob} {C = λ a _ → obp i a} 2
λ a b x → Π-is-hlevel³ {A = obp i b} {B = λ _ → B i .Hom a b} {C = λ y f → homp i f x y} 2
λ y f f' → homp-set i a b (B i .idr f j) x y)
(λ i a b x y f f' → compp i f' (idp i))
(λ i a b x y f f' → E .idr' f' i)
(λ i a b x y f f' → F .idr' f' i)
(λ i a b x y f f' → f')
i j a b x y f f'
go i .idl' {a} {b} {x} {y} {f} f' j = is-set→squarep
(λ i j → Π-is-hlevel³ {A = B i .Ob} {B = λ _ → B i .Ob} {C = λ a _ → obp i a} 2
λ a b x → Π-is-hlevel³ {A = obp i b} {B = λ _ → B i .Hom a b} {C = λ y f → homp i f x y} 2
λ y f f' → homp-set i a b (B i .idl f j) x y)
(λ i a b x y f f' → compp i (idp i) f')
(λ i a b x y f f' → E .idl' f' i)
(λ i a b x y f f' → F .idl' f' i)
(λ i a b x y f f' → f')
i j a b x y f f'
go i .assoc' {a} {b} {c} {d} {w} {x} {y} {z} {f} {g} {h} f' g' h' j = is-set→squarep
(λ i j → Π-is-hlevel³ {A = B i .Ob} {B = λ _ → B i .Ob} {C = λ _ _ → B i .Ob} 2
λ a b c → Π-is-hlevel³ {A = B i .Ob} {B = λ _ → obp i a} {C = λ _ _ → obp i b} 2
λ d w x → Π-is-hlevel³ {A = obp i c} {B = λ _ → obp i d} {C = λ _ - → B i .Hom c d} 2
λ y z f → Π-is-hlevel³ {A = B i .Hom b c} {B = λ _ → B i .Hom a b} {C = λ _ _ → homp i f y z} 2
λ g h f' → Π-is-hlevel² {A = homp i g x y} {B = λ _ → homp i h w x} 2
λ g' h' → homp-set i a d (B i .assoc f g h j) w z)
(λ i a b c d w x y z f g h f' g' h' → compp i f' (compp i g' h'))
(λ i a b c d w x y z f g h f' g' h' → E .assoc' f' g' h' i)
(λ i a b c d w x y z f g h f' g' h' → F .assoc' f' g' h' i)
(λ i a b c d w x y z f g h f' g' h' → compp i (compp i f' g') h')
i j a b c d w x y z f g h f' g' h'Complicating it🔗
Suppose that we have and together with a functor which is an isomorphism of precategories, and a functor over This is the situation in the introduction, but where the line comes from the identity system on precategories given by isomorphisms of precategories.
module
_ {o ℓ o' ℓ'} {B C : Precategory o ℓ} (F : Functor B C)
{ℰ : Displayed B o' ℓ'} {ℱ : Displayed C o' ℓ'}
(G : Displayed-functor F ℰ ℱ)
where
private
module ℰ = Displayed ℰ
module ℱ = Displayed ℱ
module G = Displayed-functor G
module C = Precategory C
module F = Functor FThe functor must be componentwise an isomorphism of types: This is the displayed equivalent of an isomorphism of precategories.
Displayed-pathp
: (eqv : is-precat-iso F)
→ (∀ a → is-equiv {A = ℰ.Ob[ a ]} G.F₀')
→ ( ∀ {a b} {f} {a' : ℰ.Ob[ a ]} {b' : ℰ.Ob[ b ]}
→ is-equiv {A = ℰ.Hom[ f ] a' b'} G.F₁')
→ PathP (λ i → Displayed (Precategory-path F eqv i) o' ℓ') ℰ ℱ
Displayed-pathp eqv obeqv homeqv = displayed-pathp-worker input where
ps = Precategory-path F eqvWe’ll define a displayed-pathp-data. We define the paths
between displayed object spaces and displayed path spaces by gluing
against the ungluing of the paths in the underlying category,
in the right endpoint category
Diagrammatically, this looks something like
p1 : PathP (λ i → ps i .Ob → Type o') ℰ.Ob[_] ℱ.Ob[_]
p1 i x = Glue ℱ.Ob[ unglue x ] λ where
(i = i0) → ℰ.Ob[ x ] , G.F₀' , obeqv x
(i = i1) → ℱ.Ob[ x ] , _ , id-equivWe glue the type
along
— the action of the displayed functor on objects — against the line of
types given by applying the space of displayed objects of
to the ungluing of
giving a line of type families p1
ranging from
The situation for Hom spaces is analogous.
p2 : PathP
(λ i → {x y : ps i .Ob} (f : ps i .Hom x y) → p1 i x → p1 i y → Type ℓ')
ℰ.Hom[_] ℱ.Hom[_]
p2 i {x} {y} f x' y' = Glue (ℱ.Hom[ unglue f ] (unglue x') (unglue y')) λ where
(i = i0) → ℰ.Hom[ f ] x' y' , G.F₁' , homeqv
(i = i1) → ℱ.Hom[ f ] x' y' , id≃
open displayed-pathp-data
input : displayed-pathp-data
input .obp = p1
input .homp = p2We now “just” have to produce inhabitants of p2 along
which restrict to
and
identity morphisms (and composition morphisms) at the endpoints of
We can do so by gluing, now at the level of terms, against a
heterogeneous composition. The details are quite nasty, but the core of
it is extending the witness that
respects identity to a path, over line given by gluing
and ungluing the domain/codomain, between the identity maps in
and
input .idp i {x} {x'} = attach (∂ i)
(λ { (i = i0) → ℰ.id' ; (i = i1) → ℱ.id' })
(inS (comp (λ j → ℱ.Hom[ p (~ j) ] (unglue x') (unglue x')) (∂ i)
λ { j (j = i0) → ℱ.id'
; j (i = i0) → G.F-id' (~ j)
; j (i = i1) → ℱ.id' }))
where
p : unglue (ps i .id {x}) ≡ C.id
p j = hfill (∂ i) (~ j) λ where
k (k = i0) → C.id
k (i = i0) → F.F-id (~ k)
k (i = i1) → C.idThe case for compositions is analogous and yet much nastier, so I won’t comment on it. You can’t make me.
input .compp i {x} {y} {z} {f} {g} {x'} {y'} {z'} f' g' = attach _
(λ { (i = i0) → f' ℰ.∘' g' ; (i = i1) → f' ℱ.∘' g' })
(inS (comp (λ j → ℱ.Hom[ p j ] (unglue x') (unglue z')) (∂ i)
λ { k (k = i0) → unglue f' ℱ.∘' unglue g'
; k (i = i0) → G.F-∘' {f' = f'} {g' = g'} (~ k)
; k (i = i1) → f' ℱ.∘' g' }))
where
p : I → C .Hom (unglue x) (unglue z)
p j = hfill (∂ i) j λ where
k (i = i0) → F.F-∘ f g (~ k)
k (i = i1) → f C.∘ g
k (k = i0) → unglue f C.∘ unglue gmodule
_ {o ℓ o' ℓ'} {B : Precategory o ℓ} {ℰ ℱ : Displayed B o' ℓ'}
(F : Displayed-functor Id ℰ ℱ)
where
private
module F = Displayed-functor F
module ℰ = Displayed ℰAs one last step, we show that if the functor
is displayed over the identity, the path
is an actual identity, rather than a PathP.
Displayed-path
: (F₀-eqv : ∀ a → is-equiv F.₀')
→ (F₁-eqv : ∀ {a b} {f : B .Hom a b} {a' : ℰ.Ob[ a ]} {b' : ℰ.Ob[ b ]}
→ is-equiv (F.₁' {f = f} {a' = a'} {b' = b'}))
→ ℰ ≡ ℱ
Displayed-path F₀-eqv F₁-eqv =
transport
(λ i → PathP
(λ j → Displayed
(to-path-refl {a = B} Precategory-identity-system i j) o' ℓ') ℰ ℱ)
(Displayed-pathp Id F (iso id-equiv id-equiv) F₀-eqv F₁-eqv)