BoehmStructure

Todd Waugh Ambridge, January 2024

# Structural properties of ternary Boehm encodings

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

open import Integers.Addition renaming (_+_ to _â„€+_)
open import Notation.Order
open import Integers.Order
open import Integers.Type
open import MLTT.Spartan
open import Naturals.Addition renaming (_+_ to _ℕ+_)

open import TWA.Thesis.Chapter5.Integers

module TWA.Thesis.Chapter5.BoehmStructure where

## downLeft, downMid and downRight

downLeft downMid downRight : â„€ → â„€
downLeft  a = a â„€+ a
downMid   a = succâ„€ (downLeft a)
downRight a = succâ„€ (downMid  a)

## downLeft and downRight properties

pred-downMid : (a : â„€) → predâ„€ (downMid a)  downLeft a
pred-downMid a = predsuccâ„€ _

pred-downRight : (a : â„€) → predâ„€ (downRight a)  downMid a
pred-downRight a = predsuccâ„€ _

pred-pred-downRight
 : (a : â„€) → predâ„€ (predâ„€ (downRight a))  downLeft a
pred-pred-downRight a = ap predâ„€ (predsuccâ„€ _) ∙ predsuccâ„€ _

downLeft-monotone' : (a b : â„€) → ((n , _) : a ≀℀ b)
                   → downLeft a +pos (n ℕ+ n)  downLeft b
downLeft-monotone' a b (n , refl)
 = ap ((a â„€+ a) â„€+_) (distributivity-pos-addition n n ⁻Âč)
 ∙ â„€+-rearrangement (a â„€+ a) (pos n) (pos n) ⁻Âč
 ∙ ap (λ - → (- +pos n) +pos n) (â„€+-comm a a)
 ∙ ap (_+pos n)
     (â„€+-assoc a a (pos n)
     ∙ ap (a â„€+_) (â„€+-comm a (pos n))
     ∙ â„€+-assoc a (pos n) a ⁻Âč)
 ∙ â„€+-assoc (a +pos n) a (pos n)

℀≀<-trans : (a b c : â„€) → a ≀℀ b → b <â„€ c → a <â„€ c
℀≀<-trans a b c (m , refl) (n , refl)
 = m ℕ+ n
 , (ap (succâ„€ a â„€+_) (distributivity-pos-addition m n ⁻Âč)
 ∙ â„€+-assoc (succâ„€ a) (pos m) (pos n) ⁻Âč 
 ∙ ap (_+pos n) (â„€-left-succ-pos a m))

downLeft<<downRight : (a b : â„€) → a <â„€ b → downLeft a <â„€ downRight b
downLeft<<downRight a b (n , refl)
 = (succ (succ (succ (n ℕ+ n))))
 , ap (succâ„€ ∘ succâ„€)
     (ap succâ„€
       (ap (_+pos (n ℕ+ n)) (â„€-left-succ a a ⁻Âč)
       ∙ ap ((succâ„€ a â„€+ a) â„€+_) (distributivity-pos-addition n n ⁻Âč)
       ∙ â„€+-rearrangement (succâ„€ a â„€+ a) (pos n) (pos n) ⁻Âč
       ∙ ap (λ - → (- +pos n) +pos n) (â„€+-comm (succâ„€ a) a)
       ∙ ap (_+pos n)
           (â„€+-assoc a (succâ„€ a) (pos n)
         ∙ ap (a â„€+_) (â„€+-comm (succâ„€ a) (pos n))
         ∙ â„€+-assoc a (pos n) (succâ„€ a) ⁻Âč)
       ∙ â„€+-assoc (a +pos n) (succâ„€ a) (pos n))
   ∙ â„€-left-succ (a +pos n) (succâ„€ a +pos n) ⁻Âč
   ∙ ap (_â„€+ (succâ„€ a +pos n)) (â„€-left-succ-pos a n ⁻Âč))

downLeft<downRight
 : (a : â„€) (n : ℕ)
 → rec a downLeft (succ n) <â„€ rec a downRight (succ n)
downLeft<downRight a zero = 1 , refl
downLeft<downRight a (succ n)
 = downLeft<<downRight _ _ (downLeft<downRight a n)

downLeft≀downRight
 : (a : â„€) (n : ℕ) → rec a downLeft n ≀℀ rec a downRight n
