----------------------------------------------------------------------------------------------------
-- Some taboos about Cnf having limits of bounded sequences
----------------------------------------------------------------------------------------------------

{-# OPTIONS --cubical --safe #-}

module CantorNormalForm.LimitsAndTaboos where

open import Cubical.Foundations.Prelude
open import Cubical.Foundations.HLevels
open import Cubical.Data.Sigma
open import Cubical.Data.Sum as Sum
open import Cubical.Data.Empty
  renaming (rec to ⊥-rec)
open import Cubical.Relation.Nullary
open import Cubical.Data.Nat as N
  using ( ; suc ; injSuc)
open import Cubical.Data.Nat.Order as N using ()
open import Cubical.Data.Bool
  renaming (false to ff; true to tt)
  hiding (_≤_; _≥_)


open import PropTrunc
open import General-Properties
open import CantorNormalForm.Base
open import CantorNormalForm.Wellfoundedness
open import CantorNormalForm.Classifiability
open import CantorNormalForm.Addition
open import CantorNormalForm.Subtraction

open import BooleanSequence
open import Simulations Cnf _≤_

--
-- We have showed that Cnf does not have limits.
--
import CantorNormalForm.Classifiability
  using (Cnf-does-not-have-limits)


--
-- Assuming LEM, every nonempty subset of CNFs has a minimal element.
-- (A consequence of Theorem 10.4.3 in the HoTT book)
--
minimal-witness : LEM  (P : Cnf  Type)  (∀ x  isProp (P x))
    x  P x  Σ[ a  Cnf ] P a × (∀ z  P z  a  z)
minimal-witness lem P pvP = wf-ind step
 where
  A Q : Cnf  Type
  A x =  z  P z  x  z
  Q x = P x  Σ[ y  Cnf ] P y × A y
  pvA :  x  isProp (A x)
  pvA x = isPropΠ2  _ _  isProp⟨≤⟩)
  pvPA :  x  isProp (P x × A x)
  pvPA x = isProp× (pvP x) (pvA x)
  ΣPA-isProp : isProp (Σ[ y  Cnf ] P y × A y)
  ΣPA-isProp (y₀ , py₀ , ay₀) (y₁ , py₁ , ay₁) = Σ≡Prop pvPA y₀≡y₁
   where
    y₀≤y₁ : y₀  y₁
    y₀≤y₁ = ay₀ y₁ py₁
    y₁≤y₀ : y₁  y₀
    y₁≤y₀ = ay₁ y₀ py₀
    y₀≡y₁ : y₀  y₁
    y₀≡y₁ = ≤-antisym y₀≤y₁ y₁≤y₀
  step :  x  (∀ y  y < x  Q y)  Q x
  step x h px with lem (A x) (pvA x)
  ... | yes a = x , px , a
  ... | no ¬a = ∥-∥rec ΣPA-isProp claim₁ claim₀
   where
    claim₀ :  Σ[ z  Cnf ] ¬ (P z  x  z) 
    claim₀ = LEM-¬∀-∃¬ _  z  isPropΠ  _  isProp⟨≤⟩)) lem ¬a
    claim₁ : (Σ[ z  Cnf ] ¬ (P z  x  z))  Σ[ y  Cnf ] P y × A y
    claim₁ (z , f) = goal
     where
      z<x : z < x
      z<x with <-tri z x
      ... | inl z<x = z<x
      ... | inr z≥x = ⊥-rec (f  _  z≥x))
      pz : P z
      pz with lem (P z) (pvP z)
      ... | yes p = p
      ... | no ¬p = ⊥-rec (f λ p  ⊥-rec (¬p p))
      goal : Σ[ y  Cnf ] P y × A y
      goal = h z z<x pz


--
-- Therefore, assuming LEM, we can compute suprema of bounded sequences.
--
LEM-computes-sup : LEM
   (f :   Cnf) (b : Cnf)  (∀ i  f i  b)
   Σ[ a  Cnf ] a is-sup-of f
LEM-computes-sup lem f = minimal-witness lem P pvP
 where
  P : Cnf  Type
  P b =  i  f i  b
  pvP :  b  isProp (P b)
  pvP _ = isPropΠ  _  isProp⟨≤⟩)

--
-- If Cnf has limits of bounded increasing sequences, then WLPO holds.
-- The proof is essentially the same as the one of the no go theorem.
--

