module Cat.Displayed.Instances.Factorisations where

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 ⌟
      left    : Hom X mid
      right   : Hom mid Y
      factors : f ≡ right ∘ left

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
    field
      map : Hom (s .mid) (t .mid)
      sq₀ : t.left ∘ sq .top ≡ map     ∘ s.left
      sq₁ : t.right ∘ map    ≡ sq .bot ∘ s.right

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.

  Factorisations' : 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
    map = f .map ∘ g .map
    sq₀ = pulll (f .sq₀) ∙ extendr (g .sq₀)
    sq₁ = pulll (f .sq₁) ∙ extendr (g .sq₁)
The only interesting thing to note about the coherence data here is that we can reindex Interpolants over identifications between squares without disturbing the middle map.
  Factorisations' .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
    map = f .map
    sq₀ = ap₂ _∘_ refl (sym (ap top p')) ∙ f .sq₀
    sq₁ = f .sq₁ ∙ ap₂ _∘_ (ap bot p') refl
  Factorisations' .coh[_] p' f = Interpolant-pathp refl

Functorial factorisations🔗

A (functorial) factorisation on is a section of Factorisations'. These naturally assemble into a category.

  Factorisation : Type _
  Factorisation = Section Factorisations'

  Factorisations : Precategory _ _
  Factorisations = Sections Factorisations'

We shall now identify some first properties of functorial factorisations.

Because the morphism-assignment of sections has a pretty dependent type, we can not immediately reuse the functor reasoning combinators for functorial factorisations.

However, we can define a functor that assigns each arrow to its midpoint and re-use the combinators for that functor.
  Mid : Functor (Arr C) C
  Mid = record where
    F₀ x = Mid₀ (x .snd .snd)
    F₁ f = S₁ f .map
    F-id    = apd (λ i → map) S-id
    F-∘ f g = apd (λ i → map) (S-∘ _ _)

  module Mid = Func Mid
  open Mid using (elim ; expand ; weave ; collapse) renaming (⟨_⟩ to adjust) public

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

  L : Functor (Arr C) (Arr C)
  L .F₀ (X , Y , f) = X , Mid₀ f , λ→ f
  L .F₁ {X , Z , f} {X' , Z' , f'} sq = record
    { top = sq .top
    ; bot = S₁ sq .map
    ; com = S₁ sq .sq₀
    }
  L .F-id    = ext (refl ,ₚ Mid.elim refl)
  L .F-∘ f g = ext (refl ,ₚ Mid.expand refl)

  R : Functor (Arr C) (Arr C)
  R .F₀ (X , Y , f) = Mid₀ f , Y , ρ→ f
  R .F₁ {X , Z , f} {X' , Z' , f'} sq = record
    { top = S₁ sq .map
    ; bot = sq .bot
    ; com = S₁ sq .sq₁
    }
  R .F-id    = ext (Mid.elim refl   ,ₚ refl)
  R .F-∘ f g = ext (Mid.expand refl ,ₚ refl)

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-ε : L => Id
  L-ε .η (X , Y , f) = record
    { top = id
    ; bot = ρ→ f
    ; com = elimr refl ∙ factors f
    }
  L-ε .is-natural x y f = ext (id-comm-sym ,ₚ S₁ f .sq₁)

  R-η : Id => R
  R-η .η (X , Y , f) = record
    { top = λ→ f
    ; bot = id
    ; com = sym (factors f) ∙ introl refl
    }
  R-η .is-natural x y f = ext (S₁ f .sq₀ ,ₚ id-comm-sym)

  1. Note that here denotes the ordinal and not the set with three elements.↩︎