downLeft≀downRight a 0 = zero , refl
downLeft≀downRight a (succ n) = <-is-≀ _ _ (downLeft<downRight a n)

downLeft-≀-succ : (a : â„€) → downLeft a ≀℀ downLeft (succâ„€ a)
downLeft-≀-succ a
 = 2 , (ap succâ„€ (â„€-left-succ a a ⁻Âč) ∙ â„€-right-succ (succâ„€ a) a ⁻Âč)

downLeft-monotone : (a b : â„€) → a ≀℀ b → downLeft a ≀℀ downLeft b
downLeft-monotone = ≀-succ-to-monotone downLeft downLeft-≀-succ

downLeftⁿ-monotone : (a b : â„€) (n : ℕ) → a ≀℀ b
                   → rec a downLeft (succ n) ≀℀ rec b downLeft (succ n)
downLeftⁿ-monotone a b 0 a≀b
 = downLeft-monotone a b a≀b
downLeftⁿ-monotone a b (succ n) a≀b
 = downLeft-monotone _ _ (downLeftⁿ-monotone a b n a≀b)

downRight-≀-succ : (a : â„€) → downRight a ≀℀ downRight (succâ„€ a)
downRight-≀-succ a = 2 , ap (succâ„€ ∘ succâ„€) (pr₂ (downLeft-≀-succ a))

downRight-monotone : (a b : â„€) → a ≀℀ b → downRight a ≀℀ downRight b
downRight-monotone = ≀-succ-to-monotone downRight downRight-≀-succ

downRightⁿ-monotone
 : (a b : â„€) (n : ℕ)
 → a ≀℀ b
 → rec a downRight (succ n) ≀℀ rec b downRight (succ n)
downRightⁿ-monotone a b 0 a≀b
 = downRight-monotone a b a≀b
downRightⁿ-monotone a b (succ n) a≀b
 = downRight-monotone _ _ (downRightⁿ-monotone a b n a≀b)

downLeft≀<downRight : (a b : â„€) → a ≀℀ b → downLeft a <â„€ downRight b
downLeft≀<downRight a b a≀b
 = ℀≀<-trans _ _ _ (downLeft-monotone _ _ a≀b) (downLeft<downRight b 0)

downLeft≠downMid : (a b : â„€) → a  b → downLeft a ≠ downMid b
downLeft≠downMid a a refl
 = â„€-less-not-equal (downLeft a) (downMid a)
     (0 , refl)

downLeft≠downRight : (a b : â„€) → a  b → downLeft a ≠ downRight b
downLeft≠downRight a a refl
 = â„€-less-not-equal (downLeft a) (downRight a)
     (1 , refl)

downMid≠downRight : (a b : â„€) → a  b → downMid a ≠ downRight b
downMid≠downRight a a refl
 = â„€-less-not-equal (downMid a) (downRight a)
     (0 , refl)

downRightdownLeft : (a : â„€) → downRight a  downLeft (succâ„€ a)
downRightdownLeft a
 = ap succâ„€ (â„€-left-succ a a ⁻Âč ∙ â„€+-comm (succâ„€ a) a)
 ∙ â„€-left-succ a (succâ„€ a) ⁻Âč

## below and below'

_below_ : â„€ → â„€ → đ“€â‚€ ̇ 
a below b = downLeft b ≀ a ≀ downRight b

downLeft-below  : (a : â„€) → downLeft a below a
downLeft-below  a = (0 , refl) , (2 , refl)

downMid-below   : (a : â„€) → downMid a below a
downMid-below   a = (1 , refl) , (1 , refl)

downRight-below : (a : â„€) → downRight a below a
downRight-below a = (2 , refl) , (0 , refl)

_below'_ : â„€ → â„€ → đ“€â‚€ ̇
a below' b = (a  downLeft b) + (a  downMid b) + (a  downRight b)

below'-implies-below : (a b : â„€) → a below' b → a below b
below'-implies-below .(downLeft  b) b (inl      refl )
 = downLeft-below b
below'-implies-below .(downMid   b) b (inr (inl refl))
 = downMid-below b
below'-implies-below .(downRight b) b (inr (inr refl))
 = downRight-below b

below-implies-below' : (a b : â„€) → a below b → a below' b
below-implies-below' a b ((0 , e) , _)
 = inl (e ⁻Âč)