-- We first specialise the jumping sequence s ↑ to CNF

_↑ : (  Bool)    Cnf
(s )  0      = 𝟎
(s ) (suc i) = if (least-index-true s i) then ω else ((s ) i + 𝟏)

s↑-spec-<ω :  s  (n : )  (∀ i  i N.< n  s i  ff)  (s ) n < ω
s↑-spec-<ω s 0 p = <₁
s↑-spec-<ω s (suc n) p = goal
   where
    claim₀ :  i  i N.≤ n  s i  ff
    claim₀ i i≤n = p i (N.suc-≤-suc i≤n)
    claim₁ : least-index-true s n  ff
    claim₁ = least-index-true-spec-ff s n claim₀
    claim₂ : (s ) (suc n)  (s ) n + 𝟏
    claim₂ = cong (if_then ω else (s ) n + 𝟏) claim₁
    IH : (s ) n < ω
    IH = s↑-spec-<ω s n  i i<n  p i (N.≤-suc i<n))
    claim₃ : (s ) n + 𝟏 < ω
    claim₃ = ω^-is-add-indecomposable ((s ) n) 𝟏 IH (<₂ <₁)
    goal : (s ) (suc n) < ω
    goal = subst (_< ω) (sym claim₂) claim₃

s↑-inc :  s  is-<-increasing (s )
s↑-inc s i with least-index-true s i  tt
... | yes p = subst ((s ) i <_) (sym claim₀) claim₁
   where
    claim₀ : (s ) (suc i)  ω
    claim₀ = cong (if_then ω else ((s ) i + 𝟏)) p
    q :  j  j N.< i  s j  ff
    q = least-index-true-case-tt s i p
    claim₁ : (s ) i < ω
    claim₁ = s↑-spec-<ω s i q
... | no ¬p = goal
   where
    p : least-index-true s i  ff
    p = ¬true→false _ ¬p
    claim₀ : (s ) (suc i)  (s ) i + 𝟏
    claim₀ = cong (if_then ω else ((s ) i + 𝟏)) p
    claim₁ : (s ) i < (s ) i + 𝟏
    claim₁ = <+𝟏
    goal : (s ) i < (s ) (suc i)
    goal = subst ((s ) i <_) (sym claim₀) claim₁

s↑-inc' :  s  (i j : )  i N.< j  (s ) i < (s ) j
s↑-inc' s i 0 i<0 = ⊥-rec (N.¬-<-zero i<0)
s↑-inc' s i (suc j) (0 , i+1≡j+1) = subst  x  (s ) i < (s ) x) i+1≡j+1 (s↑-inc s i)
s↑-inc' s i (suc j) (suc k , k+i+1≡j) = <-trans IH fact
   where
    IH : (s ) i < (s ) j
    IH = s↑-inc' s i j (k , injSuc k+i+1≡j)
    fact : (s ) j < (s ) (suc j)
    fact = s↑-inc s j

