module Cat.Univalent.Rezk.HIT {o β„“} (C : Precategory o β„“) where

Higher inductive Rezk completionsπŸ”—

We can define the Rezk completion of a precategory directly as a higher inductive type, without passing through replacement. Importantly, under this construction, the resulting universal functor becomes definitionally fully faithful.

The type of objects of looks a lot like the delooping of a group, but with an inclusion rather than a single basepoint: indeed, we can think of it as delooping all the automorphism groups of at once. Completely analogously, we have a constructor turning isomorphisms in into paths in and we have a generating triangle saying that this constructor respects composition, filling the diagram

data C^ : Type (o βŠ” β„“) where
  inc  : ⌞ C ⌟ β†’ C^
  glue : βˆ€ {x y} β†’ x β‰… y β†’ inc x ≑ inc y
  glueα΅€
    : βˆ€ {x y z} (f : x β‰… y) (g : y β‰… z)
    β†’ Triangle (glue f) (glue (g ∘Iso f)) (glue g)
  squash : is-groupoid C^

Note that, as in the case for simple deloopings, this generating triangle is sufficient to ensure that glue is functorial.

glue-∘
  : (e : x β‰… y) (e' : y β‰… z)
  β†’ Path (Path C^ (inc x) (inc z)) (glue e βˆ™ glue e') (glue (e' ∘Iso e))
glue-∘ e e' = sym (triangleβ†’commutes (glueα΅€ e e'))

glue-id : Path (Path C^ (inc x) (inc x)) (glue id-iso) refl
glue-id =
  glue id-iso                                     β‰‘βŸ¨ βˆ™-intror (βˆ™-invr _) βŸ©β‰‘
  glue id-iso βˆ™ glue id-iso βˆ™ sym (glue id-iso)   β‰‘βŸ¨ βˆ™-pulll (glue-∘ _ _ βˆ™ ap C^.glue (ext (idl _))) βŸ©β‰‘
  glue id-iso βˆ™ sym (glue id-iso)                 β‰‘βŸ¨ βˆ™-invr _ βŸ©β‰‘
  refl                                            ∎

We will need an elimination principle for C^ into sets, saying that it suffices to handle the point inclusions and the generating paths; the generating triangle is handled automatically, as is the truncation. Of course, we can also eliminate C^ into propositions, in which case the generating paths are also handled automatically.

C^-elim-set
  : βˆ€ {β„“} {P : C^ β†’ Type β„“} ⦃ _ : βˆ€ {x} β†’ H-Level (P x) 2 ⦄
  β†’ (pi : βˆ€ x β†’ P (inc x))
  β†’ (pg : βˆ€ {x y} (e : x β‰… y) β†’ PathP (Ξ» i β†’ P (glue e i)) (pi x) (pi y))
  β†’ βˆ€ x β†’ P x
C^-elim-set pi pg (inc x) = pi x
C^-elim-set pi pg (glue x i) = pg x i
C^-elim-set {P = P} pi pg (glueα΅€ {x} f g i j) =
  is-set→squarep (λ i j → hlevel {T = P (glueᡀ f g i j)} 2)
    (Ξ» i β†’ pi x) (Ξ» i β†’ pg f i) (Ξ» i β†’ pg (g ∘Iso f) i) (Ξ» i β†’ pg g i) i j
C^-elim-set {P = P} pi pg (squash x y p q Ξ± Ξ² i j k) =
  is-hlevel→is-hlevel-dep 2 (λ x → is-hlevel-suc 2 (hlevel {T = P x} 2))
    (go x) (go y) (Ξ» i β†’ go (p i)) (Ξ» i β†’ go (q i))
    (Ξ» i j β†’ go (Ξ± i j)) (Ξ» i j β†’ go (Ξ² i j)) (squash x y p q Ξ± Ξ²) i j k
  where go = C^-elim-set {P = P} pi pg

Defining spans over C^πŸ”—

We now turn to the problem of defining the This turns out to have a lot of β€œcases”, but we can break them down intuitively as follows: to define a function where is a groupoid, we can start by giving a function