below-implies-below' a b ((1 , e) , _)
 = (inr ∘ inl) (e ⁻Âč)
below-implies-below' a b ((2 , e) , _)
 = (inr ∘ inr) (e ⁻Âč)
below-implies-below' a b ((succ (succ (succ _)) , _) , (0 , f))
 = (inr ∘ inr) f
below-implies-below' a b ((succ (succ (succ _)) , _) , (1 , f))
 = (inr ∘ inl) (succâ„€-lc f)
below-implies-below' a b ((succ (succ (succ _)) , _) , (2 , f))
 = inl (succâ„€-lc (succâ„€-lc f))
below-implies-below' a b
 ((succ (succ (succ n)) , e) , (succ (succ (succ m)) , f))
 = 𝟘-elim (k≠2 k2)
 where
   k : ℕ
   k = (succ (succ (succ (succ (succ (succ (n ℕ+ m)))))))
   η : downLeft b +pos k  downRight b
   η = ap ((succâ„€ ^ 6) ∘ downLeft b â„€+_)
          (distributivity-pos-addition n m ⁻Âč)
     ∙ ap (succâ„€ ^ 6)
         (â„€+-assoc (downLeft b) (pos n) (pos m) ⁻Âč)
     ∙ ap (succâ„€ ^ 5)
         (â„€-left-succ-pos (downLeft b +pos n) m ⁻Âč)
     ∙ ap (succâ„€ ^ 4)
         (â„€-left-succ-pos (succâ„€ (downLeft b +pos n)) m ⁻Âč)
     ∙ ap (succâ„€ ^ 3)
         (â„€-left-succ-pos ((succâ„€ ^ 2) (downLeft b +pos n)) m ⁻Âč)
     ∙ ap ((succâ„€ ^ 3) ∘ (_+pos m)) e
     ∙ f
   ζ : downLeft b +pos 2  downRight b
   ζ = refl
   k2 : k  2
   k2 = pos-lc (â„€+-lc (pos k) (pos 2) (downLeft b) (η ∙ ζ ⁻Âč))
   k≠2 : k ≠ 2
   k≠2 = λ ()

## upLeft and upRight

upRight : â„€ → â„€
upRight x = sign x (num x /2)

upLeft : â„€ → â„€
upLeft x = upRight (predâ„€ x)

## upLeft and upRight properties

upRight-suc : (a : â„€) → upRight (succâ„€ (succâ„€ a))  succâ„€ (upRight a)
upRight-suc (pos zero) = refl
upRight-suc (pos (succ zero)) = refl
upRight-suc (pos (succ (succ x))) = refl
upRight-suc (negsucc zero) = refl
upRight-suc (negsucc (succ zero)) = refl
upRight-suc (negsucc (succ (succ x))) = refl

upRight-pred : (a : â„€) → upRight (predâ„€ (predâ„€ a))  predâ„€ (upRight a)
upRight-pred (pos 0) = refl
upRight-pred (pos 1) = refl
upRight-pred (pos (succ (succ x))) = refl
upRight-pred (negsucc 0) = refl
upRight-pred (negsucc 1) = refl
upRight-pred (negsucc (succ (succ x))) = refl

upLeft-suc : (a : â„€) → upLeft (succâ„€ (succâ„€ a))  succâ„€ (upLeft a)
upLeft-suc (pos zero) = refl
upLeft-suc (pos (succ zero)) = refl
upLeft-suc (pos (succ (succ x))) = refl
upLeft-suc (negsucc zero) = refl
upLeft-suc (negsucc (succ zero)) = refl
upLeft-suc (negsucc (succ (succ x))) = refl

upLeft-pred : (a : â„€) → upLeft (predâ„€ (predâ„€ a))  predâ„€ (upLeft a)
upLeft-pred = upRight-pred ∘ predâ„€

upRight-succ-pos : (a : ℕ) → upRight (pos a) ≀℀ upRight (succâ„€ (pos a))
upRight-succ-pos 0 = 0 , refl
upRight-succ-pos 1 = 1 , refl
upRight-succ-pos (succ (succ a))
 = m , (â„€-left-succ-pos (pos (a /2)) m ∙ ap succâ„€ (pr₂ IH))
 where
   IH = upRight-succ-pos a
   m = pr₁ IH

upRight-succ-negsucc
 : (a : ℕ) → upRight (negsucc a) ≀℀ upRight (succâ„€ (negsucc a))