s↑-inc-≤ :  s i j  i N.≤ j  (s ) i  (s ) j
s↑-inc-≤ s i j (0 , i≡j) = inr (cong (s ) (sym i≡j))
s↑-inc-≤ s i j (suc k , k+i+1≡j) = inl (s↑-inc' s i j (k , N.+-suc _ _  k+i+1≡j))

s↑-spec->ω :  s i  s i  tt  ω < (s ) (suc (suc i))
s↑-spec->ω s i si≡tt = goal
   where
    n : 
    n = fst (least-index-true-spec-tt s i si≡tt)
    n≤i : n N.≤ i
    n≤i = fst (snd (least-index-true-spec-tt s i si≡tt))
    p : least-index-true s n  tt
    p = snd (snd (least-index-true-spec-tt s i si≡tt))
    claim₀ : (s ) (suc n)  ω
    claim₀ = cong (if_then ω else ((s ) n + 𝟏)) p
    n+1<i+2 : suc n N.< suc (suc i)
    n+1<i+2 = N.suc-≤-suc (N.suc-≤-suc n≤i)
    claim₁ : (s ) (suc n) < (s ) (suc (suc i))
    claim₁ = s↑-inc' s (suc n) (suc (suc i)) n+1<i+2
    goal : ω < (s ) (suc (suc i))
    goal = ≤∘<-in-< (inr claim₀) claim₁

s↑-bounded-by-ω+i :  s i  (s ) i < ω + NtoC i
s↑-bounded-by-ω+i s 0 = <₁
s↑-bounded-by-ω+i s (suc i) = cases case₀ case₁
   where
    cases : {b : Bool} {A : Type}
           (b  tt  A)  (b  ff  A)  A
    cases {ff} f g = g refl
    cases {tt} f g = f refl
    case₀ : least-index-true s i  tt  (s ) (suc i) < ω + NtoC (suc i)
    case₀ p = ≤∘<-in-< (inr (sym claim₀)) claim₁
     where
      claim₀ : (s ) (suc i)  ω
      claim₀ = cong (if_then ω else ((s ) i + 𝟏)) p
      claim₁ : ω < ω + NtoC (suc i)
      claim₁ = <₃ refl <₁
    case₁ : least-index-true s i  ff  (s ) (suc i) < ω + NtoC (suc i)
    case₁ p = ≤∘<-in-< (inr (sym claim₀)) claim₁
     where
      claim₀ : (s ) (suc i)  (s ) i + 𝟏
      claim₀ = cong (if_then ω else ((s ) i + 𝟏)) p
      IH : (s ) i < ω + NtoC i
      IH = s↑-bounded-by-ω+i s i
      lemma :  i x  x < ω + NtoC i  x + 𝟏 < ω + NtoC (suc i)
      lemma 0 x p with x<ω-finite (x + 𝟏) (ω^-is-add-indecomposable x 𝟏 p (<₂ <₁))
      ... | (n , x+1=n) = subst (_< ω + 𝟏) (sym x+1=n) (<-trans (NtoC<ω n) (<₃ refl <₁))
      lemma (suc i) x p with <-tri x ω
      lemma (suc i) x p | inl x<ω = <-trans (ω^-is-add-indecomposable x 𝟏 x<ω (<₂ <₁)) (+r-is-<-monotone ω 𝟎 (NtoC (suc (suc i))) <₁)
      lemma (suc i) x p | inr x≥ω with x<ω+ω-finite x x≥ω (<-trans p (+r-is-<-monotone ω (NtoC (suc i)) ω (NtoC<ω (suc i))))
      lemma (suc i)x p | inr x≥ω | (n , x=ω+n) = subst  z  z + 𝟏 < ω + NtoC (suc (suc i))) (sym x=ω+n) (subst2 (_<_) (+-is-assoc ω (NtoC n) 𝟏) (cong (ω +_) (sym (NtoC⟨suc⟩≡1+NtoC (suc i)))) (+r-is-<-monotone ω (NtoC n + 𝟏) (𝟏 + NtoC (suc i)) (subst (_< _) (sym (NtoC⟨suc⟩≡1+NtoC n)  sym (ω^𝟎+-is-+𝟏 (NtoC n) _)) (+r-is-<-monotone 𝟏 _ _ (+-left-cancellation-< ω (NtoC n) (NtoC (suc i)) (subst (_< (ω + NtoC (suc i))) x=ω+n p))))))
      claim₁ : (s ) i + 𝟏 < ω + NtoC (suc i)
      claim₁ = (lemma i ((s ) i) IH)

s↑-bounded-by-ω+ω :  s i  (s ) i < ω + ω
s↑-bounded-by-ω+ω s i = <-trans (s↑-bounded-by-ω+i s i) (+r-is-<-monotone ω (NtoC i) ω (NtoC<ω i))

s↑-bounded-below-by-i :  s i  (s ) (suc i) > NtoC i
s↑-bounded-below-by-i s i with least-index-true s i
s↑-bounded-below-by-i s ℕ.zero | ff = <₁
s↑-bounded-below-by-i s (suc i) | ff = subst (_< (s ) (suc i) + 𝟏) (sym (NtoC⟨suc⟩≡NtoC+𝟏 i)) (succ-is-<-monotone (s↑-bounded-below-by-i s i))
s↑-bounded-below-by-i s i | tt = NtoC<ω i


