module Cat.Displayed.Instances.Factorisations where
open Displayed
open Functor
open _=>s_
open _=>_
module _ {o ℓ} (C : Precategory o ℓ) where
open Cat.Reasoning C
The displayed category of factorisations🔗
Given a category we can define a displayed category over the arrow category where an object over consists of a factorisation of through some choice of object This is akin to the non-displayed notion of factorisation, but without the reference to pre-existing classes and for and to belong to.
record Splitting {X Y : ⌞ C ⌟} (f : Hom X Y) : Type (o ⊔ ℓ) where
no-eta-equality
field
{mid} : ⌞ C ⌟
: Hom X mid
map : Hom mid Y
out : f ≡ out ∘ map com
{-# INLINE Splitting.constructor #-}
open Splitting public
A morphism between splittings lying over a square from to in the arrow category, depicted in blue in the diagram below, is a map between the “middle” objects of the two factorisations making both the top and bottom rectangles commute.
record
Interpolant{X X' Y Y'} {f : Hom X Y} {g : Hom X' Y'}
(sq : Homᵃ C f g) (s : Splitting f) (t : Splitting g)
: Type ℓ where
no-eta-equality
private
module s = Splitting s
module t = Splitting t
field
: Hom (s .mid) (t .mid)
map : t.map ∘ sq .top ≡ map ∘ s.map
sq₀ : t.out ∘ map ≡ sq .bot ∘ s.out sq₁
In the literature on factorisation systems, the total category of this displayed category is identified with the diagram category of composable triples1 in and its projection functor sends each triple to its composite. In a proof assistant, defining this as a displayed category is superior because it lets us define sections of the composition functor— which send each arrow to a factorisation— where the domain and codomain of a factored arrow are definitionally the ones we started with.
{-# INLINE Interpolant.constructor #-}
open Interpolant public
unquoteDecl H-Level-Interpolant = declare-record-hlevel 2 H-Level-Interpolant (quote Interpolant)
module _ {o ℓ} {C : Precategory o ℓ} where
open Precategory C
Interpolant-pathp: ∀ {X X' Y Y'} {f : Hom X Y} {g : Hom X' Y'} {sq sq' : Homᵃ C f g} {p : sq ≡ sq'} {s : Splitting C f} {t : Splitting C g}
→ {f : Interpolant C sq s t} {g : Interpolant C sq' s t}
→ f .map ≡ g .map
→ PathP (λ i → Interpolant C (p i) s t) f g
.map = p i
Interpolant-pathp p i {p = q} {s} {t} {f} {g} p i .sq₀ = is-prop→pathp (λ i → Hom-set _ _ (t .map ∘ q i .top) (p i ∘ s .map)) (f .sq₀) (g .sq₀) i
Interpolant-pathp {p = q} {s} {t} {f} {g} p i .sq₁ = is-prop→pathp (λ i → Hom-set _ _ (t .out ∘ p i) (q i .bot ∘ s .out)) (f .sq₁) (g .sq₁) i
Interpolant-pathp
instance
Extensional-Interpolant: ∀ {X X' Y Y' ℓr} {f : Hom X Y} {g : Hom X' Y'} {sq : Homᵃ C f g} {s : Splitting C f} {t : Splitting C g}
→ ⦃ _ : Extensional (Hom (s .mid) (t .mid)) ℓr ⦄
→ Extensional (Interpolant C sq s t) ℓr
= injection→extensional! Interpolant-pathp auto
Extensional-Interpolant
module _ {o ℓ} (C : Precategory o ℓ) where
open Cat.Reasoning C
: Displayed (Arr C) _ _
Factorisations' .Ob[_] (_ , _ , f) = Splitting C f
Factorisations' .Hom[_] sq s s' = Interpolant C sq s s'
Factorisations'
.id' = record { sq₀ = id-comm ; sq₁ = id-comm }
Factorisations'
._∘'_ f g = record where
Factorisations' = f .map ∘ g .map
map = pulll (f .sq₀) ∙ extendr (g .sq₀)
sq₀ = pulll (f .sq₁) ∙ extendr (g .sq₁) sq₁
The only interesting to note about the coherence data here is that we
can reindex Interpolant
s over
identifications between squares without disturbing the middle map.
.Hom[_]-set f x y = hlevel 2
Factorisations'
.idr' f = Interpolant-pathp (idr _)
Factorisations' .idl' f = Interpolant-pathp (idl _)
Factorisations' .assoc' f g h = Interpolant-pathp (assoc _ _ _)
Factorisations'
.hom[_] p' f = record where
Factorisations' = f .map
map = ap₂ _∘_ refl (sym (ap top p')) ∙ f .sq₀
sq₀ = f .sq₁ ∙ ap₂ _∘_ (ap bot p') refl
sq₁ .coh[_] p' f = Interpolant-pathp refl Factorisations'
Functorial factorisations🔗
A (functorial) factorisation on
is a section of Factorisations'
. These naturally
assemble into a category.
: Type _
Factorisation = Section Factorisations'
Factorisation
: Precategory _ _
Factorisations = Sections Factorisations' Factorisations
We shall now identify some first properties of functorial factorisations.
module Factorisation {o ℓ} {C : Precategory o ℓ} (fac : Factorisation C) where
open Cat.Reasoning C
open Section fac
private module Arr = Cat.Reasoning (Arr C)
module _ {X Y : ⌞ C ⌟} (f : Hom X Y) where
open Splitting (Section.S₀ fac (X , Y , f))
renaming (mid to Mid ; map to λ→ ; out to ρ→ ; com to factors)
public
module _ {u v w x : ⌞ C ⌟} {f : Hom u v} {g : Hom w x} (sq : Homᵃ C f g) where
open Interpolant (Section.S₁ fac sq) using (map) public
Because the morphism-assignment of sections has a pretty dependent
type, we can not immediately reuse the functor reasoning combinators for
functorial factorisations.
Adapting them to this case is pretty straightforward, though, so here
are the ones we’ll need.
adjust: ∀ {u v w x} {f : Hom u v} {g : Hom w x} {sq sq' : Homᵃ C f g}
→ sq ≡ sq'
→ S₁ sq .map ≡ S₁ sq' .map
= apd (λ i → map) (ap S₁ p)
adjust p
weave: ∀ {u v w x w' x' y z} {f : Hom u v} {g : Hom w x} {g' : Hom w' x'} {h : Hom y z}
→ {sq : Homᵃ C g h} {sq' : Homᵃ C f g}
→ {tq : Homᵃ C g' h} {tq' : Homᵃ C f g'}
→ sq Arr.∘ sq' ≡ tq Arr.∘ tq'
→ S₁ sq .map ∘ S₁ sq' .map
.map ∘ S₁ tq' .map
≡ S₁ tq = apd (λ i → map) (sym (S-∘ _ _)) ∙∙ adjust p ∙∙ apd (λ i → map) (S-∘ _ _)
weave p
collapse: ∀ {u v w x y z} {f : Hom u v} {g : Hom w x} {h : Hom y z}
→ {sq : Homᵃ C g h} {sq' : Homᵃ C f g} {tq : Homᵃ C f h}
→ sq Arr.∘ sq' ≡ tq
→ S₁ sq .map ∘ S₁ sq' .map
.map
≡ S₁ tq = apd (λ i → map) (sym (S-∘ _ _)) ∙ adjust p
collapse p
expand: ∀ {u v w x y z} {f : Hom u v} {g : Hom w x} {h : Hom y z}
→ {sq : Homᵃ C g h} {sq' : Homᵃ C f g} {tq : Homᵃ C f h}
→ tq ≡ sq Arr.∘ sq'
→ S₁ tq .map
.map ∘ S₁ sq' .map
≡ S₁ sq = sym (collapse (sym p))
expand p
: ∀ {u v} {f : Hom u v} {sq : Homᵃ C f f} → sq ≡ Arr.id → S₁ sq .map ≡ id
annihilate = adjust p ∙ apd (λ i → map) S-id annihilate p
Given a functorial factorisation, we can define two endofunctors on
referred to simply as its left and right parts, which
send a morphism
to
and
respectively, while sending a square to either the top or bottom
rectangles in the definition of Interpolant
.
If is a functorial factorisation on splitting an into the left factor functor on is This is naturally made into a copointed endofunctor, with the counit assigning to each arrow the square
If is a functorial factorisation on splitting an into the right factor functor on is This is naturally made into a pointed endofunctor, with the unit assigning to each arrow the square
: Functor (Arr C) (Arr C)
L .F₀ (X , Y , f) = X , Mid f , λ→ f
L .F₁ {X , Z , f} {X' , Z' , f'} sq = record
L { top = sq .top
; bot = S₁ sq .map
; com = S₁ sq .sq₀
}
.F-id = ext (refl ,ₚ annihilate refl)
L .F-∘ f g = ext (refl ,ₚ expand refl)
L
: Functor (Arr C) (Arr C)
R .F₀ (X , Y , f) = Mid f , Y , ρ→ f
R .F₁ {X , Z , f} {X' , Z' , f'} sq = record
R { top = S₁ sq .map
; bot = sq .bot
; com = S₁ sq .sq₁
}
.F-id = ext (annihilate refl ,ₚ refl)
R .F-∘ f g = ext (expand refl ,ₚ refl) R
open Functor L renaming (F₁ to L₁) using () public
open Functor R renaming (F₁ to R₁) using () public
These endofunctors are naturally (co)pointed, meaning that the left (resp. right) functor admits a natural transformation to (resp. from) the identity on These transformations send a morphism to a triangle consisting of the complementary part of the factorisation.
: L => Id
L-ε .η (X , Y , f) = record
L-ε { top = id
; bot = ρ→ f
; com = elimr refl ∙ factors f
}
.is-natural x y f = ext (id-comm-sym ,ₚ S₁ f .sq₁)
L-ε
: Id => R
R-η .η (X , Y , f) = record
R-η { top = λ→ f
; bot = id
; com = sym (factors f) ∙ introl refl
}
.is-natural x y f = ext (S₁ f .sq₀ ,ₚ id-comm-sym) R-η
-- This is an ugly hack to pretend that morphisms in Factorisations have
-- record fields themselves. Note that we have to choose different names
-- to not clash with those from _=>s_, and that these can not be
-- overloaded.
module
_ {o ℓ} {C : Precategory o ℓ} {X Y : ⌞ Factorisation C ⌟}
(f : Factorisations C .Precategory.Hom X Y)
where
open Cat.Reasoning C
private
module X = Factorisation X
module Y = Factorisation Y
record Hack : Type (o ⊔ ℓ) where
field
: ∀ {x y} (g : Hom x y) → Hom (X.Mid g) (Y.Mid g)
mapᶠᶠ
: ∀ {x y} (g : Hom x y) → Y.λ→ g ≡ mapᶠᶠ g ∘ X.λ→ g
sq₀ᶠᶠ : ∀ {x y} (g : Hom x y) → Y.ρ→ g ∘ mapᶠᶠ g ≡ X.ρ→ g
sq₁ᶠᶠ
comᶠᶠ: ∀ {w x y z} {g : Hom w x} {h : Hom y z} (i : Homᵃ C g h)
→ mapᶠᶠ h ∘ X .Section.S₁ i .map ≡ Y .Section.S₁ i .map ∘ mapᶠᶠ g
: Hack
hack = record
hack { mapᶠᶠ = λ g → f .map (_ , _ , g) .map
; sq₀ᶠᶠ = λ g → intror refl ∙ f .map (_ , _ , g) .sq₀
; sq₁ᶠᶠ = λ g → f .map (_ , _ , g) .sq₁ ∙ eliml refl
; comᶠᶠ = λ i → apd (λ i → map) (f .com _ _ i)
}
open Hack hack public
Note that here denotes the ordinal and not the set with three elements.↩︎