upRight-succ-negsucc 0 = 1 , refl
upRight-succ-negsucc 1 = 0 , refl
upRight-succ-negsucc (succ (succ a))
 = m , (â„€-left-pred-pos (negsucc (a /2)) m
       ∙ ap predâ„€ (pr₂ IH)
       ∙ upRight-pred _ ⁻Âč
       ∙ ap (upRight ∘ predâ„€) (predsuccâ„€ _))
 where
   IH = upRight-succ-negsucc a
   m = pr₁ IH

upRight-≀-succ : (a : â„€) → upRight a ≀℀ upRight (succâ„€ a)
upRight-≀-succ = â„€-elim (λ a → upRight a ≀℀ upRight (succâ„€ a))
                   upRight-succ-pos upRight-succ-negsucc

upRight-monotone : (a b : â„€) → a ≀℀ b → upRight a ≀℀ upRight b
upRight-monotone = ≀-succ-to-monotone upRight upRight-≀-succ

upLeft-monotone : (a b : â„€) → a ≀℀ b → upLeft a ≀℀ upLeft b
upLeft-monotone a b (n , refl)
 = upRight-monotone _ _ (n , â„€-left-pred-pos a n)

upRight≀upLeft-succ : (a : â„€) → upRight a  upLeft (succâ„€ a)
upRight≀upLeft-succ a = ap upRight (predsuccâ„€ _ ⁻Âč)

upRight≀upLeft : (a b : â„€) → a <â„€ b → upRight a ≀℀ upLeft b
upRight≀upLeft a b (n      , refl)
 = transport (_≀℀ upLeft (succâ„€ a +pos n)) (upRight≀upLeft-succ a ⁻Âč)
     (upLeft-monotone _ _ (n , refl))

upRight-<-succ-succ : (a : â„€) → upRight a <â„€ upRight (succâ„€ (succâ„€ a))
upRight-<-succ-succ a
 = transport (upRight a <â„€_) (upRight-suc a ⁻Âč) (0 , refl)

upRight-<<' : (a b : â„€) (n : ℕ) → (a +pos succ n)  predâ„€ b
            → upRight a <â„€ upRight b
upRight-<<' a b zero e
 = transport (λ - → upRight a <â„€ upRight -)
     (ap succâ„€ e ∙ succpredâ„€ _)
     (upRight-<-succ-succ a)
upRight-<<' a b (succ n) e
 = transport (λ - → upRight a <â„€ upRight -)
     (ap succâ„€ e ∙ succpredâ„€ _)
     (℀≀-trans _ _ _ (upRight-<-succ-succ a)
       (upRight-monotone _ _
       (succ n , ap succâ„€ (â„€-left-succ-pos (succâ„€ a) n
               ∙ ap succâ„€ (â„€-left-succ-pos a n)))))

upRight-<< : (a b : â„€) → a <â„€ predâ„€ b → upRight a <â„€ upRight b
upRight-<< a b (n , e)
 = upRight-<<' a b n (â„€-left-succ-pos a n ⁻Âč ∙ e)

upLeft-<< : (a b : â„€) → a <â„€ b → upLeft a <â„€ upRight b
upLeft-<< a b (n , refl)
 = upRight-<< (predâ„€ a) b
     (n , (ap (_+pos n) (succpredâ„€ _) ∙ predsuccâ„€ _ ⁻Âč
         ∙ ap predâ„€ (â„€-left-succ-pos a n ⁻Âč)))

## above and above'

_above_ : â„€ → â„€ → đ“€â‚€ ̇ 
b above a = upLeft a ≀℀ b ≀℀ upRight a

_above'_ : â„€ → â„€ → đ“€â‚€ ̇
a above' b = (a  upLeft b) + (a  upRight b)

upLeft--+-pos : (a : ℕ) → (upLeft (pos a)  upRight (pos a))
                         + (succâ„€ (upLeft (pos a))  upRight (pos a))
upLeft--+-pos 0 = inr refl
upLeft--+-pos 1 = inl refl
upLeft--+-pos (succ (succ a))
 = Cases (upLeft--+-pos a)
     (λ l → inl (upLeft-suc (pos a) ∙ ap succâ„€ l))
     (λ r → inr (ap succâ„€ (upLeft-suc (pos a) ∙ r)))

