Martin Escardo. 2018, 2023, 2024, 2026.

An incarnation of the delay monad.

The short 2018-2024 code was from from SquashedCantor, moved here on
16th September 2026.

\begin{code}

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

open import UF.FunExt

module TypeTopology.DelayMonad (fe : FunExt) where

open import CoNaturals.Type
open import CoNaturals.UniversalProperty fe
open import MLTT.Plus-Properties
open import MLTT.Spartan
open import MLTT.Two-Properties
open import Naturals.Sequence fe
open import Naturals.UniversalProperty
open import Notation.CanonicalMap
open import UF.Base
open import UF.Embeddings
open import UF.Equiv
open import UF.EquivalenceExamples
open import UF.Sets
open import UF.Sets-Properties
open import UF.Singleton-Properties
open import UF.Subsingletons
open import UF.Subsingletons-FunExt
open import UF.Subsingletons-Properties

private
 fe' : Fun-Ext
 fe' {𝓀} {π“₯} = fe 𝓀 π“₯

\end{code}

A delayed element of X is a "time" u : β„•βˆž together with a partial
element of X, which is defined when u is finite.

\begin{code}

𝔻 : 𝓀 Μ‡ β†’ 𝓀 Μ‡
𝔻 X = Ξ£ u κž‰ β„•βˆž , (is-finite u β†’ X)

𝔻-time : {X : 𝓀 Μ‡ } β†’ 𝔻 X β†’ β„•βˆž
𝔻-time (u , Ο€) = u

𝔻-value : {X : 𝓀 Μ‡ } (𝕕 : 𝔻 X) β†’ is-finite (𝔻-time 𝕕) β†’ X
𝔻-value (u , Ο€) = Ο€

\end{code}

The following two abbreviations for the transport of finiteness, moved
here from SquashedCantor on 17th September 2026, are used repeatedly
below.

\begin{code}

transport-finite : {u v : β„•βˆž} (p : u = v) β†’ is-finite u β†’ is-finite v
transport-finite = transport is-finite

transport-finite⁻¹ : {u v : β„•βˆž} (p : u = v) β†’ is-finite v β†’ is-finite u
transport-finite⁻¹ = transport⁻¹ is-finite

transport-value : (X : 𝓀 Μ‡ ) {u v : β„•βˆž}
                  (p : u = v)
                β†’ (is-finite u β†’ X)
                β†’ (is-finite v β†’ X)
transport-value X = transport (Ξ» - β†’ is-finite - β†’ X)

\end{code}

Added 20th December 2023.

The delay monad structure.

\begin{code}

η𝔻 : {X : 𝓀 Μ‡ } β†’ X β†’ 𝔻 X
η𝔻 x = (Zero , Ξ» _ β†’ x)

δ𝔻 : {X : 𝓀 Μ‡ } β†’ 𝔻 X β†’ 𝔻 X
δ𝔻 (u , f) = (Succ u , f ∘ is-finite-down u)

\end{code}

TODO. Prove the (wild) monad laws.

Added 9th January 2024.

\begin{code}

𝔻-functor : {X : 𝓀 Μ‡ } {Y : π“₯ Μ‡ }
          β†’ (X β†’ Y)
          β†’ (𝔻 X β†’ 𝔻 Y)
𝔻-functor f (u , Ο€) = (u , f ∘ Ο€)

𝔻-functor-id : {X : 𝓀 Μ‡ }
             β†’ 𝔻-functor (𝑖𝑑 X) ∼ 𝑖𝑑 (𝔻 X)
𝔻-functor-id d = refl

𝔻-functor-∘ : {X : 𝓀 Μ‡ } {Y : π“₯ Μ‡ } {Z : 𝓦 Μ‡ }
              (f : X β†’ Y) (g : Y β†’ Z)
            β†’ 𝔻-functor (g ∘ f) = 𝔻-functor g ∘ 𝔻-functor f
𝔻-functor-∘ f g = refl

𝔻-functor-id-= : {X : 𝓀 Μ‡ }
               β†’ 𝔻-functor (𝑖𝑑 X) = 𝑖𝑑 (𝔻 X)
𝔻-functor-id-= = refl

𝔻-functor-∘-= : {X : 𝓀 Μ‡ } {Y : π“₯ Μ‡ } {Z : 𝓦 Μ‡ }
                (f : X β†’ Y) (g : Y β†’ Z)
               β†’ 𝔻-functor (g ∘ f) = 𝔻-functor g ∘ 𝔻-functor f
𝔻-functor-∘-= f g = refl

𝔻-is-set : {X : 𝓀 Μ‡ }
         β†’ is-set X
         β†’ is-set (𝔻 X)
