Tom de Jong, 1-18 March 2021

We show that the induction principle for π•ŠΒΉ with propositional computation rules
follows from the universal property of π•ŠΒΉ.

This is claimed at the end of Section 6.2 in the HoTT Book and follows from a
general result by Sojakova in her PhD Thesis "Higher Inductive Types as
Homotopy-Initial Algebras" (CMU-CS-16-125). The proof of the general result is
quite complicated (see for instance Lemma 105 in the PhD thesis) and the
development below offers an alternative proof for π•ŠΒΉ.

\begin{code}

{-# OPTIONS --safe --without-K #-}

open import MLTT.Spartan
open import UF.Base
open import UF.Equiv
open import UF.FunExt
open import UF.Sets
open import UF.Sets-Properties
open import UF.Subsingletons

module SyntheticHomotopyTheory.Circle.Induction where

\end{code}

First some preliminaries on the free loop space.

\begin{code}

𝓛 : (X : 𝓀 Μ‡ ) β†’ 𝓀 Μ‡
𝓛 X = Ξ£ x κž‰ X , x = x

𝓛-functor : {X : 𝓀 Μ‡ } {Y : π“₯ Μ‡ } (f : X β†’ Y) β†’ 𝓛 X β†’ 𝓛 Y
𝓛-functor f (x , p) = f x , ap f p

𝓛-functor-id : {X : 𝓀 Μ‡ } β†’ 𝓛-functor id ∼ id {𝓀} {𝓛 X}
𝓛-functor-id {𝓀} {X} (x , p) = to-Ξ£-= (refl , Ξ³ p)
 where
  Ξ³ : {y z : X} (q : y = z) β†’ transport (Ξ» - β†’ y = -) q refl = q
  Ξ³ refl = refl

𝓛-functor-comp : {X : 𝓀 Μ‡ } {Y : π“₯ Μ‡ } {Z : 𝓦 Μ‡ } (f : X β†’ Y) (g : Y β†’ Z)
               β†’ 𝓛-functor g ∘ 𝓛-functor f ∼ 𝓛-functor (g ∘ f)
𝓛-functor-comp f g (x , p) = to-Ξ£-= (refl , (ap-ap f g p))

ap-𝓛-functor-lemma : {A : 𝓀 Μ‡ } {B : π“₯ Μ‡ } (f g : A β†’ B)
                     {a : A} (p : a = a) {b : B} (q : b = b)
                     (u : 𝓛-functor f (a , p) = (b , q))
                     (v : 𝓛-functor g (a , p) = (b , q))
                     (w : (f , u) = (g , v))
                   β†’ ap (Ξ» - β†’ 𝓛-functor - (a , p)) (ap pr₁ w) = u βˆ™ v ⁻¹
ap-𝓛-functor-lemma f g p q refl v refl = refl

happly-𝓛-functor-lemma : {A : 𝓀 Μ‡ } {B : π“₯ Μ‡ } (f g : A β†’ B)
                         {a : A} (p : a = a) {b : B} (q : b = b)
                         (u : 𝓛-functor f (a , p) = (b , q))
                         (v : 𝓛-functor g (a , p) = (b , q))
                         (w : (f , u) = (g , v))
                       β†’ happly (ap pr₁ w) a = (ap pr₁ u) βˆ™ (ap pr₁ v) ⁻¹
happly-𝓛-functor-lemma f g p q refl v refl = refl

\end{code}

Next we introduce the circle π•ŠΒΉ with its point base, its loop at base and its
universal property.

\begin{code}

module _
        (π•ŠΒΉ : 𝓀 Μ‡ )
        (base : π•ŠΒΉ)
        (loop : base = base)
       where

 π•ŠΒΉ-universal-map : (A : π“₯ Μ‡ )
                  β†’ (π•ŠΒΉ β†’ A) β†’ 𝓛 A
 π•ŠΒΉ-universal-map A f = (f base , ap f loop)

 module _
         (π•ŠΒΉ-universal-property : {π“₯ : Universe} (A : π“₯ Μ‡ )
                                β†’ is-equiv (π•ŠΒΉ-universal-map A))
        where

  π•ŠΒΉ-uniqueness-principle : {A : π“₯ Μ‡ } (a : A) (p : a = a)
                          β†’ βˆƒ! r κž‰ (π•ŠΒΉ β†’ A) , (r base , ap r loop) = (a , p)
  π•ŠΒΉ-uniqueness-principle {π“₯} {A} a p =
    equivs-are-vv-equivs (π•ŠΒΉ-universal-map A)
                         (π•ŠΒΉ-universal-property A) (a , p)

  π•ŠΒΉ-at-most-one-function : {A : π“₯ Μ‡ } (a : A) (p : a = a)
                          β†’ is-prop (Ξ£ r κž‰ (π•ŠΒΉ β†’ A) , (r base , ap r loop) = (a , p))
  π•ŠΒΉ-at-most-one-function a p = singletons-are-props (π•ŠΒΉ-uniqueness-principle a p)

\end{code}

The recursion principle for π•ŠΒΉ with its computation rule follows immediately
from the universal property of π•ŠΒΉ.

\begin{code}

  π•ŠΒΉ-rec : {A : π“₯ Μ‡ } (a : A) (p : a = a)
         β†’ π•ŠΒΉ β†’ A
  π•ŠΒΉ-rec {π“₯} {A} a p = βˆƒ!-witness (π•ŠΒΉ-uniqueness-principle a p)

  π•ŠΒΉ-rec-comp : {A : π“₯ Μ‡ } (a : A) (p : a = a)
              β†’ 𝓛-functor (π•ŠΒΉ-rec a p) (base , loop) =[ 𝓛 A ] (a , p)
  π•ŠΒΉ-rec-comp {π“₯} {A} a p = βˆƒ!-is-witness (π•ŠΒΉ-uniqueness-principle a p)

  π•ŠΒΉ-rec-on-base : {A : π“₯ Μ‡ } (a : A) (p : a = a)
                  β†’ π•ŠΒΉ-rec a p base = a
  π•ŠΒΉ-rec-on-base a p = ap pr₁ (π•ŠΒΉ-rec-comp a p)

  π•ŠΒΉ-rec-on-loop : {A : π“₯ Μ‡ } (a : A) (p : a = a)
                 β†’ transport (Ξ» - β†’ - = -) (π•ŠΒΉ-rec-on-base a p)
                     (ap (π•ŠΒΉ-rec a p) loop)
                 = p
  π•ŠΒΉ-rec-on-loop a p = from-Ξ£-=' (π•ŠΒΉ-rec-comp a p)

\end{code}

The induction principle for π•ŠΒΉ also follows quite directly. The idea is to turn
a type family A over π•ŠΒΉ to the type Ξ£ A and consider a nondependent map π•ŠΒΉ β†’ Ξ£ A
as a substitute for the dependent function (x : π•ŠΒΉ) β†’ A x.

What is significantly harder is showing that it obeys the computation rules.

\begin{code}

  module π•ŠΒΉ-induction
          (A : π•ŠΒΉ β†’ π“₯ Μ‡ )
          (a : A base)
          (l : transport A loop a = a)
         where

   l⁺ : (base , a) =[ Σ A ] (base , a)
   l⁺ = to-Σ-= (loop , l)

   r : π•ŠΒΉ β†’ Ξ£ A
   r = π•ŠΒΉ-rec (base , a) l⁺

\end{code}

Next we show that r is a retraction of pr₁ : Ξ£ A β†’ π•ŠΒΉ. This tells us that
r (x) = (x , prβ‚‚ (r x)), so that we can define π•ŠΒΉ-induction by transport.

\begin{code}

   r-retraction-lemma : 𝓛-functor (pr₁ ∘ r) (base , loop) =[ 𝓛 π•ŠΒΉ ] (base , loop)
   r-retraction-lemma =
    ((pr₁ ∘ r) base , ap (pr₁ ∘ r) loop) =⟨ I   ⟩
    𝓛-functor pr₁ (r base , ap r loop)   =⟨ II  ⟩
    (base , ap pr₁ (to-Ξ£-= (loop , l)))  =⟨ III ⟩
    (base , loop)                        ∎
     where
      I   = to-Ξ£-= (refl , ((ap-ap r pr₁ loop) ⁻¹))
      II  = ap (𝓛-functor pr₁) (π•ŠΒΉ-rec-comp (base , a) l⁺)
      III = to-Ξ£-= (refl , (ap-pr₁-to-Ξ£-= (loop , l)))

   r-is-retraction-of-pr₁ : pr₁ ∘ r = id
   r-is-retraction-of-pr₁ = ap pr₁ (π•ŠΒΉ-at-most-one-function base loop
                                     (pr₁ ∘ r , r-retraction-lemma)
                                     (id , to-Σ-= (refl , ap-id-is-id loop)))

   π•ŠΒΉ-induction : (x : π•ŠΒΉ) β†’ A x
   π•ŠΒΉ-induction x = transport A (happly r-is-retraction-of-pr₁ x) (prβ‚‚ (r x))

\end{code}

Next we set out to prove the computation rules for π•ŠΒΉ-induction.

\begin{code}

   ρ : π•ŠΒΉ β†’ Ξ£ A
   ρ x = (x , π•ŠΒΉ-induction x)

   r-comp : (r base , ap r loop) =[ 𝓛 (Ξ£ A) ] ((base , a) , l⁺)
   r-comp = π•ŠΒΉ-rec-comp (base , a) l⁺

   ρ-r-homotopy : ρ ∼ r
   ρ-r-homotopy x = to-Ξ£-= ((γ₁ ⁻¹) , Ξ³β‚‚)
    where
     γ₁ : pr₁ (r x) = pr₁ (ρ x)
     γ₁ = happly r-is-retraction-of-pr₁ x
     Ξ³β‚‚ = transport A (γ₁ ⁻¹) (prβ‚‚ (ρ x))                  =⟨refl⟩
          transport A (γ₁ ⁻¹) (transport A γ₁ (prβ‚‚ (r x))) =⟨ I    ⟩
          transport A (γ₁ βˆ™ γ₁ ⁻¹) (prβ‚‚ (r x))             =⟨ II   ⟩
          transport A refl (prβ‚‚ (r x))                     =⟨refl⟩
          prβ‚‚ (r x)                                        ∎
      where
       I  = (transport-βˆ™ A γ₁ (γ₁ ⁻¹)) ⁻¹
       II = ap (Ξ» - β†’ transport A - (prβ‚‚ (r x))) ((right-inverse γ₁) ⁻¹)

   ρ-and-r-on-base-and-loop : (ρ base , ap ρ loop) =[ 𝓛 (Ξ£ A) ] (r base , ap r loop)
   ρ-and-r-on-base-and-loop = to-Σ-= (ρ-r-homotopy base , γ)
    where
     Ξ³ = transport (Ξ» - β†’ - = -) (ρ-r-homotopy base) (ap ρ loop) =⟨ I  ⟩
         ρ-r-homotopy base ⁻¹ βˆ™ ap ρ loop βˆ™ ρ-r-homotopy base    =⟨ II ⟩
         ap r loop                                               ∎
      where
       I  = transport-along-= (ρ-r-homotopy base) (ap ρ loop)
       II = homotopies-are-natural'' ρ r ρ-r-homotopy {base} {base} {loop}

   ρ-comp : (ρ base , ap ρ loop) =[ 𝓛 (Ξ£ A) ] ((base , a) , l⁺)
   ρ-comp = ρ-and-r-on-base-and-loop βˆ™ r-comp

\end{code}

Looking at ρ-comp, we see that ρ base = (base , π•ŠΒΉ-induction base) = (base , a),
which looks promising, for if we can show that the equality in the first
component is refl, then π•ŠΒΉ-induction base = a would follow. So that's exactly
what we do next.

\begin{code}

   ρ-comp-lemma : ap pr₁ (ap pr₁ ρ-comp) = refl
   ρ-comp-lemma =
    ap pr₁ (ap pr₁ ρ-comp)                                          =⟨ I   ⟩
    ap (pr₁ ∘ pr₁) ρ-comp                                           =⟨ II  ⟩
    ap (pr₁ ∘ pr₁) ρ-and-r-on-base-and-loop βˆ™ ap (pr₁ ∘ pr₁) r-comp =⟨ III ⟩
    p ⁻¹ βˆ™ p                                                        =⟨ IV  ⟩
    refl                                                            ∎
    where
     p = happly r-is-retraction-of-pr₁ base
     I   = ap-ap pr₁ pr₁ ρ-comp
     II  = ap-βˆ™ (pr₁ ∘ pr₁) ρ-and-r-on-base-and-loop r-comp
     IV  = left-inverse p
     III = apβ‚‚ _βˆ™_ γ₁ Ξ³β‚‚
      where
       γ₁ : ap (pr₁ ∘ pr₁) ρ-and-r-on-base-and-loop  = p ⁻¹
       γ₁ = ap (pr₁ ∘ pr₁) ρ-and-r-on-base-and-loop  =⟨ I₁   ⟩
            ap pr₁ (ap pr₁ ρ-and-r-on-base-and-loop) =⟨ II₁  ⟩
            ap pr₁ (ρ-r-homotopy base)               =⟨ III₁ ⟩
            p ⁻¹                                     ∎
        where
         I₁   = (ap-ap pr₁ pr₁ ρ-and-r-on-base-and-loop) ⁻¹
         II₁  = ap (ap pr₁) (ap-pr₁-to-Ξ£-= (ρ-r-homotopy base , _))
         III₁ = ap-pr₁-to-Ξ£-= ((p ⁻¹) , _)
       Ξ³β‚‚ : ap (pr₁ ∘ pr₁) r-comp = p
       Ξ³β‚‚ = Ο• ⁻¹
        where
         ΞΊ = r-retraction-lemma
         Ο• = p                                                     =⟨ Iβ‚‚    ⟩
             ap pr₁ ΞΊ βˆ™ ap Ο€ (to-Ξ£-= (refl , ap-id-is-id loop)) ⁻¹ =⟨ IIβ‚‚   ⟩
             ap pr₁ ΞΊ βˆ™ refl ⁻¹                                    =⟨refl⟩
             ap pr₁ ΞΊ                                              =⟨ IIIβ‚‚  ⟩
             ap pr₁ (ap pr₁ r-comp)                                =⟨ IVβ‚‚   ⟩
             ap (pr₁ ∘ pr₁) r-comp                                 ∎
          where
           Ο€ : 𝓛 (π•ŠΒΉ) β†’ π•ŠΒΉ
           Ο€ = pr₁
           Iβ‚‚   = happly-𝓛-functor-lemma (pr₁ ∘ r) id loop loop
                   κ (to-Σ-= (refl , ap-id-is-id loop))
                   (π•ŠΒΉ-at-most-one-function base loop
                     (pr₁ ∘ r , r-retraction-lemma)
                     (id , to-Σ-= (refl , ap-id-is-id loop)))
           IIβ‚‚  = ap (Ξ» - β†’ ap pr₁ ΞΊ βˆ™ - ⁻¹)
                   (ap-pr₁-to-Ξ£-= {𝓀} {𝓀} {π•ŠΒΉ} {Ξ» - β†’ (- = -)} {_} {_}
                    (refl , ap-id-is-id loop))
           IVβ‚‚  = ap-ap pr₁ pr₁ r-comp
           IIIβ‚‚ = ap pr₁ ΞΊ                        =⟨refl⟩
                  ap pr₁ (κ₁ βˆ™ (ΞΊβ‚‚ βˆ™ κ₃))         =⟨ I'   ⟩
                  ap pr₁ κ₁ βˆ™ ap pr₁ (ΞΊβ‚‚ βˆ™ κ₃)    =⟨ II'  ⟩
                  refl βˆ™ ap pr₁ (ΞΊβ‚‚ βˆ™ κ₃)         =⟨ III' ⟩
                  ap pr₁ (ΞΊβ‚‚ βˆ™ κ₃)                =⟨ IV'  ⟩
                  ap pr₁ ΞΊβ‚‚ βˆ™ ap pr₁ κ₃           =⟨ V'   ⟩
                  ap pr₁ ΞΊβ‚‚ βˆ™ refl                =⟨refl⟩
                  ap pr₁ ΞΊβ‚‚                       =⟨ VI'  ⟩
                  ap (pr₁ ∘ 𝓛-functor pr₁) r-comp =⟨refl⟩
                  ap (pr₁ ∘ pr₁) r-comp           =⟨ VII' ⟩
                  ap pr₁ (ap pr₁ r-comp)          ∎
                  where
                   κ₁ = to-Ξ£-= (refl , ((ap-ap r pr₁ loop) ⁻¹))
                   ΞΊβ‚‚ = ap (𝓛-functor pr₁) r-comp
                   κ₃ = to-Ξ£-= (refl , (ap-pr₁-to-Ξ£-= (loop , l)))
                   I'   = ap-βˆ™ pr₁ κ₁ (ΞΊβ‚‚ βˆ™ κ₃)
                   II'  = ap (_βˆ™ (ap pr₁ (ΞΊβ‚‚ βˆ™ κ₃)))
                           (ap-pr₁-to-Ξ£-= {𝓀} {𝓀} {π•ŠΒΉ} {Ξ» - β†’ (- = -)} {_} {_}
                            (refl , ((ap-ap r pr₁ loop) ⁻¹)))
                   III' = refl-left-neutral
                   IV'  = ap-βˆ™ pr₁ ΞΊβ‚‚ κ₃
                   V'   = ap ((ap pr₁ ΞΊβ‚‚) βˆ™_)
                           (ap-pr₁-to-Ξ£-= {𝓀} {𝓀} {π•ŠΒΉ} {Ξ» - β†’ (- = -)} {_} {_}
                            (refl , ap-pr₁-to-Ξ£-= (loop , l)))
                   VI'  = ap-ap (𝓛-functor pr₁) pr₁ r-comp
                   VII' = (ap-ap pr₁ pr₁ r-comp) ⁻¹

   π•ŠΒΉ-induction-on-base : π•ŠΒΉ-induction base = a
   π•ŠΒΉ-induction-on-base =
    transport (Ξ» - β†’ transport A - (π•ŠΒΉ-induction base) = a) ρ-comp-lemma Ξ³
     where
      Ξ³ : transport A (ap pr₁ (ap pr₁ ρ-comp)) (π•ŠΒΉ-induction base) = a
      Ξ³ = from-Ξ£-=' (ap pr₁ ρ-comp)

\end{code}

This takes care of the first computation rule for π•ŠΒΉ-induction. We can
get a fairly direct proof of the second computation rule (the one for
loop) by assuming that base = base is a set, because this tells us
that every element of loop = loop must be refl.

We can satisfy this assumption for our intended application (see
CircleConstruction.lagda), because for the construction involving β„€-torsors it's
is quite easy to prove that base = base is a set.

However, for completeness sake, below we also show that assuming function
extensionality and univalence, it is possible to prove that base = base is a
set, by using both computation rules for π•ŠΒΉ-rec and the first computation rule
for π•ŠΒΉ-induction.

\begin{code}

   π•ŠΒΉ-induction-on-loop-lemma : (loop , transport (Ξ» - β†’ transport A loop - = -)
                                         π•ŠΒΉ-induction-on-base
                                         (apd π•ŠΒΉ-induction loop))
                              = (loop , l)
   π•ŠΒΉ-induction-on-loop-lemma =
      (fromto-Ξ£-= (loop , transport (Ξ» - β†’ transport A loop - = -) Οƒ Ο„)) ⁻¹
    βˆ™ (ap from-Ξ£-= Ξ³) βˆ™ (fromto-Ξ£-= (loop , l))
     where
      Οƒ = π•ŠΒΉ-induction-on-base
      Ο„ = apd π•ŠΒΉ-induction loop
      Ξ³ : to-Ξ£-= (loop , transport (Ξ» - β†’ transport A loop - = -) Οƒ Ο„)
        = to-Σ-= (loop , l)
      Ξ³ = to-Ξ£-= (loop , transport (Ξ» - β†’ transport A loop - = -) Οƒ Ο„)    =⟨ I   ⟩
          transport (Ξ» - β†’ - = -) (to-Ξ£-= (refl , Οƒ)) (to-Ξ£-= (loop , Ο„)) =⟨ II  ⟩
          transport (Ξ» - β†’ - = -) (ap pr₁ ρ-comp) (to-Ξ£-= (loop , Ο„))     =⟨ III ⟩
          transport (Ξ» - β†’ - = -) (ap pr₁ ρ-comp) (ap ρ loop)             =⟨ IV  ⟩
          to-Σ-= (loop , l)                                               ∎
       where
        I   = h loop Οƒ Ο„
         where
          h : {X : 𝓦 Μ‡ } {Y : X β†’ 𝓣 Μ‡ } {x : X} (p : x = x) {y y' : Y x}
              (q : y = y') (q' : transport Y p y = y)
            β†’ to-Ξ£-= (p , transport (Ξ» - β†’ transport Y p - = -) q q')
            = transport (Ξ» - β†’ - = -) (to-Ξ£-= (refl , q)) (to-Ξ£-= (p , q'))
          h p refl q' = refl
        II  = ap (Ξ» - β†’ transport (Ξ» - β†’ - = -) - (to-Ξ£-= (loop , Ο„))) h
         where
          h = to-Ξ£-= (refl , Οƒ)                 =⟨ I'  ⟩
              to-Ξ£-= (from-Ξ£-= (ap pr₁ ρ-comp)) =⟨ II' ⟩
              ap pr₁ ρ-comp                     ∎
           where
            I'  = (ap to-Σ-= (to-Σ-= (ρ-comp-lemma , refl))) ⁻¹
            II' = tofrom-Ξ£-= (ap pr₁ ρ-comp)
        III = ap (transport (Ξ» - β†’ - = -) (ap pr₁ ρ-comp)) (h π•ŠΒΉ-induction loop)
         where
          h : {X : 𝓦 Μ‡ } {Y : X β†’ 𝓣 Μ‡ } (f : (x : X) β†’ Y x)
              {x x' : X} (p : x = x')
            β†’ to-Ξ£-= (p , apd f p) = ap (Ξ» x β†’ (x , f x)) p
          h f refl = refl
        IV  = from-Σ-=' ρ-comp

   module _
           (base-sethood : is-set (base = base))
          where

    π•ŠΒΉ-induction-on-loop : transport (Ξ» - β†’ transport A loop - = -)
                            π•ŠΒΉ-induction-on-base (apd π•ŠΒΉ-induction loop)
                         = l
    π•ŠΒΉ-induction-on-loop =
     ap-pr₁-refl-lemma (Ξ» - β†’ transport A - a = a) π•ŠΒΉ-induction-on-loop-lemma Ξ³
     where
      Ξ³ : ap pr₁ π•ŠΒΉ-induction-on-loop-lemma = refl
      Ξ³ = base-sethood (ap pr₁ π•ŠΒΉ-induction-on-loop-lemma) refl

    π•ŠΒΉ-induction-comp : (π•ŠΒΉ-induction base , apd π•ŠΒΉ-induction loop)
                      =[ Ξ£ y κž‰ A base , transport A loop y = y ] (a , l)
    π•ŠΒΉ-induction-comp = to-Ξ£-= (π•ŠΒΉ-induction-on-base , π•ŠΒΉ-induction-on-loop)

\end{code}

As promised above, here follows a proof, assuming function
extensionality and univalence, that base = base is a set, using both
computation rules for π•ŠΒΉ-rec and the first computation rule for
π•ŠΒΉ-induction.

The proof uses the encode-decode method (Section 8.1.4 of the HoTT
Book) to show that base = base is a retract of β„€. Since sets are
closed under retracts, the claim follows.

\begin{code}

  open import SyntheticHomotopyTheory.Circle.Integers
  open import SyntheticHomotopyTheory.Circle.Integers-Properties

  open import UF.Univalence

  module _
          (ua : is-univalent 𝓀₀)
         where

   succ-β„€-= : β„€ = β„€
   succ-β„€-= = eqtoid ua β„€ β„€ succ-β„€-≃

   code : π•ŠΒΉ β†’ 𝓀₀ Μ‡
   code = π•ŠΒΉ-rec β„€ succ-β„€-=

\end{code}

   Using the first computation rule for π•ŠΒΉ-rec:

\begin{code}

   code-on-base : code base = β„€
   code-on-base = π•ŠΒΉ-rec-on-base β„€ succ-β„€-=

   β„€-to-code-base : β„€ β†’ code base
   β„€-to-code-base = Idtofun (code-on-base ⁻¹)

   code-base-to-β„€ : code base β†’ β„€
   code-base-to-β„€ = Idtofun code-on-base

   transport-code-loop-is-succ-β„€ : code-base-to-β„€
                                 ∘ transport code loop
                                 ∘ β„€-to-code-base
                                 = succ-β„€
   transport-code-loop-is-succ-β„€ =
    δ ∘ transport code loop ∘ Ρ                  =⟨ I    ⟩
    δ ∘ transport id acl ∘ Ρ                     =⟨refl⟩
    Idtofun cob ∘ Idtofun acl ∘ Idtofun (cob ⁻¹) =⟨ II   ⟩
    Idtofun cob ∘ Idtofun (cob ⁻¹ βˆ™ acl)         =⟨ III  ⟩
    Idtofun (cob ⁻¹ βˆ™ acl βˆ™ cob)                 =⟨ IV   ⟩
    Idtofun succ-β„€-=                             =⟨ V    ⟩
    succ-β„€                                       ∎
     where
      cob = code-on-base
      acl = ap code loop
      Ξ΅ = β„€-to-code-base
      Ξ΄ = code-base-to-β„€
      I   = ap (Ξ» - β†’ Ξ΄ ∘ - ∘ Ξ΅) (transport-ap' id code loop)
      II  = ap (_∘_ (Idtofun cob)) ((Idtofun-βˆ™ ua (cob ⁻¹) acl) ⁻¹)
      III = (Idtofun-βˆ™ ua (cob ⁻¹ βˆ™ acl) cob) ⁻¹

\end{code}

      Using the second computation rule for π•ŠΒΉ-rec

\begin{code}

      IV  = ap Idtofun ((transport-along-= cob acl) ⁻¹
                       βˆ™ (π•ŠΒΉ-rec-on-loop β„€ succ-β„€-=))
      V   = Idtofun-eqtoid ua succ-β„€-≃

   transport-code-loop⁻¹-is-pred-β„€ : code-base-to-β„€
                                   ∘ transport code (loop ⁻¹)
                                   ∘ β„€-to-code-base
                                   ∼ pred-β„€
   transport-code-loop⁻¹-is-pred-β„€ x = equivs-are-lc succ-β„€ succ-β„€-is-equiv Ξ³
    where
     Ξ³ : (succ-β„€ ∘ code-base-to-β„€ ∘ transport code (loop ⁻¹) ∘ β„€-to-code-base) x
       = (succ-β„€ ∘ pred-β„€) x
     Ξ³ = (succ-β„€ ∘ Ξ΄ ∘ t⁻¹ ∘ Ξ΅) x    =⟨ I   ⟩
         (δ ∘ t ∘ Ρ ∘ δ ∘ t⁻¹ ∘ Ρ) x =⟨ II  ⟩
         (δ ∘ t ∘ t⁻¹ ∘ Ρ) x         =⟨ III ⟩
         (δ ∘ Ρ) x                   =⟨ IV  ⟩
         x                           =⟨ V   ⟩
         (succ-β„€ ∘ pred-β„€) x         ∎
      where
       Ξ΅ = β„€-to-code-base
       Ξ΄ = code-base-to-β„€
       t⁻¹ = transport code (loop ⁻¹)
       t   = transport code loop
       I   = happly (transport-code-loop-is-succ-β„€ ⁻¹) ((Ξ΄ ∘ t⁻¹ ∘ Ξ΅) x)
       II  = ap (δ ∘ t) (Idtofun-section code-on-base (t⁻¹ (Ρ x)))
       III = ap Ξ΄ (back-and-forth-transport loop)
       IV  = Idtofun-retraction code-on-base x
       V   = (succ-β„€-is-retraction x) ⁻¹

   transport-code-loop⁻¹-is-pred-β„€' : transport code (loop ⁻¹)
                                    ∼ β„€-to-code-base ∘ pred-β„€ ∘ code-base-to-β„€
   transport-code-loop⁻¹-is-pred-β„€' x =
    transport code (loop ⁻¹) x                   =⟨ I   ⟩
    (Ρ ∘ δ ∘ transport code (loop ⁻¹)) x         =⟨ II  ⟩
    (Ρ ∘ δ ∘ transport code (loop ⁻¹) ∘ Ρ ∘ δ) x =⟨ III ⟩
    (Ξ΅ ∘ pred-β„€ ∘ Ξ΄) x                           ∎
     where
      Ξ΅ = β„€-to-code-base
      Ξ΄ = code-base-to-β„€
      I   = (Idtofun-section code-on-base (transport code (loop ⁻¹) x)) ⁻¹
      II  = ap (Ρ ∘ δ ∘ transport code (loop ⁻¹))
             ((Idtofun-section code-on-base x) ⁻¹)
      III = ap Ξ΅ (transport-code-loop⁻¹-is-pred-β„€ (Ξ΄ x))

   encode : (x : π•ŠΒΉ) β†’ (base = x) β†’ code x
   encode x p = transport code p (β„€-to-code-base 𝟎)

   iterated-path : {X : 𝓦 Μ‡ } {x : X} β†’ x = x β†’ β„• β†’ x = x
   iterated-path p zero     = refl
   iterated-path p (succ n) = p βˆ™ iterated-path p n

   iterated-path-comm : {X : 𝓦 Μ‡ } {x : X} (p : x = x) (n : β„•)
                      β†’ iterated-path p n βˆ™ p = p βˆ™ iterated-path p n
   iterated-path-comm p zero = refl βˆ™ p =⟨ refl-left-neutral ⟩
                               p        =⟨ refl              ⟩
                               p βˆ™ refl ∎
   iterated-path-comm p (succ n) = p βˆ™ iterated-path p n βˆ™ p   =⟨ I  ⟩
                                   p βˆ™ (iterated-path p n βˆ™ p) =⟨ II ⟩
                                   p βˆ™ (p βˆ™ iterated-path p n) ∎
    where
     I  =  βˆ™assoc p (iterated-path p n) p
     II = ap (p βˆ™_) (iterated-path-comm p n)

   loops : β„€ β†’ base = base
   loops 𝟎       = refl
   loops (pos n) = iterated-path loop (succ n)
   loops (neg n) = iterated-path (loop ⁻¹) (succ n)

   module _
           (fe : funext 𝓀₀ 𝓀)
          where

    open import UF.Lower-FunExt

    loops-lemma : (_βˆ™ loop) ∘ loops ∘ pred-β„€ = loops
    loops-lemma = dfunext fe h
     where
      h : (k : β„€) β†’ loops (pred-β„€ k) βˆ™ loop = loops k
      h 𝟎 = loop ⁻¹ βˆ™ refl βˆ™ loop =⟨ refl              ⟩
            loop ⁻¹ βˆ™ loop        =⟨ left-inverse loop ⟩
            refl                  ∎
      h (pos n) = g n
       where
        g : (n : β„•) β†’ loops (pred-β„€ (pos n)) βˆ™ loop = loops (pos n)
        g zero     = iterated-path-comm loop zero
        g (succ n) = iterated-path-comm loop (succ n)
      h (neg n) =
       loop ⁻¹ βˆ™ (loop ⁻¹ βˆ™ iterated-path (loop ⁻¹) n) βˆ™ loop =⟨ I'   ⟩
       loop ⁻¹ βˆ™ (iterated-path (loop ⁻¹) n βˆ™ loop ⁻¹) βˆ™ loop =⟨ II'  ⟩
       loop ⁻¹ βˆ™ iterated-path (loop ⁻¹) n βˆ™ (loop ⁻¹ βˆ™ loop) =⟨ III' ⟩
       loop ⁻¹ βˆ™ iterated-path (loop ⁻¹) n                    ∎
        where
         I'   = ap (Ξ» - β†’ loop ⁻¹ βˆ™ - βˆ™ loop)
                 ((iterated-path-comm (loop ⁻¹) n) ⁻¹)
         II'  = βˆ™assoc (loop ⁻¹) (iterated-path (loop ⁻¹) n βˆ™ loop ⁻¹) loop
              βˆ™ ap (loop ⁻¹ βˆ™_)
                 (βˆ™assoc (iterated-path (loop ⁻¹) n) (loop ⁻¹) loop)
              βˆ™ (βˆ™assoc (loop ⁻¹) (iterated-path (loop ⁻¹) n)
                  (loop ⁻¹ βˆ™ loop)) ⁻¹
         III' = ap ((loop ⁻¹ βˆ™ iterated-path (loop ⁻¹) n) βˆ™_)
                 (left-inverse loop)

    transport-loops-lemma : transport (Ξ» - β†’ code - β†’ base = -) loop
                             (loops ∘ code-base-to-β„€)
                          = (loops ∘ code-base-to-β„€)
    transport-loops-lemma =
     transport (Ξ» - β†’ code - β†’ base = -) loop f                     =⟨ I   ⟩
     transport (Ξ» - β†’ base = -) loop ∘ f ∘ transport code (loop ⁻¹) =⟨ II  ⟩
     (_βˆ™ loop) ∘ f ∘ transport code (loop ⁻¹)                       =⟨ III ⟩
     (_βˆ™ loop) ∘ loops ∘ Ξ΄ ∘ Ξ΅ ∘ pred-β„€ ∘ Ξ΄                         =⟨ IV  ⟩
     (_βˆ™ loop) ∘ loops ∘ pred-β„€ ∘ Ξ΄                                 =⟨ V   ⟩
     loops ∘ δ                                                      ∎
      where
       Ξ΅ : β„€ β†’ code base
       Ξ΅ = β„€-to-code-base
       Ξ΄ : code base β†’ β„€
       Ξ΄ = code-base-to-β„€
       f : code base β†’ base = base
       f = loops ∘ δ
       I   = transport-along-β†’ code (_=_ base) loop f
       II  = refl
       III = ap ((_βˆ™ loop) ∘ f ∘_)
              (dfunext (lower-funext 𝓀₀ 𝓀 fe) transport-code-loop⁻¹-is-pred-β„€')
       IV  = ap (Ξ» - β†’ (_βˆ™ loop) ∘ loops ∘ - ∘ pred-β„€ ∘ Ξ΄)
              (dfunext (lower-funext 𝓀₀ 𝓀 fe) (Idtofun-retraction code-on-base))
       V   = ap (_∘ δ) loops-lemma


    open π•ŠΒΉ-induction (Ξ» - β†’ code - β†’ base = -)
                      (loops ∘ code-base-to-β„€)
                      transport-loops-lemma

    decode : (x : π•ŠΒΉ) β†’ code x β†’ base = x
    decode = π•ŠΒΉ-induction

    decode-encode : (x : π•ŠΒΉ) (p : base = x) β†’ decode x (encode x p) = p
    decode-encode base refl =
     decode base (encode base refl)                       =⟨refl⟩
     decode base (transport code refl (β„€-to-code-base 𝟎)) =⟨refl⟩
     decode base (β„€-to-code-base 𝟎)                       =⟨ I    ⟩
     loops (code-base-to-β„€ (β„€-to-code-base 𝟎))            =⟨ II   ⟩
     loops 𝟎                                              =⟨refl⟩
     refl                                                 ∎
      where

\end{code}

       Using the first computation rule for π•ŠΒΉ-induction

\begin{code}

       I  = happly π•ŠΒΉ-induction-on-base (β„€-to-code-base 𝟎)
       II = ap loops (Idtofun-retraction code-on-base 𝟎)

    open import UF.Retracts

    Ξ©π•ŠΒΉ-is-set : is-set (base = base)
    Ξ©π•ŠΒΉ-is-set = subtypes-of-sets-are-sets' (encode base)
                  (sections-are-lc (encode base)
                   ((decode base) , (decode-encode base)))
                   (transport is-set (code-on-base ⁻¹) β„€-is-set)

  module π•ŠΒΉ-induction'
          {π“₯ : Universe}
          (A : π•ŠΒΉ β†’ π“₯ Μ‡ )
          (a : A base)
          (l : transport A loop a = a)
          (fe : funext 𝓀₀ 𝓀)
          (ua : is-univalent 𝓀₀)
         where

   open π•ŠΒΉ-induction A a l

   π•ŠΒΉ-induction-on-loop' : transport (Ξ» - β†’ transport A loop - = -)
                            π•ŠΒΉ-induction-on-base (apd π•ŠΒΉ-induction loop)
                         = l
   π•ŠΒΉ-induction-on-loop' = π•ŠΒΉ-induction-on-loop (Ξ©π•ŠΒΉ-is-set ua fe)

   π•ŠΒΉ-induction-comp' : (π•ŠΒΉ-induction base , apd π•ŠΒΉ-induction loop)
                      =[ Ξ£ y κž‰ A base , transport A loop y = y ] (a , l)
   π•ŠΒΉ-induction-comp' = π•ŠΒΉ-induction-comp (Ξ©π•ŠΒΉ-is-set ua fe)

\end{code}