upLeft--+-negsucc
 : (a : ℕ)
 → (upLeft (negsucc a)  upRight (negsucc a))
 + (succâ„€ (upLeft (negsucc a))  upRight (negsucc a))
upLeft--+-negsucc 0 = inl refl
upLeft--+-negsucc 1 = inr refl
upLeft--+-negsucc (succ (succ a))
 = Cases (upLeft--+-negsucc a)
      (λ l → inl (upLeft-pred (negsucc a) ∙ ap predâ„€ l))
      (λ r → inr (predsuccâ„€ _ ⁻Âč ∙ ap predâ„€ r))

upLeft--+
 : (a : â„€) → (upLeft a  upRight a) + (succâ„€ (upLeft a)  upRight a)
upLeft--+ = â„€-elim _ upLeft--+-pos upLeft--+-negsucc

upLeft≀upRight : (a : â„€) → upLeft a ≀℀ upRight a
upLeft≀upRight a = upRight-monotone _ _ (1 , succpredâ„€ _)

upLeft-upRight-mono : (a b : â„€) → a ≀℀ b → upLeft a ≀℀ upRight b
upLeft-upRight-mono a b a≀b
 = ℀≀-trans _ _ _ (upLeft-monotone _ _ a≀b) (upLeft≀upRight b)

upLeft≀upRightⁿ : (a : â„€) (n : ℕ) → rec a upLeft n ≀℀ rec a upRight n
upLeft≀upRightⁿ a 0 = ℀≀-refl a
upLeft≀upRightⁿ a 1 = upLeft≀upRight a
upLeft≀upRightⁿ a (succ (succ n))
 = upLeft-upRight-mono _ _ (upLeft≀upRightⁿ a (succ n))

upLeft-above : (a : â„€) → upLeft a above a
upLeft-above a = ℀≀-refl _ , upLeft≀upRight a

upRight-above : (a : â„€) → upRight a above a
upRight-above a = upLeft≀upRight a , ℀≀-refl _

above'-implies-above : (a b : â„€) → a above' b → a above b
above'-implies-above .(upLeft  b) b (inl refl) = upLeft-above b
above'-implies-above .(upRight b) b (inr refl) = upRight-above b

above-implies-above' : (a b : â„€) → a above b → a above' b
above-implies-above' a b (l≀a , a≀r)
 = Cases (℀≀-split (upLeft b) a l≀a)
     (λ l<a → Cases (℀≀-split a (upRight b) a≀r)
       (λ a<r → 𝟘-elim
                  (Cases (upLeft--+ b)
                    (λ e → â„€-less-not-bigger-or-equal (upLeft b) a
                             l<a
                             (transport (a ≀℀_) (e ⁻Âč) a≀r))
                    (λ e → â„€-less-not-bigger-or-equal a (upRight b)
                             a<r
                             (transport (_≀℀ a) e l<a))))
       inr)
     (inl ∘ _⁻Âč)

## Relationship between below and above

upRight-downLeft-pos : (b : ℕ) → pos b  upRight (downLeft (pos b))
upRight-downLeft-pos 0 = refl
upRight-downLeft-pos (succ b)
 = ap succâ„€ (upRight-downLeft-pos b)
 ∙ upRight-suc (downLeft (pos b)) ⁻Âč
 ∙ ap (upRight ∘ succâ„€) (â„€-left-succ-pos (pos b) b ⁻Âč)

upRight-downLeft-negsucc
 : (b : ℕ) → negsucc b  upRight (downLeft (negsucc b))
upRight-downLeft-negsucc 0 = refl
upRight-downLeft-negsucc (succ b)
 = ap predâ„€ (upRight-downLeft-negsucc b)
 ∙ upRight-pred (downLeft (negsucc b)) ⁻Âč
 ∙ ap (upRight ∘ predâ„€) (â„€-left-pred-negsucc (negsucc b) b ⁻Âč)

upRight-downMid-pos : (b : ℕ) → pos b  upRight (downMid (pos b))
upRight-downMid-pos 0 = refl
upRight-downMid-pos (succ b)
 = ap succâ„€ (upRight-downMid-pos b)
 ∙ upRight-suc (downMid (pos b)) ⁻Âč
 ∙ ap (upRight ∘ succâ„€ ∘ succâ„€) (â„€-left-succ-pos (pos b) b ⁻Âč)