𝔻-is-set {𝓀} {X} X-is-set = Ξ£-is-set
                             (β„•βˆž-is-set fe')
                             (Ξ» u β†’ Ξ -is-set fe' (Ξ» Ο† β†’ X-is-set))

to-𝔻-= : {X : 𝓀 Μ‡ }
          (u u' : β„•βˆž)
          (Ο€  : is-finite u  β†’ X)
          (Ο€' : is-finite u' β†’ X)
        β†’ (Ξ£ p κž‰ u = u' , Ο€ = Ο€' ∘ transport-finite p)
        β†’ (u , Ο€) =[ 𝔻 X ] (u' , Ο€')
to-𝔻-= {𝓀} {X} u u Ο€ Ο€ (refl , refl) = refl

from-𝔻-= : {X : 𝓀 Μ‡ }
            (u u' : β„•βˆž)
            (Ο€  : is-finite u  β†’ X)
            (Ο€' : is-finite u' β†’ X)
          β†’ (u , Ο€) =[ 𝔻 X ] (u' , Ο€')
          β†’ Ξ£ p κž‰ u = u' , (Ο€ = Ο€' ∘ transport-finite p)
from-𝔻-= {𝓀} {X} u u Ο€ Ο€ refl = (refl , refl)

\end{code}

Added 16th September 2026.

A delayed element is either its value, when the time is zero, or the
delayed element with the time decreased by one.

\begin{code}

𝔻-out : {X : 𝓀 Μ‡ } β†’ 𝔻 X β†’ X + 𝔻 X
𝔻-out (u , Ο€) = 𝟚-equality-cases
                 (Ξ» (z : is-Zero u)
                       β†’ inl (Ο€ (Zero-is-finite' fe' u z)))
                 (Ξ» (p : is-positive u)
                       β†’ inr (Pred u , Ο€ ∘ is-finite-up' fe' u))

𝔻-outβ‚€ : {X : 𝓀 Μ‡ } (u : β„•βˆž) (Ο€ : is-finite u β†’ X) (z : is-Zero u)
       β†’ 𝔻-out (u , Ο€) = inl (Ο€ (Zero-is-finite' fe' u z))
𝔻-outβ‚€ u Ο€ = 𝟚-equality-casesβ‚€

𝔻-out₁ : {X : 𝓀 Μ‡ } (u : β„•βˆž) (Ο€ : is-finite u β†’ X) (p : is-positive u)
       β†’ 𝔻-out (u , Ο€) = inr (Pred u , Ο€ ∘ is-finite-up' fe' u)
𝔻-out₁ u Ο€ = 𝟚-equality-cases₁

\end{code}

We now show that the type 𝔻 X is a final coalgebra of the functor X + (-),
with the structure map 𝔻-out defined above.

\begin{code}

is-𝔻-coalgebra-map : {X : 𝓀 Μ‡ } {Y : π“₯ Μ‡ }
                   β†’ (Y β†’ X + Y)
                   β†’ (Y β†’ 𝔻 X)
                   β†’ 𝓀 βŠ” π“₯ Μ‡
is-𝔻-coalgebra-map k h = 𝔻-out ∘ h ∼ +functor id h ∘ k

\end{code}

That is, h is a coalgebra map when the following diagram commutes.

                     k
          Y ------------------> X + Y
          |                       |
          |                       |
        h |                       | X + h
          |                       |
          |                       |
          v                       v
         𝔻 X -----------------> X + 𝔻 X
                   𝔻-out

The map 𝔻-out is an equivalence, with the following inverse 𝔻-in, so
that a coalgebra map can be presented with 𝔻-in in place of it.

\begin{code}

𝔻-in : {X : 𝓀 Μ‡ } β†’ X + 𝔻 X β†’ 𝔻 X
𝔻-in (inl x)       = (Zero , Ξ» _ β†’ x)
𝔻-in (inr (u , Ο€)) = (Succ u , Ο€ ∘ is-finite-down u)

𝔻-out-𝔻-in : {X : 𝓀 Μ‡ } (w : X + 𝔻 X) β†’ 𝔻-out (𝔻-in w) = w
𝔻-out-𝔻-in (inl x) = I
 where
  I = 𝔻-out (Zero , (Ξ» _ β†’ x)) =⟨ 𝔻-outβ‚€ Zero (Ξ» _ β†’ x) refl ⟩
      inl x                    ∎
𝔻-out-𝔻-in (inr (u , Ο€)) = II
 where
  II = 𝔻-out (Succ u , Ο€ ∘ is-finite-down u)                =⟨ IIβ‚€ ⟩
       (inr (Pred (Succ u) ,
        Ο€ ∘ is-finite-down u ∘ is-finite-up' fe' (Succ u))) =⟨ II₁ ⟩
       inr (u , Ο€)                                          ∎
      where
       h : (Ο† : is-finite u)
         β†’ Ο€ (is-finite-down u (is-finite-up' fe' (Succ u) Ο†)) = Ο€ Ο†
       h Ο† = ap Ο€ (being-finite-is-prop fe' u _ _)

       IIβ‚€ = 𝔻-out₁ (Succ u) (Ο€ ∘ is-finite-down u) refl
       II₁ = ap inr (to-𝔻-= _ _ _ _ (refl , dfunext fe' h))

𝔻-in-𝔻-out : {X : 𝓀 Μ‡ } (d : 𝔻 X) β†’ 𝔻-in (𝔻-out d) = d
𝔻-in-𝔻-out (u , Ο€) = 𝟚-equality-cases I II
 where
  I : is-Zero u β†’ 𝔻-in (𝔻-out (u , Ο€)) = (u , Ο€)
  I z = 𝔻-in (𝔻-out (u , Ο€))                     =⟨ ap 𝔻-in (𝔻-outβ‚€ u Ο€ z) ⟩
        𝔻-in (inl (Ο€ (Zero-is-finite' fe' u z))) =⟨ Iβ‚€ ⟩
        (u , Ο€)                                  ∎
       where
        Iβ‚€ = to-𝔻-= _ _ _ _
              (((is-Zero-equal-Zero fe' z)⁻¹) ,
               dfunext fe' (Ξ» Ο† β†’ ap Ο€ (being-finite-is-prop fe' u _ _)))

  II : is-positive u β†’ 𝔻-in (𝔻-out (u , Ο€)) = (u , Ο€)
  II p = 𝔻-in (𝔻-out (u , Ο€))                          =⟨ ap 𝔻-in (𝔻-out₁ u Ο€ p) ⟩
         𝔻-in (inr (Pred u , Ο€ ∘ is-finite-up' fe' u)) =⟨ IIβ‚€ ⟩
         (u , Ο€)                                       ∎
        where
         IIβ‚€ = to-𝔻-= _ _ _ _
                (((positive-equal-Succ fe' p)⁻¹) ,
                 dfunext fe' (Ξ» Ο† β†’ ap Ο€ (being-finite-is-prop fe' u _ _)))

𝔻-out-is-equiv : {X : 𝓀 Μ‡ } β†’ is-equiv (𝔻-out {𝓀} {X})
𝔻-out-is-equiv = qinvs-are-equivs 𝔻-out (𝔻-in , 𝔻-in-𝔻-out , 𝔻-out-𝔻-in)

𝔻-flip : {X : 𝓀 Μ‡ } (d : 𝔻 X) (w : X + 𝔻 X)
       β†’ (𝔻-out d = w) ≃ (d = 𝔻-in w)
𝔻-flip d w = (𝔻-out d = w)              β‰ƒβŸ¨ I ⟩
             (𝔻-out d = 𝔻-out (𝔻-in w)) β‰ƒβŸ¨ II ⟩
             (d = 𝔻-in w)               β– 
            where
             I  = ≃-sym (transport-≃ (Ξ» - β†’ 𝔻-out d = -) (𝔻-out-𝔻-in w))
             II = ≃-sym (ap 𝔻-out , ap-is-equiv 𝔻-out 𝔻-out-is-equiv)

\end{code}

For a coalgebra k : Y β†’ X + Y, we show that the type

  Ξ£ h κž‰ (Y β†’ 𝔻 X) , is-𝔻-coalgebra-map k h

is a singleton, by a chain of type equivalences, as follows, where
item n is established by the definition stepβ‚™ in the code below.

 1. For h : Y β†’ 𝔻 X and y : Y, because 𝔻-out is an equivalence, the type

      𝔻-out (h y) = +functor id h (k y)

    is equivalent to the type

      h y = 𝔻-in (+functor id h (k y)).

 2. A map h : Y β†’ 𝔻 X amounts to a time function t : Y β†’ β„•βˆž together
    with values Ξ½ : Value t, where, for any t : Y β†’ β„•βˆž,

      Value t = (y : Y) β†’ is-finite (t y) β†’ X,

    via h = pair t Ξ½, with

      pair t Ξ½ y = (t y , Ξ½ y).

 3. For y : Y, the element

      𝔻-in (+functor id (pair t Ξ½) (k y)) : 𝔻 X

    is equal, by cases on k y, to the pair

      (time t (k y) , value t Ξ½ (k y)),

    where the functions

      time t    : X + Y β†’ β„•βˆž,
      value t Ξ½ : (w : X + Y) β†’ is-finite (time t w) β†’ X

    give the time Zero and the value x for w = inl x, and the time
    Succ (t y') and the value of Ξ½ at y' for w = inr y', so that, for
    h = pair t Ξ½, the equation of step 1 becomes

      pair t ν y = (time t (k y) , value t ν (k y)).

 4. Splitting the equation of step 3 into a time part and a value part,
    and collecting the time parts, the type of coalgebra maps becomes the
    type of quadruples (t , e , Ξ½ , q), where

      t : Y β†’ β„•βˆž,
      e : t ∼ time* t,
      Ξ½ : Value t,
      q : value-condition t Ξ½ e,

    with time* t y = time t (k y).

 5. The type t ∼ time* t of step 4 is equivalent to the type

      is-homomorphism kΜ… t,

    where kΜ… : Y β†’ πŸ™ + Y is k followed by the map that forgets values,
    because both types are propositions, as β„•βˆž is a set.

 6. The type of pairs (t , e) is a singleton, which amounts to the
    finality of β„•βˆž as a coalgebra of the functor 1 + (-).

 7. Fix t : Y β†’ β„•βˆž and e : t ∼ time* t. A witness that t y is finite is
    a natural number n together with an identification ι n = t y, and
    so a function Ξ½ : Value t amounts to a function a : Ξ  A, whose
    argument is the size n of the witness, where

      A n = (y : Y) β†’ ΞΉ n = t y β†’ X.

 8. For Ξ½ : Value t, the value condition on Ξ½ is equivalent to the
    fixed-point condition

      ν y ψ = value* ν y ψ,

    for all y : Y and all witnesses ψ that t y is finite, where

      value* ν y ψ = value t ν (k y) (e* y ψ)

    and e* y transports such a witness along e y. This condition is
    then split by the size n of ψ into the fixed-point condition at
    size n, for each n : β„•.

 9. For the function a : Ξ  A of step 7 corresponding to Ξ½, the fixed-point
    conditions at sizes 0 and succ n say that

      a 0        = aβ‚€,
      a (succ n) = Οƒ n (a n),

    where the value

      aβ‚€ : A 0

    and the induction step function

      Οƒ : (n : β„•) β†’ A n β†’ A (succ n)

    are defined by cases on k y.

10. That is, the function a is defined by induction from aβ‚€ and Οƒ. By
    the dependent universal property of β„• as a natural numbers object with
    codomain A, for any aβ‚€ : A 0 and any induction step function
    Οƒ : (n : β„•) β†’ A n β†’ A (succ n), there is a unique a : Ξ  A defined by
    induction from them, and so the type

      Ξ£ Ξ½ κž‰ Value t , value-condition t Ξ½ e

    of pairs (Ξ½ , q) is a singleton.

11. The type

      Ξ£ (t , e) κž‰ (Ξ£ t κž‰ (Y β†’ β„•βˆž) , t ∼ time* t) ,
                   Ξ£ Ξ½ κž‰ Value t , value-condition t Ξ½ e,

    to which the type of coalgebra maps is equivalent by steps 1-4, is a
    sum of the singletons of step 10 over the singleton of step 6, and
    hence is a singleton, which completes the proof.

\begin{code}

private
 forget-value : {X : 𝓀 Μ‡ } {Y : π“₯ Μ‡ } β†’ X + Y β†’ πŸ™ {𝓀₀} + Y
 forget-value (inl x) = inl ⋆
 forget-value (inr y) = inr y

module _ {X : 𝓀 Μ‡ } {Y : π“₯ Μ‡ } (k : Y β†’ X + Y) where

 private
  kΜ… : Y β†’ πŸ™ {𝓀₀} + Y
  kΜ… = forget-value ∘ k

  Value : (Y β†’ β„•βˆž) β†’ 𝓀 βŠ” π“₯ Μ‡
  Value t = (y : Y) β†’ is-finite (t y) β†’ X

  time : (Y β†’ β„•βˆž) β†’ X + Y β†’ β„•βˆž
  time t (inl x)  = Zero
  time t (inr y') = Succ (t y')

  time* : (Y β†’ β„•βˆž) β†’ (Y β†’ β„•βˆž)
  time* t y = time t (k y)

  value : (t : Y β†’ β„•βˆž)
        β†’ Value t
        β†’ (w : X + Y)
        β†’ is-finite (time t w)
        β†’ X
  value t Ξ½ (inl x)  Ο† = x
  value t Ξ½ (inr y') Ο† = Ξ½ y' (is-finite-down (t y') Ο†)

  value-inl : (t : Y β†’ β„•βˆž)
              (Ξ½ : Value t)
              (y : Y) (x : X)
            β†’ k y = inl x
            β†’ (Ο† : is-finite (time t (k y)))
            β†’ value t Ξ½ (k y) Ο† = x
  value-inl t Ξ½ y x q = transport⁻¹ E q (Ξ» Ο† β†’ refl)
   where
    E : X + Y β†’ 𝓀 Μ‡
    E w = (Ο† : is-finite (time t w)) β†’ value t Ξ½ w Ο† = x

  value-inr : (t : Y β†’ β„•βˆž)
              (Ξ½ : Value t)
              (y y' : Y)
            β†’ k y = inr y'
            β†’ (Ο† : is-finite (time t (k y))) (s : time t (k y) = Succ (t y'))
            β†’ value t Ξ½ (k y) Ο†
            = Ξ½ y' (is-finite-down (t y') (transport-finite s Ο†))
  value-inr t ν y y' q = transport⁻¹ E q e
   where
    E : X + Y β†’ 𝓀 Μ‡
    E w = (Ο† : is-finite (time t w)) (s : time t w = Succ (t y'))
        β†’ value t Ξ½ w Ο†
        = Ξ½ y' (is-finite-down (t y') (transport-finite s Ο†))

    e : E (inr y')
    e Ο† s = ap (Ξ» - β†’ Ξ½ y' (is-finite-down (t y') -))
               (being-finite-is-prop fe' (Succ (t y'))
                 Ο† (transport-finite s Ο†))

  pair : (t : Y β†’ β„•βˆž) β†’ Value t β†’ (Y β†’ 𝔻 X)
  pair t Ξ½ y = (t y , Ξ½ y)

  coalgebra-condition : (Y β†’ 𝔻 X) β†’ 𝓀 βŠ” π“₯ Μ‡
  coalgebra-condition h = Ξ  y κž‰ Y , h y = 𝔻-in (+functor id h (k y))

\end{code}

This says the following diagram commutes, which is the diagram for
is-𝔻-coalgebra-map with its bottom arrow inverted.

                     k
          Y ------------------> X + Y
          |                       |
          |                       |
        h |                       | X + h
          |                       |
          |                       |
          v                       v
         𝔻 X <----------------- X + 𝔻 X
                   𝔻-in

\begin{code}

  𝔻-in-equation : (t : Y β†’ β„•βˆž)
                  (Ξ½ : Value t)
                  (w : X + Y)
                β†’ 𝔻-in (+functor id (pair t Ξ½) w) = (time t w , value t Ξ½ w)
  𝔻-in-equation t Ξ½ (inl x)  = refl
  𝔻-in-equation t Ξ½ (inr y') = refl

\end{code}

When h is pair t Ξ½, so that h has time t and values Ξ½, the composite of
X + h with 𝔻-in, which is the right-hand and bottom edges of the above
diagram, is the pairing of the time map with the value map.

                      X + pair t Ξ½
          X + Y ----------------------> X + 𝔻 X
               \                          |
                \                         |
                 \                        | 𝔻-in
                  \                       |
                   \                      |
                    \                     v
                     ------------------> 𝔻 X
                    (time t , value t Ξ½)

\begin{code}

  step₁ : (h : Y β†’ 𝔻 X) β†’ is-𝔻-coalgebra-map k h ≃ coalgebra-condition h
  step₁ h = Ξ -cong fe' fe' (Ξ» y β†’ 𝔻-flip (h y) (+functor id h (k y)))

  stepβ‚‚ : (Ξ£ h κž‰ (Y β†’ 𝔻 X) , coalgebra-condition h)
        ≃ (Ξ£ (t , Ξ½) κž‰ (Ξ£ t κž‰ (Y β†’ β„•βˆž) , Value t) ,
             coalgebra-condition (pair t Ξ½))
  stepβ‚‚ = Ξ£-bicong _ _ Ξ Ξ£-distr-≃ (Ξ» h β†’ ≃-refl _)

  step₃ : (t : Y β†’ β„•βˆž) (Ξ½ : Value t) β†’ coalgebra-condition (pair t Ξ½)
        ≃ (Ξ  y κž‰ Y , pair t Ξ½ y = (time t (k y) , value t Ξ½ (k y)))
  step₃ t Ξ½ = Ξ -cong fe' fe'
               (Ξ» y β†’ transport-≃
                       (Ξ» - β†’ pair t Ξ½ y = -)
                       (𝔻-in-equation t Ξ½ (k y)))

  value-condition : (t : Y β†’ β„•βˆž) β†’ Value t β†’ t ∼ time* t β†’ 𝓀 βŠ” π“₯ Μ‡
  value-condition t Ξ½ e = Ξ  y κž‰ Y , transport-value X (e y) (Ξ½ y)
                                  = value t ν (k y)

  stepβ‚„ : (t : Y β†’ β„•βˆž) (Ξ½ : Value t)
        β†’ (Ξ  y κž‰ Y , pair t Ξ½ y = (time t (k y) , value t Ξ½ (k y)))
        ≃ (Ξ£ e κž‰ t ∼ time* t , value-condition t Ξ½ e)
  stepβ‚„ t Ξ½ = (Ξ  y κž‰ Y , pair t Ξ½ y = (time t (k y) , value t Ξ½ (k y))) β‰ƒβŸ¨ I ⟩
              (Ξ  y κž‰ Y , Ξ£ p κž‰ (t y = time* t y) ,
                 transport-value X p (Ξ½ y) = value t Ξ½ (k y))           β‰ƒβŸ¨ II ⟩
              (Ξ£ e κž‰ t ∼ time* t , value-condition t Ξ½ e)                β– 
             where
              I  = Ξ -cong fe' fe' (Ξ» y β†’ Ξ£-=-≃)
              II = Ξ Ξ£-distr-≃

  time-SUCC : (t : Y β†’ β„•βˆž) (w : X + Y)
            β†’ time t w = SUCC (πŸ™+ t (forget-value w))
  time-SUCC t (inl x)  = refl
  time-SUCC t (inr y') = refl

  being-fixed-point-of-time*-is-prop : (t : Y β†’ β„•βˆž) β†’ is-prop (t ∼ time* t)
  being-fixed-point-of-time*-is-prop t = Ξ -is-prop fe' (Ξ» y β†’ β„•βˆž-is-set fe')

  being-homomorphism-is-prop : (t : Y β†’ β„•βˆž) β†’ is-prop (is-homomorphism kΜ… t)
  being-homomorphism-is-prop t =
   Ξ -is-set fe' (Ξ» _ β†’ +-is-set πŸ™ β„•βˆž (props-are-sets πŸ™-is-prop) (β„•βˆž-is-set fe'))

  stepβ‚… : (t : Y β†’ β„•βˆž) β†’ (t ∼ time* t) ≃ is-homomorphism kΜ… t
  stepβ‚… t = logically-equivalent-props-are-equivalent
             (being-fixed-point-of-time*-is-prop t)
             (being-homomorphism-is-prop t)
             f
             g
   where
    f : t ∼ time* t β†’ is-homomorphism kΜ… t
    f e = coalg-mophism← kΜ… t (dfunext fe' (Ξ» y β†’
           t y               =⟨ e y ⟩
           time* t y         =⟨ time-SUCC t (k y) ⟩
           SUCC (πŸ™+ t (kΜ… y)) ∎))

    g : is-homomorphism kΜ… t β†’ t ∼ time* t
    g a y = t y               =⟨ happly (coalg-mophismβ†’ kΜ… t a) y ⟩
            SUCC (πŸ™+ t (kΜ… y)) =⟨ (time-SUCC t (k y))⁻¹ ⟩
            time* t y         ∎

  step₆ : βˆƒ! t κž‰ (Y β†’ β„•βˆž) , t ∼ time* t
  step₆ = equiv-to-singleton
           (Ξ£-cong stepβ‚…)
           (PRED-is-the-homotopy-final-coalgebra kΜ…)

  module _ (t : Y β†’ β„•βˆž) (e : t ∼ time* t) where

   A : β„• β†’ 𝓀 βŠ” π“₯ Μ‡
   A n = (y : Y) β†’ ΞΉ n = t y β†’ X

   step₇ : Value t ≃ ((n : β„•) β†’ A n)
   step₇ = ((y : Y) β†’ is-finite (t y) β†’ X)    β‰ƒβŸ¨ I ⟩
           ((y : Y) (n : β„•) β†’ ΞΉ n = t y β†’ X) β‰ƒβŸ¨ Ξ -flip ⟩
           ((n : β„•) β†’ A n)                    β– 
          where
           I = Ξ -cong fe' fe' (Ξ» y β†’ curry-uncurry fe)

   e* : (y : Y) β†’ is-finite (t y) β†’ is-finite (time* t y)
   e* y = transport-finite (e y)

   value* : Value t β†’ Value t
   value* ν y ψ = value t ν (k y) (e* y ψ)

   value-condition-≃ : (Ξ½ : Value t) β†’ value-condition t Ξ½ e ≃ (Ξ½ β‰ˆ value* Ξ½)
   value-condition-≃ Ξ½ = Ξ -cong fe' fe' IV
    where
     I : (y : Y)
       β†’ (transport-value X (e y) (Ξ½ y) = value t Ξ½ (k y))
       ≃ (Ξ½ y ∘ transport-finite ((e y)⁻¹) = value t Ξ½ (k y))
     I y = transport-≃ (Ξ» - β†’ - = value t Ξ½ (k y))
            (transport-along-β†’' is-finite (e y) (Ξ½ y))

     II : (y : Y)
        β†’ (Ξ½ y ∘ transport-finite ((e y)⁻¹) = value t Ξ½ (k y))
        ≃ (Ξ  Ο† κž‰ is-finite (time t (k y)) ,
             Ξ½ y (transport-finite ((e y)⁻¹) Ο†) = value t Ξ½ (k y) Ο†)
     II y = ≃-funext fe' _ _

     III : (y : Y)
         β†’ (Ξ  Ο† κž‰ is-finite (time t (k y)) ,
              Ξ½ y (transport-finite ((e y)⁻¹) Ο†) = value t Ξ½ (k y) Ο†)
         ≃ (Ξ  ψ κž‰ is-finite (t y) , Ξ½ y ψ = value* Ξ½ y ψ)
     III y =
      (Ξ  Ο† κž‰ is-finite (time t (k y)) ,
         Ξ½ y (transport-finite ((e y)⁻¹) Ο†) = value t Ξ½ (k y) Ο†)   β‰ƒβŸ¨ IIIβ‚€ ⟩
      (Ξ  ψ κž‰ is-finite (t y) ,
         Ξ½ y (transport-finite ((e y)⁻¹) (e* y ψ)) = value* Ξ½ y ψ) β‰ƒβŸ¨ III₁ ⟩
      (Ξ  ψ κž‰ is-finite (t y) , Ξ½ y ψ = value* Ξ½ y ψ)               β– 
      where
       IIIβ‚€ = ≃-sym (Ξ -change-of-variable-≃ fe _ (transport-≃ is-finite (e y)))
       III₁ = Ξ -cong fe' fe' (Ξ» ψ β†’
               transport-≃
                (Ξ» - β†’ - = value* Ξ½ y ψ)
                (ap (ν y) (being-finite-is-prop fe' (t y) _ ψ)))

     IV : (y : Y)
        β†’ (transport-value X (e y) (Ξ½ y) = value t Ξ½ (k y))
        ≃ (Ξ  ψ κž‰ is-finite (t y) , Ξ½ y ψ = value* Ξ½ y ψ)
     IV y =
      (transport-value X (e y) (Ξ½ y) = value t Ξ½ (k y))          β‰ƒβŸ¨ I y ⟩
      (Ξ½ y ∘ transport-finite ((e y)⁻¹) = value t Ξ½ (k y))       β‰ƒβŸ¨ II y ⟩
      (Ξ  Ο† κž‰ is-finite (time t (k y)) ,
         Ξ½ y (transport-finite ((e y)⁻¹) Ο†) = value t Ξ½ (k y) Ο†) β‰ƒβŸ¨ III y ⟩
      (Ξ  ψ κž‰ is-finite (t y) , Ξ½ y ψ = value* Ξ½ y ψ)             β– 

   fixed-point-of-value*-at : Value t β†’ β„• β†’ 𝓀 βŠ” π“₯ Μ‡
   fixed-point-of-value*-at Ξ½ n = Ξ  y κž‰ Y ,
                                  Ξ  p κž‰ (ΞΉ n = t y) ,
                                  ν y (n , p) = value* ν y (n , p)

   fixed-point-of-value*-≃ : (Ξ½ : Value t)
                           β†’ (Ξ½ β‰ˆ value* Ξ½)
                           ≃ (Ξ  n κž‰ β„• , fixed-point-of-value*-at Ξ½ n)
   fixed-point-of-value*-≃ Ξ½ =
    Ξ½ β‰ˆ value* Ξ½                             β‰ƒβŸ¨ I ⟩
    ((y : Y) (n : β„•) (p : ΞΉ n = t y)
        β†’ Ξ½ y (n , p) = value* Ξ½ y (n , p)) β‰ƒβŸ¨ Ξ -flip ⟩
    (Ξ  n κž‰ β„• , fixed-point-of-value*-at Ξ½ n) β– 
    where
     I = Ξ -cong fe' fe' (Ξ» y β†’ curry-uncurry fe)

   stepβ‚ˆ : (Ξ½ : Value t)
         β†’ value-condition t Ξ½ e ≃ (Ξ  n κž‰ β„• , fixed-point-of-value*-at Ξ½ n)
   stepβ‚ˆ Ξ½ =
    value-condition t Ξ½ e                    β‰ƒβŸ¨ value-condition-≃ Ξ½ ⟩
    Ξ½ β‰ˆ value* Ξ½                             β‰ƒβŸ¨ fixed-point-of-value*-≃ Ξ½ ⟩
    (Ξ  n κž‰ β„• , fixed-point-of-value*-at Ξ½ n) β– 

   zero-impossible : (y y' : Y) β†’ k y = inr y' β†’ ΞΉ 0 β‰  t y
   zero-impossible y y' q p = Zero-not-Succ
                               (Zero         =⟨ p ⟩
                                t y          =⟨ e y ⟩
                                time t (k y) =⟨ ap (time t) q ⟩
                                Succ (t y')  ∎)

   succ-impossible : (y : Y) (x : X) β†’ k y = inl x β†’ (n : β„•) β†’ ΞΉ (succ n) β‰  t y
   succ-impossible y x q n p = Succ-not-Zero
                                (ι (succ n)   =⟨ p ⟩
                                 t y          =⟨ e y ⟩
                                 time t (k y) =⟨ ap (time t) q ⟩
                                 Zero         ∎)

   down : (y y' : Y) β†’ k y = inr y' β†’ (n : β„•) β†’ ΞΉ (succ n) = t y β†’ ΞΉ n = t y'
   down y y' q n p = Succ-lc
                      (ι (succ n)   =⟨ p ⟩
                       t y          =⟨ e y ⟩
                       time t (k y) =⟨ ap (time t) q ⟩
                       Succ (t y')  ∎)

   aβ‚€-cases : (y : Y) (w : X + Y) β†’ k y = w β†’ ΞΉ 0 = t y β†’ X
   aβ‚€-cases y (inl x)  q p = x
   aβ‚€-cases y (inr y') q p = 𝟘-elim (zero-impossible y y' q p)

   aβ‚€ : A 0
   aβ‚€ y = aβ‚€-cases y (k y) refl

   aβ‚€-cases-equation : (y : Y) (w : X + Y) (q : k y = w) (p : ΞΉ 0 = t y)
                     β†’ aβ‚€ y p = aβ‚€-cases y w q p
   aβ‚€-cases-equation y w refl p = refl

   Οƒ-cases : (y : Y) (w : X + Y)
           β†’ k y = w β†’ (n : β„•) β†’ A n β†’ ΞΉ (succ n) = t y β†’ X
   Οƒ-cases y (inl x)  q n aβ‚™ p = 𝟘-elim (succ-impossible y x q n p)
   Οƒ-cases y (inr y') q n aβ‚™ p = aβ‚™ y' (down y y' q n p)

   Οƒ : (n : β„•) β†’ A n β†’ A (succ n)
   Οƒ n aβ‚™ y p = Οƒ-cases y (k y) refl n aβ‚™ p

   Οƒ-cases-equation : (y : Y) (w : X + Y) (q : k y = w)
                      (n : β„•) (aβ‚™ : A n) (p : ΞΉ (succ n) = t y)
                    β†’ Οƒ n aβ‚™ y p = Οƒ-cases y w q n aβ‚™ p
   Οƒ-cases-equation y w refl n aβ‚™ p = refl

   value*-at-0-is-aβ‚€ : (Ξ½ : Value t)
                       (y : Y) (p : ι 0 = t y)
                     β†’ value* Ξ½ y (0 , p) = aβ‚€ y p
   value*-at-0-is-aβ‚€ Ξ½ y p = equality-cases (k y) I II
    where
     I : (x : X) β†’ k y = inl x β†’ value* Ξ½ y (0 , p) = aβ‚€ y p
     I x q = value* ν y (0 , p) =⟨ value-inl t ν y x q (e* y (0 , p)) ⟩
             x                  =⟨ (aβ‚€-cases-equation y (inl x) q p)⁻¹ ⟩
             aβ‚€ y p             ∎

     II : (y' : Y) β†’ k y = inr y' β†’ value* Ξ½ y (0 , p) = aβ‚€ y p
     II y' q = 𝟘-elim (zero-impossible y y' q p)

   value*-at-succ-is-Οƒ : (Ξ½ : Value t)
                         (n : β„•) (y : Y) (p : ΞΉ (succ n) = t y)
                       β†’ value* Ξ½ y (succ n , p)
                       = Οƒ n (Ξ» y₁ p₁ β†’ Ξ½ y₁ (n , p₁)) y p
   value*-at-succ-is-Οƒ Ξ½ n y p = equality-cases (k y) I II
    where
     aβ‚™ : A n
     aβ‚™ y₁ p₁ = Ξ½ y₁ (n , p₁)

     I : (x : X) β†’ k y = inl x β†’ value* Ξ½ y (succ n , p) = Οƒ n aβ‚™ y p
     I x q = 𝟘-elim (succ-impossible y x q n p)

     II : (y' : Y) β†’ k y = inr y' β†’ value* Ξ½ y (succ n , p) = Οƒ n aβ‚™ y p
     II y' q = value* Ξ½ y (succ n , p)        =⟨ IIβ‚€ ⟩
               Ξ½ y' (is-finite-down (t y') Ο†) =⟨ II₁ ⟩
               Ξ½ y' (n , down y y' q n p)     =⟨ IIβ‚‚ ⟩
               Οƒ n aβ‚™ y p                     ∎
              where
               Ο† : is-finite (Succ (t y'))
               Ο† = transport-finite (ap (time t) q) (e* y (succ n , p))

               IIβ‚€ = value-inr t Ξ½ y y' q (e* y (succ n , p)) (ap (time t) q)
               II₁ = ap (Ξ½ y') (being-finite-is-prop fe' (t y')
                                 (is-finite-down (t y') Ο†) (n , down y y' q n p))
               IIβ‚‚ = (Οƒ-cases-equation y (inr y') q n aβ‚™ p)⁻¹

   fixed-point-of-value*-at-0-≃ : (Ξ½ : Value t)
                                β†’ fixed-point-of-value*-at Ξ½ 0
                                ≃ (⌜ step₇ ⌝ Ξ½ 0 = aβ‚€)
   fixed-point-of-value*-at-0-≃ Ξ½ =
    fixed-point-of-value*-at Ξ½ 0                           β‰ƒβŸ¨ I ⟩
    (Ξ  y κž‰ Y , Ξ  p κž‰ (ΞΉ 0 = t y) , Ξ½ y (0 , p) = aβ‚€ y p) β‰ƒβŸ¨ ≃-sym II ⟩
    (⌜ step₇ ⌝ Ξ½ 0 = aβ‚€)                                  β– 
     where
      I = Ξ -cong fe' fe' (Ξ» y β†’ Ξ -cong fe' fe' (Ξ» p β†’
           transport-≃ (Ξ» - β†’ Ξ½ y (0 , p) = -) (value*-at-0-is-aβ‚€ Ξ½ y p)))

      II : (⌜ step₇ ⌝ Ξ½ 0 = aβ‚€)
         ≃ (Ξ  y κž‰ Y , Ξ  p κž‰ (ΞΉ 0 = t y) , Ξ½ y (0 , p) = aβ‚€ y p)
      II = ≃-funextβ‚‚ fe' fe' _ _

   fixed-point-of-value*-at-succ-≃
    : (Ξ½ : Value t) (n : β„•)
    β†’ fixed-point-of-value*-at Ξ½ (succ n)
    ≃ (⌜ step₇ ⌝ Ξ½ (succ n) = Οƒ n (⌜ step₇ ⌝ Ξ½ n))
   fixed-point-of-value*-at-succ-≃ Ξ½ n
    = fixed-point-of-value*-at Ξ½ (succ n)             β‰ƒβŸ¨ I ⟩
      (Ξ  y κž‰ Y , Ξ  p κž‰ (ΞΉ (succ n) = t y) ,
         Ξ½ y (succ n , p) = Οƒ n (⌜ step₇ ⌝ Ξ½ n) y p) β‰ƒβŸ¨ II ⟩
      (⌜ step₇ ⌝ Ξ½ (succ n) = Οƒ n (⌜ step₇ ⌝ Ξ½ n))   β– 
     where
      I  = Ξ -cong fe' fe' (Ξ» y β†’ Ξ -cong fe' fe' (Ξ» p β†’
            transport-≃
             (Ξ» - β†’ Ξ½ y (succ n , p) = -)
             (value*-at-succ-is-Οƒ Ξ½ n y p)))
      II = ≃-sym (≃-funextβ‚‚ fe' fe' _ _)

   is-defined-by-induction : ((n : β„•) β†’ A n) β†’ 𝓀 βŠ” π“₯ Μ‡
   is-defined-by-induction a = (a 0 = aβ‚€) Γ— ((n : β„•) β†’ a (succ n) = Οƒ n (a n))

   step₉ : (Ξ½ : Value t)
         β†’ (Ξ  n κž‰ β„• , fixed-point-of-value*-at Ξ½ n)
         ≃ is-defined-by-induction (⌜ step₇ ⌝ Ξ½)
   step₉ Ξ½ =
    (Ξ  n κž‰ β„• , fixed-point-of-value*-at Ξ½ n)             β‰ƒβŸ¨ I ⟩
    (fixed-point-of-value*-at Ξ½ 0
      Γ— (Ξ  n κž‰ β„• , fixed-point-of-value*-at Ξ½ (succ n))) β‰ƒβŸ¨ II ⟩
    is-defined-by-induction (⌜ step₇ ⌝ Ξ½)                β– 
    where
     I  = head-tail-≃ {𝓀 βŠ” π“₯} {fixed-point-of-value*-at Ξ½}
     II = Γ—-cong
           (fixed-point-of-value*-at-0-≃ Ξ½)
           (Ξ -cong fe' fe' (fixed-point-of-value*-at-succ-≃ Ξ½))

   step₁₀ : βˆƒ! Ξ½ κž‰ Value t , value-condition t Ξ½ e
   step₁₀ = equiv-to-singleton (Ξ£-bicong _ _ step₇ Ο•) (β„•-is-nno-dep fe' A aβ‚€ Οƒ)
    where
     Ο• : (Ξ½ : Value t)
       β†’ value-condition t Ξ½ e ≃ is-defined-by-induction (⌜ step₇ ⌝ Ξ½)
     Ο• Ξ½ = value-condition t Ξ½ e                    β‰ƒβŸ¨ stepβ‚ˆ Ξ½ ⟩
           (Ξ  n κž‰ β„• , fixed-point-of-value*-at Ξ½ n) β‰ƒβŸ¨ step₉ Ξ½ ⟩
           is-defined-by-induction (⌜ step₇ ⌝ Ξ½)    β– 

  step₁₁ : βˆƒ! (t , e) κž‰ (Ξ£ t κž‰ (Y β†’ β„•βˆž) , t ∼ time* t) ,
                        Ξ£ Ξ½ κž‰ Value t , value-condition t Ξ½ e
  step₁₁ = Ξ£-is-singleton step₆ (Ξ» (t , e) β†’ step₁₀ t e)

\end{code}

Putting the above steps together, we get our desired result.

\begin{code}

 𝔻-is-final-coalgebra : βˆƒ! h κž‰ (Y β†’ 𝔻 X) , is-𝔻-coalgebra-map k h
 𝔻-is-final-coalgebra = s
  where
   e = (Ξ£ h κž‰ (Y β†’ 𝔻 X) , is-𝔻-coalgebra-map k h)                β‰ƒβŸ¨ by-step₁ ⟩
       (Ξ£ h κž‰ (Y β†’ 𝔻 X) , coalgebra-condition h)                 β‰ƒβŸ¨ stepβ‚‚ ⟩
       (Ξ£ (t , Ξ½) κž‰ (Ξ£ t κž‰ (Y β†’ β„•βˆž) , Value t) ,
                    coalgebra-condition (pair t Ξ½))              β‰ƒβŸ¨ Ξ£-assoc ⟩
       (Ξ£ t κž‰ (Y β†’ β„•βˆž) , Ξ£ Ξ½ κž‰ Value t ,
                         coalgebra-condition (pair t Ξ½))         β‰ƒβŸ¨ by-step₃ ⟩
       (Ξ£ t κž‰ (Y β†’ β„•βˆž) , Ξ£ Ξ½ κž‰ Value t , Ξ  y κž‰ Y ,
          pair t Ξ½ y = (time t (k y) , value t Ξ½ (k y)))        β‰ƒβŸ¨ by-stepβ‚„ ⟩
       (Ξ£ t κž‰ (Y β†’ β„•βˆž) , Ξ£ Ξ½ κž‰ Value t ,
          Ξ£ e κž‰ t ∼ time* t , value-condition t Ξ½ e)             β‰ƒβŸ¨ I ⟩
       (Ξ£ t κž‰ (Y β†’ β„•βˆž) , Ξ£ e κž‰ t ∼ time* t ,
                         Ξ£ Ξ½ κž‰ Value t , value-condition t Ξ½ e)  β‰ƒβŸ¨ II ⟩
       (Ξ£ (t , e) κž‰ (Ξ£ t κž‰ (Y β†’ β„•βˆž) , t ∼ time* t) ,
                     Ξ£ Ξ½ κž‰ Value t , value-condition t Ξ½ e)      β– 
      where
       by-step₁ = Ξ£-cong step₁
       by-step₃ = Ξ£-cong (Ξ» - β†’ Ξ£-cong (step₃ -))
       by-stepβ‚„ = Ξ£-cong (Ξ» - β†’ Ξ£-cong (stepβ‚„ -))
       I        = Ξ£-cong (Ξ» - β†’ Ξ£-flip)
       II       = ≃-sym Ξ£-assoc

   s : is-singleton (Ξ£ h κž‰ (Y β†’ 𝔻 X) , is-𝔻-coalgebra-map k h)
   s = equiv-to-singleton e step₁₁

\end{code}