s↑-spec->ω' :  s i n  s i  tt  i N.< n  (s ) (suc n)  ω + NtoC (n N.∸ i)
s↑-spec->ω' s i n si=tt i<n with least-index-true-spec-tt s i si=tt
s↑-spec->ω' s i n si=tt i<n | (j , (j≤i , lit=tt)) = (≤-trans (+r-is-≤-monotone ω (NtoC (n N.∸ i)) (NtoC (n N.∸ j)) (NtoC-is-≤-monotone (∸-lemma n i j j≤i))) (s↑-spec->ω'-lemma s j n lit=tt (N.≤<-trans j≤i i<n)))  where
  ∸-lemma :  n i j  j N.≤ i  n N.∸ i N.≤ n N.∸ j
  ∸-lemma n i j (ℕ.zero , p) = subst  z  n N.∸ z N.≤ n N.∸ j) p N.≤-refl
  ∸-lemma n ℕ.zero j (suc k , p) = ⊥-rec (N.snotz p)
  ∸-lemma n (suc i) j (suc k , p) = N.≤-trans (lem n i) (∸-lemma n i j (k , (injSuc p)))
    where
      lem :  n i  n N.∸ suc i N.≤ n N.∸ i
      lem ℕ.zero ℕ.zero = N.≤-refl
      lem ℕ.zero (suc i) = N.≤-refl
      lem (suc n) ℕ.zero = 1 , refl
      lem (suc n) (suc i) = lem n i
  s↑-spec->ω'-lemma :  s i n  least-index-true s i  tt  i N.< n  (s ) (suc n)  ω + NtoC (n N.∸ i)
  s↑-spec->ω'-lemma s i n p i<n with least-index-true s n  tt
  s↑-spec->ω'-lemma s i n p i<n | yes eq = ⊥-rec (true≢false (sym (least-index-true-is-true s i p)  least-index-true-case-tt s n eq i i<n))
  s↑-spec->ω'-lemma s i ℕ.zero p i<n | no ¬eq = ⊥-rec (N.¬-<-zero i<n)
  s↑-spec->ω'-lemma s i (suc n) p (ℕ.zero , q) | no ¬eq = subst2  z z'  z'  (if z then ω else (s ) (suc n) + 𝟏)) (sym (¬true→false (least-index-true s (suc n)) ¬eq)) (sym (+-is-assoc ω (NtoC (n N.∸ i)) 𝟏)  cong (ω +_) (lemma' (injSuc q))) (subst2  z z'  z  (if z' then ω else ((s ) n + 𝟏)) + 𝟏) (+-is-assoc ω (NtoC (n N.∸ i)) 𝟏) (sym p  cong (least-index-true s) (injSuc q)) (inr (cong (ω +_) (sym (lemma'' (injSuc q))))))
    where
      lemma'' :  {n} {i}  i  n  NtoC (n N.∸ i) + 𝟏  𝟏
      lemma'' {n} {i} i=n = cong  z  NtoC (z N.∸ i) + 𝟏) (sym i=n)  cong  z  NtoC z + 𝟏) (N.n∸n i)
      lemma' :  {n} {i}  i  n  NtoC (n N.∸ i) + 𝟏  NtoC (suc n N.∸ i)
      lemma' {n} {i} i=n = subst  z  NtoC (n N.∸ z) + 𝟏  NtoC (suc n N.∸ z)) (sym i=n) (subst2  z z'   NtoC z + 𝟏  NtoC z') (sym (N.n∸n n)) (sym (N.+∸ 1 n)) refl)

  s↑-spec->ω'-lemma s i (suc n) p (suc k , q) | no ¬eq = subst2  z z'  z'  (if z then ω else (s ) (suc n) + 𝟏)) (sym (¬true→false (least-index-true s (suc n)) ¬eq)) (sym (+-is-assoc ω (NtoC (n N.∸ i)) 𝟏)  cong (ω +_) (lemma q)) (succ-is-≤-monotone (s↑-spec->ω'-lemma s i n p (k , (injSuc q)))) where
   lemma :  {n} {i} {k}  suc (k N.+ suc i)  suc n  NtoC (n N.∸ i) + 𝟏  NtoC (suc n N.∸ i)
   lemma {n} {i} {k} q = sym (NtoC⟨suc⟩≡NtoC+𝟏 (n N.∸ i))  cong NtoC eq where
        eq = suc (n N.∸ i)
               ≡⟨ sym (cong  z  suc (z N.∸ i)) (injSuc q)) 
             suc ((k N.+ suc i) N.∸ i)
               ≡⟨ cong  z  suc (z N.∸ i)) (N.+-suc k i) 
             suc ((suc k N.+ i) N.∸ i)
               ≡⟨ cong suc (N.+∸ (suc k) i) 
             suc (suc k)
               ≡⟨ sym (N.+∸ (suc (suc k)) i) 
             suc (suc (k N.+ i)) N.∸ i
               ≡⟨ cong  z  suc z N.∸ i) (sym (N.+-suc k i)) 
             (suc k N.+ suc i) N.∸ i
               ≡⟨ cong  z  z N.∸ i) q 
             suc n N.∸ i
               