upRight-downMid-negsucc
 : (b : ℕ) → negsucc b  upRight (downMid (negsucc b))
upRight-downMid-negsucc 0 = refl
upRight-downMid-negsucc (succ b)
 = ap predâ„€ (upRight-downMid-negsucc b)
 ∙ upRight-pred (downMid (negsucc b)) ⁻Âč
 ∙ ap (upRight ∘ predâ„€) (predsuccâ„€ _)
 ∙ ap upRight (â„€-left-pred-negsucc (negsucc b) b ⁻Âč)
 ∙ ap upRight (succpredâ„€ _ ⁻Âč)

upRight-downLeft : (a : â„€) → a  upRight (downLeft a)
upRight-downLeft
 = â„€-elim _ upRight-downLeft-pos upRight-downLeft-negsucc

upRight-downMid : (a : â„€) → a  upRight (downMid a)
upRight-downMid = â„€-elim _ upRight-downMid-pos upRight-downMid-negsucc

upRight-downRight : (a : â„€) → succâ„€ a  upRight (downRight a)
upRight-downRight a = ap succâ„€ (upRight-downLeft a)
                    ∙ upRight-suc (downLeft a) ⁻Âč

upLeft-downLeft : (a : â„€) → succâ„€ (upLeft (downLeft a))  a
upLeft-downLeft a = upRight-suc (predâ„€ (downLeft a)) ⁻Âč
                  ∙ ap (upRight ∘ succâ„€) (succpredâ„€ _)
                  ∙ upRight-downMid a ⁻Âč

upLeft-downMid : (a : â„€) → upLeft (downMid a)  a
upLeft-downMid a = ap upRight (pred-downMid a) ∙ upRight-downLeft a ⁻Âč

upLeft-downRight : (a : â„€) → upLeft (downRight a)  a
upLeft-downRight a
 = ap upRight (pred-downRight a) ∙ upRight-downMid a ⁻Âč

below-implies-above-dL : (b : â„€) → b above (downLeft b)
below-implies-above-dL b
 = (1 , upLeft-downLeft  b)
 , (0 , upRight-downLeft b)

below-implies-above-dM : (b : â„€) → b above (downMid b)
below-implies-above-dM b
 = (0 , upLeft-downMid  b)
 , (0 , upRight-downMid b)

below-implies-above-dR : (b : â„€) → b above (downRight b)
below-implies-above-dR b
 = (0 , upLeft-downRight  b)
 , (1 , upRight-downRight b)

below'-implies-above : (a b : â„€) → a below' b → b above a
below'-implies-above .(downLeft  b) b (inl refl)
 = below-implies-above-dL b
below'-implies-above .(downMid   b) b (inr (inl refl))
 = below-implies-above-dM b
below'-implies-above .(downRight b) b (inr (inr refl))
 = below-implies-above-dR b

dL-transform : (a : â„€) → downLeft (succâ„€ a)  (succâ„€ ^ 2) (downLeft a)
dL-transform a = â„€-left-succ a (succâ„€ a) ∙ ap succâ„€ (â„€-right-succ a a)

dL-transform-pred
 : (a : â„€) → downLeft (predâ„€ a)  (predâ„€ ^ 2) (downLeft a)
dL-transform-pred a
 = â„€-left-pred a (predâ„€ a) ∙ ap predâ„€ (â„€-right-pred a a)

dR-transform
 : (a : â„€) → downRight (succâ„€ a)  (succâ„€ ^ 2) (downRight a)
dR-transform a = ap (succâ„€ ^ 2) (dL-transform a)

dR-transform-pred
 : (a b : â„€) → downRight (predâ„€ a)  (predâ„€ ^ 2) (downRight a)
dR-transform-pred a b = ap (succâ„€ ^ 2) (dL-transform-pred a)
                      ∙ ap succâ„€ (succpredâ„€ _)
                      ∙ succpredâ„€ _
                      ∙ predsuccâ„€ _ ⁻Âč
                      ∙ ap predâ„€ (predsuccâ„€ _ ⁻Âč)