record C^-corr {β„“'} (P : Type β„“') : Type (o βŠ” β„“ βŠ” β„“') where
  field
    has-is-groupoid : is-groupoid P

    base : ⌞ C ⌟ β†’ ⌞ C ⌟ β†’ P

Then, we must give actions of the isomorphisms on both the left and the right of making it into a sort of β€œprofunctor”; and, correspondingly, these actions must be β€œprofunctorial”. In particular, they should respect composition and commute past each other, which we can state concisely in terms of triangles and squares.

    lmap : βˆ€ {x x' y} (e : x β‰… x') β†’ base x y ≑ base x' y
    rmap : βˆ€ {x y y'} (e : y β‰… y') β†’ base x y ≑ base x y'

    lcoh : βˆ€ {x x' x'' y} (e : x β‰… x') (e' : x' β‰… x'')
         β†’ Triangle (lmap {y = y} e) (lmap (e' ∘Iso e)) (lmap e')

    rcoh : βˆ€ {x y y' y''} (e : y β‰… y') (e' : y' β‰… y'')
         β†’ Triangle (rmap {x = x} e) (rmap (e' ∘Iso e)) (rmap e')

    comm : βˆ€ {x x' y y'} (e : x β‰… x') (e' : y β‰… y')
         β†’ Square (rmap e) (lmap e') (lmap e') (rmap e)
This is sufficient to discharge all the cases when writing a binary function from into a groupoid; we leave the formalisation in this <details> block because it is rather fiddly.
  private
    instance
      _ : H-Level P 3
      _ = hlevel-instance has-is-groupoid

    goβ‚€ : (x : ⌞ C ⌟) (y : C^) β†’ P
    goβ‚€ ΞΎ (inc x)              = base ΞΎ x
    goβ‚€ ΞΎ (glue x i)           = rmap {ΞΎ} x i
    goβ‚€ ΞΎ (glueα΅€ f g i j)      = rcoh {ΞΎ} f g i j
    goβ‚€ ΞΎ (squash x y p q Ξ± Ξ² i j k) =
      let go = go₀ ξ in is-hlevel→is-hlevel-dep 2 (λ _ → hlevel 3)
        (go x) (go y) (Ξ» i β†’ go (p i)) (Ξ» i β†’ go (q i))
        (Ξ» i j β†’ go (Ξ± i j)) (Ξ» i j β†’ go (Ξ² i j))
        (squash x y p q Ξ± Ξ²) i j k

    lmap' : βˆ€ {x x'} (e : x β‰… x') β†’ goβ‚€ x ≑ goβ‚€ x'
    lmap' e = funextP $ C^-elim-set (Ξ» _ β†’ lmap e) Ξ» e' β†’ comm e' e

    lcoh'
      : βˆ€ {w x y : ⌞ C ⌟} (e : w β‰… x) (e' : x β‰… y)
      β†’ Triangle (lmap' e) (lmap' (e' ∘Iso e)) (lmap' e')
    lcoh' e e' = funext-square $ C^-elim-prop Ξ» x β†’ lcoh e e'

  C^-recβ‚‚ : (x y : C^) β†’ P
  C^-recβ‚‚ (inc x)          z = goβ‚€ x z
  C^-recβ‚‚ (glue x i)       z = lmap' x i z
  C^-recβ‚‚ (glueα΅€ x y i j)  z = lcoh' x y i j z
  C^-recβ‚‚ (squash x y p q Ξ± Ξ² i j k) z =
    let
      go : C^ β†’ P
      go x = C^-recβ‚‚ x z
    in is-hlevel→is-hlevel-dep 2 (λ _ → hlevel 3)
      (go x) (go y) (Ξ» i β†’ go (p i)) (Ξ» i β†’ go (q i))
      (Ξ» i j β†’ go (Ξ± i j)) (Ξ» i j β†’ go (Ξ² i j))
      (squash x y p q Ξ± Ξ²) i j k

Since is already a profunctor over we can show straightforwardly that it extends to a binary type family over

  hom^ : C^ β†’ C^ β†’ Type β„“
  hom^ x y = ⌞ C^-recβ‚‚ methods x y ⌟ where
    methods : C^-corr (Set β„“)
    methods .has-is-groupoid = hlevel 3
    methods .base x y = el! (Hom x y)

    methods .lmap e = n-ua (dom-iso→hom-equiv e)
    methods .rmap e = n-ua (cod-iso→hom-equiv e)

    methods .lcoh e e' = n-ua-triangle (ext Ξ» h β†’ assoc _ _ _)
    methods .rcoh e e' = n-ua-triangle (ext Ξ» h β†’ sym (assoc _ _ _))
    methods .comm e e' = n-ua-square   (ext Ξ» h β†’ sym (assoc _ _ _))

Making a categoryπŸ”—

Since our is valued in sets, we can use the eliminator defined above to construct the identity morphisms and the composition operation by These will consist of lifting the corresponding operation from and then showing that they respect the action of glue on hom^, which we have defined to be pre- and post-composition with the given isomorphism. Therefore, while there is a lot of code motion to put these together, they are conceptually very simple.

For a worked-out example, the necessary coherence for lifting the identity morphisms from to asks simply that if then we have which is a short calculation.

  id^ : βˆ€ x β†’ hom^ x x
  id^ = C^-elim-set (Ξ» _ β†’ id) coh where abstract
    coh : βˆ€ {x y} (j : x β‰… y) β†’ PathP (Ξ» i β†’ hom^ (glue j i) (glue j i)) id id
    coh z = path→ua-pathp _ $
      z .to ∘ id ∘ z .from  β‰‘βŸ¨ ap (z .to ∘_) (idl _) βŸ©β‰‘
      z .to ∘ z .from       β‰‘βŸ¨ z .invl βŸ©β‰‘
      id                    ∎
Lifting the composition operation is similar, but more involved, since we now have to do recursion on C^ thrice.
  ∘^ : βˆ€ x y z β†’ hom^ y z β†’ hom^ x y β†’ hom^ x z
  ∘^ = C^-elim-set f₁ cohβ‚‚ where mutual
    fβ‚€ : βˆ€ x y z β†’ hom^ (inc y) z β†’ hom^ (inc x) (inc y) β†’ hom^ (inc x) z
    fβ‚€ x y = C^-elim-set (Ξ» z β†’ _∘_) (cohβ‚€ x y)

    f₁ : βˆ€ x (y z : C^) β†’ hom^ y z β†’ hom^ (inc x) y β†’ hom^ (inc x) z
    f₁ x = C^-elim-set (fβ‚€ x) (coh₁ x)

    abstract
      cohβ‚€ : βˆ€ x y {z z'} (j : z β‰… z') β†’ PathP (Ξ» i β†’ hom^ (inc y) (glue j i) β†’ hom^ (inc x) (inc y) β†’ hom^ (inc x) (glue j i)) _∘_ _∘_
      coh₀ x y j = ua→ (λ f → funextP λ g → path→ua-pathp _ (assoc _ _ _))

      coh₁ : βˆ€ x {y z} (j : y β‰… z) β†’ PathP (Ξ» i β†’ (y : C^) β†’ hom^ (glue j i) y β†’ hom^ (inc x) (glue j i) β†’ hom^ (inc x) y) (fβ‚€ x y) (fβ‚€ x z)
      coh₁ x j = funextP (C^-elim-prop (Ξ» z β†’ uaβ†’ Ξ» h β†’ uaβ†’ Ξ» i β†’ ap (h ∘_) (insertl (j .invr)) βˆ™ pulll refl))

      cohβ‚‚ : βˆ€ {x y} (j : x β‰… y) β†’ PathP (Ξ» i β†’ (y z : C^) β†’ hom^ y z β†’ hom^ (glue j i) y β†’ hom^ (glue j i) z) (f₁ x) (f₁ y)
      coh₂ j = funextP $ elim! λ y → funextP $ elim! λ z → funextP λ f → ua→ λ g → path→ua-pathp _ (sym (assoc _ _ _))

To show that this forms a precategory, it suffices to lift the corresponding proofs also from Since we’re showing a proposition, this is very straightforward: it’s just some un/wrapping.

Rzk : Precategory (o βŠ” β„“) β„“
Rzk .P.Ob  = C^
Rzk .P.Hom x y = Hom^ x y
Rzk .P.Hom-set x y = hlevel 2
Rzk .P.id  {x}             = lift (id^ x)
Rzk .P._∘_ {w} {x} {y} f g = lift (∘^ w x y (f .lower) (g .lower))

Rzk .P.idr {x} {y} (lift f) = ap lift (idr^ x y f) where abstract
  idr^ : βˆ€ x y (f : hom^ x y) β†’ ∘^ x x y f (id^ x) ≑ f
  idr^ = elim! Ξ» x y f β†’ idr f

Rzk .P.idl {x} {y} (lift f) = ap lift (idl^ x y f) where abstract
  idl^ : βˆ€ x y (f : hom^ x y) β†’ ∘^ x y y (id^ y) f ≑ f
  idl^ = elim! Ξ» x y f β†’ idl f

Rzk .P.assoc {w} {x} {y} {z} (lift f) (lift g) (lift h) =
  ap lift (assoc^ w x y z f g h) where abstract
  assoc^ : βˆ€ w x y z (f : hom^ y z) (g : hom^ x y) (h : hom^ w x)
         β†’ ∘^ w y z f (∘^ w x y g h) ≑ ∘^ w x z (∘^ x y z f g) h
  assoc^ = elim! Ξ» w x y z f g h β†’ assoc f g h

We can give the Rezk completion functor.

complete : Functor C Rzk
complete .Functor.Fβ‚€      = inc
complete .Functor.F₁ f    = lift f
complete .Functor.F-id    = refl
complete .Functor.F-∘ f g = refl

complete-is-ff : is-fully-faithful complete
complete-is-ff = is-iso→is-equiv (iso Hom^.lower (λ x → refl) λ x → refl)

complete-is-eso : is-eso complete
complete-is-eso = elim! Ξ» x β†’ inc (x , Rzk.id-iso)

Univalence of the Rezk completionπŸ”—

To show that is univalent, we do one last monster induction, to show that, for a fixed the space of β€œisomorphs of ” is contractible. This automatically handles one coherence, since contractibility is a proposition; however, when actually lifting the glue constructor, we do still have one coherence to show.

to-path^ : (a : C^) β†’ is-contr (Ξ£[ b ∈ C^ ] a Rzk.β‰… b)
to-path^ = C^-elim-set
  (Ξ» x β†’ record { paths = Ξ» (b , e) β†’ wrap x b e })
  (Ξ» e β†’ prop!)
  where module _ (a : ⌞ C ⌟) where
    T : C^ β†’ Type _
    T x = (e : inc a Rzk.β‰… x)
        β†’ Path (Ξ£[ b ∈ C^ ] inc a Rzk.β‰… b) (inc a , Rzk.id-iso) (x , e)

    glue' : (x : ⌞ C ⌟) β†’ T (inc x)
    glue' x e = glue (hat.iso.from e) ,β‚š
      Rzk.≅-pathp _ _ (apd (λ i → lifthom^) (path→ua-pathp _ (idr _)))

However, this coherence is essentially the generating triangle glueα΅€, and so the proof goes through without much stress.

    coh : {x y : Ob} (e : x β‰… y)
        β†’ PathP (Ξ» i β†’ T (glue e i)) (glue' x) (glue' y)
    coh e = funext-dep Ξ» {xβ‚€} {x₁} Ξ± β†’
      let
        open Rzk using (to)

        Ξ±' : glue (e ∘Iso hat.iso.from xβ‚€) ≑ glue (hat.iso.from x₁)
        α' = ap C^.glue (ext (ua-pathp→path _ (apd (λ _ x → x .to .lower) α)))
      in Ξ£-set-square (Ξ» _ β†’ hlevel 2) $ glueα΅€ (hat.iso.from xβ‚€) e β–· Ξ±'

    wrap : βˆ€ b β†’ T b
    wrap = C^-elim-set glue' coh

Rzk-is-category : is-category Rzk
Rzk-is-category = contr→identity-system (λ {a} → to-path^ a)