s↑-spec->ω-back :  s n  ω < (s ) (suc n)  Σ[ i   ] (i N.≤ n) × (s i  tt)
s↑-spec->ω-back s n ω<s↑n = let (k , s↑n=ω+k) = x<ω+ω-finite ((s ) (suc n)) (inl ω<s↑n) (s↑-bounded-by-ω+ω s (suc n)) in (n N.∸ k) , N.∸-≤ n k , (least-index-true-is-true s (n N.∸ k) (s↑n=ω+k→lit⟨n-k⟩=tt s n k s↑n=ω+k))
  where
    s↑n=ω→lit⟨n⟩=tt :  s n  (s ) (suc n)  ω  least-index-true s n  tt
    s↑n=ω→lit⟨n⟩=tt s n p with least-index-true s n
    ... | tt = refl
    ... | ff = ⊥-rec (lim-is-not-suc {ω}  (NtoC , NtoC↑) , ω-is-lim-of-NtoC  (subst is-strong-suc p (_ , (succ-calc-strong-suc ((s ) n)))))

    s↑n=ω+k→lit⟨n-k⟩=tt :  s n k  (s ) (suc n)  ω + NtoC k  least-index-true s (n N.∸ k)  tt
    s↑n=ω+k→lit⟨n-k⟩=tt s n ℕ.zero p = s↑n=ω→lit⟨n⟩=tt s n p
    s↑n=ω+k→lit⟨n-k⟩=tt s ℕ.zero (suc k) p with s 0
    ... | ff = ⊥-rec (<-irrefl (<-trans (subst (_< ω) p (fin<ω 𝟏 refl)) (<₃ refl <₁)))
    ... | tt = refl
    s↑n=ω+k→lit⟨n-k⟩=tt s (suc n) (suc k) p = s↑n=ω+k→lit⟨n-k⟩=tt s n k (step s n p)
      where
        step :  s n  (s ) (suc (suc n))  ω + NtoC (suc k)  (s ) (suc n)  ω + NtoC k
        step s n p with least-index-true s (suc n)
        step s n p | tt = ⊥-rec (lim-is-not-suc {ω}  (NtoC , NtoC↑) , ω-is-lim-of-NtoC 
                                                    (subst is-strong-suc ((sym (+-is-assoc ω (NtoC k) 𝟏)  cong (ω +_) (sym (NtoC⟨suc⟩≡NtoC+𝟏 k)))  sym p)
                                                                         (ω + NtoC k , succ-calc-strong-suc (ω + NtoC k))))
        step s n p | ff with least-index-true s n
        step s n p | ff | tt = succ-injective (p  cong (ω +_) (NtoC⟨suc⟩≡NtoC+𝟏 k)  +-is-assoc ω (NtoC k) 𝟏)
        step s n p | ff | ff = succ-injective (p  cong (ω +_) (NtoC⟨suc⟩≡NtoC+𝟏 k)  +-is-assoc ω (NtoC k) 𝟏)

s↑-spec-≥ω :  s i  s i  tt  (s ) (suc i)  ω
s↑-spec-≥ω s i si≡tt = subst ((s ) (suc i) ≥_) s↑j+1≡ω s↑j+1≤s↑i+1
 where
  j : 
  j = fst (least-index-true-spec-tt s i si≡tt)
  j≤i : j N.≤ i
  j≤i = fst (snd (least-index-true-spec-tt s i si≡tt))
  p : least-index-true s j  tt
  p = snd (snd (least-index-true-spec-tt s i si≡tt))
  s↑j+1≡ω : (s ) (suc j)  ω
  s↑j+1≡ω = cong (if_then ω else ((s ) j + 𝟏)) p
  j+1≤i+1 : suc j N.≤ suc i
  j+1≤i+1 = N.suc-≤-suc j≤i
  s↑j+1≤s↑i+1 : (s ) (suc j)  (s ) (suc i)
  s↑j+1≤s↑i+1 = s↑-inc-≤ s _ _ j+1≤i+1