downLeft-upRight : (b : â„€) → downLeft (upRight b) ≀℀ b
downLeft-upRight
 = â„€-elim _ downLeft-upRight-pos downLeft-upRight-negsucc
 where
  downLeft-upRight-pos : (b : ℕ) → downLeft (upRight (pos b)) ≀℀ pos b
  downLeft-upRight-pos 0 = 0 , refl
  downLeft-upRight-pos 1 = 1 , refl
  downLeft-upRight-pos (succ (succ b))
   = transport (_≀℀ succâ„€ (succâ„€ (pos b)))
      ((ap downLeft (upRight-suc (pos b))
        ∙ dL-transform (upRight (pos b))) ⁻Âč)
      (℀≀-succⁿ-inj _ _ 2 (downLeft-upRight-pos b))
  downLeft-upRight-negsucc
   : (b : ℕ) → downLeft (upRight (negsucc b)) ≀℀ negsucc b
  downLeft-upRight-negsucc 0 = 1 , refl
  downLeft-upRight-negsucc 1 = 0 , refl
  downLeft-upRight-negsucc (succ (succ b))
   = transport (_≀℀ predâ„€ (predâ„€ (negsucc b)))
       ((ap downLeft (upRight-pred (negsucc b))
         ∙ dL-transform-pred (upRight (negsucc b))) ⁻Âč)
       (℀≀-predⁿ-inj _ _ 2 (downLeft-upRight-negsucc b))

downLeft-upLeft  : (b : â„€) → downLeft (upLeft b) ≀℀ b
downLeft-upLeft b
 = ℀≀-trans _ _ _
     (downLeft-monotone _ _ (upLeft≀upRight b))
     (downLeft-upRight b)

downRight-upLeft-pos : (b : ℕ) → pos b ≀℀ downRight (upLeft (pos b))
downRight-upLeft-pos 0 = 0 , refl
downRight-upLeft-pos 1 = 1 , refl
downRight-upLeft-pos (succ (succ b))
 = transport ((succâ„€ ^ 2) (pos b) ≀℀_)
    ((ap downRight (upLeft-suc (pos b))
      ∙ dR-transform (upLeft (pos b))) ⁻Âč)
    (℀≀-succⁿ-inj _ _ 2 (downRight-upLeft-pos b))

downRight-upLeft-negsucc
 : (b : ℕ) → negsucc b ≀℀ downRight (upLeft (negsucc b))
downRight-upLeft-negsucc 0 = 1 , refl
downRight-upLeft-negsucc 1 = 0 , refl
downRight-upLeft-negsucc (succ (succ b))
 = transport ((predâ„€ ^ 2) (negsucc b) ≀℀_)
     ((ap downRight (upLeft-pred (negsucc b))
      ∙ dR-transform-pred (upLeft (negsucc b)) (pos b)) ⁻Âč)
     (℀≀-predⁿ-inj _ _ 2 (downRight-upLeft-negsucc b)) 

downRight-upLeft : (b : â„€) → b ≀℀ downRight (upLeft b)
downRight-upLeft
 = â„€-elim _ downRight-upLeft-pos downRight-upLeft-negsucc

downRight-upRight : (b : â„€) → b ≀℀ downRight (upRight b)
downRight-upRight b
 = ℀≀-trans _ _ _
     (downRight-upLeft b)
     (downRight-monotone _ _ (upLeft≀upRight b))

above-upRight : (b : â„€) → b below (upRight b)
above-upRight b = downLeft-upRight b , downRight-upRight b

above-upLeft : (b : â„€) → b below (upLeft b)
above-upLeft b = downLeft-upLeft  b , downRight-upLeft b

above'-implies-below : (a b : â„€) → a above' b → b below a
above'-implies-below .(upLeft  b) b (inl refl) = above-upLeft b
above'-implies-below .(upRight b) b (inr refl) = above-upRight b

above-implies-below : (a b : â„€) → a above b → b below a
above-implies-below a b
 = above'-implies-below a b ∘ above-implies-above' a b

below-implies-above : (a b : â„€) → a below b → b above a
below-implies-above a b
 = below'-implies-above a b ∘ below-implies-below' a b

above-downLeft : (a : â„€) → a above (downLeft a)
above-downLeft a
 = below-implies-above (downLeft a) a (downLeft-below a)

above-downMid : (a : â„€) → a above (downMid a)
above-downMid a
 = below-implies-above (downMid a) a (downMid-below a)

above-downRight : (a : â„€) → a above (downRight a)
above-downRight a
 = below-implies-above (downRight a) a (downRight-below a)