module Cat.Monoidal.Instances.Factorisations {o ℓ} (C : Precategory o ℓ) where
private Ff = Factorisations C
open Cat.Reasoning C
open Factorisation using (adjust ; annihilate ; collapse ; weave)
Monoidal structure on functorial factorisations🔗
We show how to equip the category of functorial factorisations on with the structure of a monoidal category, such that a monoid on some factorisation is precisely a right weak factorisation structure on
The unit factorisation sends each to
: Factorisation C
Ff-unit .S₀ (_ , _ , f) = record
Ff-unit { map = id
; out = f
; com = intror refl
}
.S₁ f = record
Ff-unit { sq₀ = id-comm-sym
; sq₁ = f .com
}
.S-id = ext refl
Ff-unit .S-∘ f g = ext refl Ff-unit
We can easily calculate that the this unit factorisation is initial.
: is-initial (Factorisations C) Ff-unit Ff-unit-is-initial
: is-initial (Factorisations C) Ff-unit Ff-unit-is-initial
= record where
Ff-unit-is-initial other module o = Factorisation other
= record
centre { map = λ (X , Y , f) → record
{ map = o.λ→ f
; sq₀ = refl
; sq₁ = sym (o.factors f) ∙ introl refl
}
; com = λ x y f → Interpolant-pathp (other .S₁ f .sq₀)
}
= ext λ x y f →
paths h .λ→ f ≡⟨ h .sq₀ᶠᶠ f ⟩
o.mapᶠᶠ f ∘ id ≡⟨ elimr refl ⟩
h .mapᶠᶠ f ∎ h
If are a pair of factorisations, their tensor sends a map to the composite with “middle object” i.e. everything but the last arrow is the left factor.
module _ (F G : Factorisation C) where
private
module F = Factorisation F
module G = Factorisation G
_⊗ᶠᶠ_ : Factorisation C
_⊗ᶠᶠ_ .S₀ (_ , _ , f) = record where
= G.Mid (F.ρ→ f)
mid = G.λ→ (F.ρ→ f) ∘ F.λ→ f
map = G.ρ→ (F.ρ→ f)
out = sym (pulll (sym (G.factors _)) ∙ sym (F.factors _))
com
_⊗ᶠᶠ_ .S₁ sq = record where
open Interpolant (G .S₁ record { com = S₁ F sq .sq₁ })
using (sq₁ ; map)
renaming (sq₀ to α)
= sym (pulll (sym α) ∙ extendr (sym (F .S₁ sq .sq₀)))
sq₀
_⊗ᶠᶠ_ .S-id = ext (G.annihilate (ext (F.annihilate refl ,ₚ refl)))
_⊗ᶠᶠ_ .S-∘ f g = ext (G.expand (ext (F.expand refl ,ₚ refl)))
Showing that this extends to a functor is slightly annoying, but unsurprising.
: Functor (Ff ×ᶜ Ff) Ff
Ff-tensor-functor .F₀ (F , F') = F ⊗ᶠᶠ F'
Ff-tensor-functor .F₁ {X , Y} {X' , Y'} (f , g) .map (_ , _ , h) =
Ff-tensor-functor let
= record { com = f .sq₁ᶠᶠ h ∙ introl refl }
sq = g .map (_ , _ , Factorisation.ρ→ X h)
h' in record
{ map = Y' .S₁ sq .map ∘ h' .map
; sq₀ = sym
( pullr (pulll (sym (h' .sq₀)))
(pulll (sym (Y' .S₁ sq .sq₀)) ∙ elimr refl)
∙∙ pulll (sym (f .sq₀ᶠᶠ h))
∙∙ pullr )
∙ intror refl; sq₁ = pulll (Y' .S₁ sq .sq₁)
(h' .sq₁ ∙ eliml refl)
∙ pullr }
.F₁ {X , Y} {X' , Y'} (f , g) .com α β h = Interpolant-pathp $
Ff-tensor-functor (g .comᶠᶠ _)
pullr (weave Y' (ext (f .comᶠᶠ _ ,ₚ id-comm-sym)))
∙ extendl
.F-id {_ , Y} = ext λ x y h → elimr refl ∙ annihilate Y (ext refl)
Ff-tensor-functor
.F-∘ {X , X'} {Y , Y'} {Z , Z'} f g = ext λ x y h →
Ff-tensor-functor (sym (f .snd .comᶠᶠ _)) ∙∙ pullr (sym (g .snd .comᶠᶠ _)) ∙∙ sym
pulll (ap₂ _∘_ (sym (f .snd .comᶠᶠ _)) (sym (g .snd .comᶠᶠ _))
(extendl (sym (g .snd .comᶠᶠ _)))
∙∙ pullr _∘_ refl (ap₂ _∘_ refl (collapse X' (ext (refl ,ₚ idl id))))) ∙∙ ap₂
The following snippet, showing part of the construction of the associator, is typical of the construction of the monoidal structure on every component of the natural isomorphisms is the identity, but we end up having to shuffle quite a few identity morphisms around.
private
: Associator-for {O = ⊤} (λ _ _ → Ff) Ff-tensor-functor
assc = to-natural-iso mk where
assc : make-natural-iso (compose-assocˡ Ff-tensor-functor) _
mk .eta X .map x = record
mk { map = id
; sq₀ = elimr refl ∙∙ pullr refl ∙∙ introl refl
; sq₁ = id-comm
}
.inv X .map x = record
mk { map = id
; sq₀ = elimr refl ∙∙ pulll refl ∙∙ introl refl
; sq₁ = id-comm
}
.eta X .com x y f = Interpolant-pathp id-comm-sym
mk .inv X .com x y f = Interpolant-pathp id-comm-sym
mk .eta∘inv x = ext λ x y f → idl id
mk .inv∘eta x = ext λ x y f → idl id
mk .natural (X , X') (Y , Y') f = ext λ x y h →
mk (elimr refl)
pullr (Factorisation.collapse (Y' .snd) (ext (refl ,ₚ idl id)))
∙∙ pulll ∙∙ introl refl
: Monoidal-category Ff
Ff-monoidal .-⊗- = Ff-tensor-functor
Ff-monoidal .Unit = Ff-unit Ff-monoidal
We thus choose not to comment much on the construction of the unitors
and proof of the triangle and pentagon identities.
: Monoidal-category Ff
Ff-monoidal .-⊗- = Ff-tensor-functor
Ff-monoidal .Unit = Ff-unit Ff-monoidal
.unitor-l = to-natural-iso mk where
Ff-monoidal : make-natural-iso (Id {C = Ff}) (Bi.Right Ff-tensor-functor Ff-unit)
mk .eta X .map _ = record { sq₀ = cancelr (idl id) ∙ introl refl ; sq₁ = id-comm }
mk .inv X .map _ = record { sq₀ = introl refl ; sq₁ = id-comm }
mk
.eta X .com x y f = Interpolant-pathp $
mk (ext refl) ∙∙ intror refl
eliml refl ∙∙ adjust X .inv X .com x y f = Interpolant-pathp $
mk (ext refl) ∙∙ intror refl
eliml refl ∙∙ adjust X
.eta∘inv x = ext λ x y f → idl id
mk .inv∘eta x = ext λ x y f → idl id
mk .natural X Y f = ext λ x y g →
mk (annihilate Y (ext refl)) ∙∙ introl refl
elimr refl ∙∙ eliml
.unitor-r = to-natural-iso mk where
Ff-monoidal : make-natural-iso (Id {C = Ff}) (Bi.Left Ff-tensor-functor Ff-unit)
mk .eta X .map _ = record { sq₀ = elimr refl ; sq₁ = id-comm }
mk .inv X .map _ = record { sq₀ = elimr refl ∙ insertl (idl id) ; sq₁ = id-comm }
mk
.eta X .com x y f = Interpolant-pathp $
mk .adjust X (ext refl) ∙∙ intror refl
eliml refl ∙∙ Factorisation.inv X .com x y f = Interpolant-pathp $
mk .adjust X (ext refl) ∙∙ intror refl
eliml refl ∙∙ Factorisation
.eta∘inv x = ext λ x y f → idl id
mk .inv∘eta x = ext λ x y f → idl id
mk .natural X Y f = ext λ x y g → cancelr (idl id) ∙ introl refl
mk
.associator = assc
Ff-monoidal .triangle = ext λ x y f → pullr (idl id)
Ff-monoidal .pentagon {B = B} {C = C} {D = D} = ext λ x y f →
Ff-monoidal
pullr( cancell (idl id)
∙∙ elimr refl(ext (annihilate C (ext (annihilate B (ext refl) ,ₚ refl)) ,ₚ refl)))
∙∙ annihilate D (_∘ id) (annihilate D (ext refl)) ∙ ap
Monoids on functorial factorisations🔗
module _ {F : Factorisation C} (m : Monoid-on Ff-monoidal F) where
private
module m = Monoid-on m
module F = Factorisation F
open is-monad
open Rwfs-on
We will now show that a monoid (on some functorial factorisation in this monoidal structure can be tweaked into a right weak factorisation structure on First, note that the components of the monoidal multiplication on can be reassembled into a monadic multiplication on the right factor.
private
: F.R F∘ F.R => F.R
monoid→mult .η (X , Y , f) = record where
monoid→mult = m.μ .mapᶠᶠ f
top = id
bot = m.μ .sq₁ᶠᶠ f ∙ introl refl
com .is-natural x y f = ext $
monoid→mult _∘_ refl (F.adjust (ext refl)) ∙ m.μ .comᶠᶠ _ ,ₚ
ap₂ id-comm-sym
For ease of calculation below, we can also extract a unit
map from the monoid structure on
: Id => F.R
monoid→unit : monoid→unit ≡ F.R-η monoid-unit-agrees
Of course, what we need to show is that the monoid multiplication makes
the right factor functor
with its canonical unit
into a monad. However, that the unit derived from the monoid agrees with
is an easy corollary of initiality for the unit factorisation.
: Id => F.R
monoid→unit : monoid→unit ≡ F.R-η monoid-unit-agrees
.η (X , Y , f) = record
monoid→unit { top = m.η .mapᶠᶠ f
; bot = id
; com = m.η .sq₁ᶠᶠ f ∙ introl refl
}
.is-natural x y f = ext (m.η .comᶠᶠ _ ,ₚ id-comm-sym)
monoid→unit
= ext λ (x , y , f) →
monoid-unit-agrees
intror refl(m.η .sq₀ᶠᶠ f) ,ₚ refl ∙ sym
The calculation that these two are a monad on is a straightforward repackaging of the corresponding monoid laws.
: is-monad monoid→unit monoid→mult
monoid-mult-is-monad .μ-unitr {X , Y , f} = ext $
monoid-mult-is-monad _∘_ refl (F.adjust (ext refl) ∙ intror refl)
ap₂ (λ i x → x .mapᶠᶠ f) m.μ-unitl
∙ apd
,ₚ idl id
.μ-unitl {X , Y , f} = ext $
monoid-mult-is-monad _∘_ refl (introl (F.annihilate (ext refl)))
ap₂ (λ i x → x .mapᶠᶠ f) m.μ-unitr
∙ apd
,ₚ idl id
.μ-assoc {X , Y , f} = ext $
monoid-mult-is-monad _∘_ refl (F.adjust (ext (refl ,ₚ refl)) ∙∙ intror refl ∙∙ intror refl)
ap₂ (λ i x → x .mapᶠᶠ f) (sym m.μ-assoc)
∙∙ apd _∘_ refl (eliml (F.annihilate (ext refl)))
∙∙ ap₂ ,ₚ refl
We can then transport this along the proof that the units agree to extend to a monad. This transport will not compute very nicely, but since “being a monad” is a proposition once the unit and multiplication are fixed, this does not matter.
: Rwfs-on F
monoid-on→rwfs-on .R-μ = monoid→mult
monoid-on→rwfs-on .R-monad = done where abstract
monoid-on→rwfs-on : is-monad F.R-η monoid→mult
done = subst
done (λ e → is-monad e monoid→mult) monoid-unit-agrees
monoid-mult-is-monad