s↑-spec-≥ω+n :  s i  s i  tt   n  (s ) (suc i N.+ n)  ω + NtoC n
s↑-spec-≥ω+n s i si≡tt 0 = subst (_≥ ω) (sym (cong (s ) (N.+-zero (suc i)))) (s↑-spec-≥ω s i si≡tt)
s↑-spec-≥ω+n s i si≡tt (suc n) = goal
 where
  IH : (s ) (suc i N.+ n)  ω + NtoC n
  IH = s↑-spec-≥ω+n s i si≡tt n
  claim₀ : (s ) (suc i N.+ n) < (s ) (suc (suc i N.+ n))
  claim₀ = s↑-inc s (suc i N.+ n)
  claim₁ : (s ) (suc (suc i N.+ n))  (s ) (suc i N.+ suc n)
  claim₁ = cong (s ) (sym (N.+-suc (suc i) n))
  claim₂ : (s ) (suc i N.+ suc n) > ω + NtoC n
  claim₂ = ≤∘<-in-< IH (subst ((s ) (suc i N.+ n) <_) claim₁ claim₀)
  claim₃ : (s ) (suc i N.+ suc n)  ω + NtoC n + 𝟏
  claim₃ = <→s≤ claim₂
  claim₄ : ω + NtoC n + 𝟏  ω + (NtoC n + 𝟏)
  claim₄ = sym (+-is-assoc ω (NtoC n) 𝟏)
  claim₅ : ω + (NtoC n + 𝟏)  ω + (NtoC (suc n))
  claim₅ = cong (ω +_) (sym (NtoC⟨suc⟩≡NtoC+𝟏 n))
  goal : (s ) (suc i N.+ suc n)  ω + NtoC (suc n)
  goal = subst ((s ) (suc i N.+ suc n) ≥_) (claim₄  claim₅) claim₃

s↑-spec-<ω-back :  s n  (∀ i  (s ) i  ω + NtoC n)   i  s i  ff
s↑-spec-<ω-back s n s↑≤ω+n i = ¬true→false (s i) ¬si≡tt
 where
  ¬si≡tt : ¬ (s i  tt)
  ¬si≡tt si≡tt = <-irrefl (<∘≤-in-< claim₁ claim₂)
   where
    claim₀ : (s ) (suc i N.+ n)  ω + NtoC n
    claim₀ = s↑-spec-≥ω+n s i si≡tt n
    claim₁ : (s ) (suc (suc i N.+ n)) > ω + NtoC n
    claim₁ = ≤∘<-in-< claim₀ (s↑-inc s (suc i N.+ n))
    claim₂ : (s ) (suc (suc i N.+ n))  ω + NtoC n
    claim₂ = s↑≤ω+n (suc (suc i N.+ n))


having-limits-implies-WLPO :
    ((f :   Cnf) (b : Cnf)  (∀ i  f i < b)  is-<-increasing f 
     Σ[ a  Cnf ] a is-sup-of f)
   WLPO
having-limits-implies-WLPO h s = goal
 where
  a : Cnf
  a = fst (h (s ) (ω + ω) (s↑-bounded-by-ω+ω s) (s↑-inc s))
  a-is-sup : a is-sup-of (s )
  a-is-sup = snd (h (s ) (ω + ω) (s↑-bounded-by-ω+ω s) (s↑-inc s))

  case-ω<a :  i  s i  tt  ω < a
  case-ω<a i si≡tt = <∘≤-in-< (s↑-spec->ω s i si≡tt) (fst a-is-sup (suc (suc i)))
  case₀ : a  ω   k  s k  ff
  case₀ a≡ω k = ¬true→false (s k)  sk≡tt  <-irreflexive (sym a≡ω) (case-ω<a k sk≡tt))

  case-a≡ω : (∀ i  s i  ff)  a  ω
  case-a≡ω p = ≤-antisym a≤ω ω≤a
   where
    a≤ω : a  ω
    a≤ω = snd a-is-sup ω λ i  inl (s↑-spec-<ω s i  k _  p k))
    lemma :  x  x < ω  Σ[ i   ] x < (s ) i
    lemma 𝟎 <₁ = 1 , <∘≤-in-< <₁ (inr (cong (if_then ω else ((s ) 0 + 𝟏)) (p 0)))
    lemma x@(ω^ 𝟎 + b [ r ]) (<₂ u) = suc i , claim
     where
      IH : Σ[ i   ] b < (s ) i
      IH = lemma b (<-trans (right< 𝟎 b r) (<₂ u))
      i : 
      i = fst IH
      b<s↑i : b < (s ) i
      b<s↑i = snd IH
      claim₀ : least-index-true s i  ff
      claim₀ = least-index-true-spec-ff s i  k _  p k)
      claim₁ : (s ) (suc i)  (s ) i + 𝟏
      claim₁ = cong (if_then ω else ((s ) i + 𝟏)) claim₀
      claim₂ : b + 𝟏 < (s ) i + 𝟏
      claim₂ = succ-is-<-monotone b<s↑i
      claim₃ : b + 𝟏  x
      claim₃ = ω^𝟎+-is-+𝟏 b r
      claim : x < (s ) (suc i)
      claim = ≤∘<-in-< (inr claim₃) (<∘≤-in-< claim₂ (inr claim₁))
    lemma (ω^ ω^ _ + _ [ _ ] + _ [ _ ]) (<₂ (<₂ ()))
    lemma (ω^ ω^ _ + _ [ _ ] + _ [ _ ]) (<₂ (<₃ _ ()))
    ¬a<ω : ¬ (a < ω)
    ¬a<ω a<ω = ≤→≯ (fst a-is-sup i) a<s↑i
     where
      i : 
      i = fst (lemma a a<ω)
      a<s↑i : a < (s ) i
      a<s↑i = snd (lemma a a<ω)
    ω≤a : ω  a
    ω≤a = ≮→≥ ¬a<ω
  case₁ : ¬ a  ω  ¬ (∀ k  s k  ff)
  case₁ ¬a≡ω p = ¬a≡ω (case-a≡ω p)

  goal : (∀ k  s k  ff)  (¬ (∀ k  s k  ff))
  goal = cases case₀ case₁
   where
    cases : {x y : Cnf} {A B : Type}
           (x  y  A)  (¬ x  y  B)  A  B
    cases {x} {y} f g with Cnf-is-discrete x y
    ... | yes x≡y = inl (f x≡y)
    ... | no ¬x≡y = inr (g ¬x≡y)

MP→limits-unique : MP 
                    f {f↑ : is-<-increasing f} g {g↑ : is-<-increasing g}  {x y : Cnf} 
                   x  y  x is-lim-of (f , f↑)  y is-lim-of (g , g↑)  f simulated-by g
MP→limits-unique mp f {f↑} g {g↑} {x} {y} x≤y xlimf ylimq i =  map-snd  {n}  h-spec-tt n) (mp h λ p  <-irrefl (≤∘<-in-< (≤-trans x≤y (y≤fi p)) (fi<x p))) 
  where
    h :   Bool
    h k = Sum.rec  _   ff)  _  tt) (<-tri (g k) (f i))
    h-spec-tt :  k  h k  tt  f i  g k
    h-spec-tt k hk=tt with <-tri (g k) (f i)
    ... | inl _ = ⊥-rec (false≢true hk=tt)
    ... | inr fi≤gk  = fi≤gk
    h-spec-ff :  k  h k  ff  g k < f i
    h-spec-ff k hk=ff with <-tri (g k) (f i)
    ... | inl gk<fi = gk<fi
    ... | inr _ = ⊥-rec (true≢false hk=ff)
    ∀khk=ff : ¬ (Σ[ n   ] (h n  tt))  (k : )  h k  ff
    ∀khk=ff p k = Dec→Stable (h k  ff) λ hk≠ff  p (k , ¬false→true (h k) hk≠ff)
    ∀kgk<fi : ¬ (Σ[ n   ] (h n  tt))  (k : )  g k < f i
    ∀kgk<fi p k = h-spec-ff k (∀khk=ff p k)
    y≤fi : ¬ (Σ[ n   ] (h n  tt))  y  f i
    y≤fi p = snd ylimq (f i) λ k  <-in-≤ (∀kgk<fi p k)
    fi<x : ¬ (Σ[ n   ] (h n  tt))  f i < x
    fi<x p = <∘≤-in-< (f↑ i) (fst xlimf (suc i))