changeset 949:057d3309ed9d

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 04 Aug 2024 13:05:12 +0900
parents e5288029f850
children 5c75fc6dfe59
files DPP.agda ModelChecking.agda RBTree.agda logic.agda nat.agda
diffstat 5 files changed, 1427 insertions(+), 177 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DPP.agda	Sun Aug 04 13:05:12 2024 +0900
@@ -0,0 +1,206 @@
+{-# OPTIONS --cubical-compatible #-}
+-- {-# OPTIONS --cubical-compatible --safe #-}
+module DPP where
+
+open import Level renaming (zero to Z ; suc to succ)
+
+open import Data.Nat hiding (compare)
+open import Data.Nat.Properties as NatProp
+open import Data.Maybe
+-- open import Data.Maybe.Properties
+open import Data.Empty
+open import Data.List
+-- open import Data.Tree.Binary
+-- open import Data.Product
+open import Function as F hiding (const)
+open import Relation.Binary
+open import Relation.Binary.PropositionalEquality
+open import Relation.Nullary
+open import logic
+open import Data.Unit hiding ( _≟_ ) -- ;  _≤?_ ; _≤_)
+open import Relation.Binary.Definitions
+
+open import ModelChecking
+
+
+--
+-- single process implemenation
+--
+
+
+record Phil  : Set  where
+   field 
+      ptr : ℕ
+      left right : AtomicNat
+
+init-Phil : Phil
+init-Phil = record { ptr = 0 ; left = init-AtomicNat ; right = init-AtomicNat }
+
+pickup_rfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
+pickup_lfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
+eating : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
+putdown_rfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
+putdown_lfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
+thinking : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
+
+pickup_rfork p next = f_set (Phil.right p) (Phil.ptr p) ( λ f → pickup_lfork record p { right = f } next )
+pickup_lfork p next = f_set (Phil.left p) (Phil.ptr p) ( λ f → eating record p { left = f } next )
+eating p next = putdown_rfork p next
+putdown_rfork p next = f_set (Phil.right p) 0 ( λ f → putdown_lfork record p { right = f } next )
+putdown_lfork p next = f_set (Phil.left p) 0 ( λ f → thinking record p { left = f } next )
+thinking p next = next p
+
+run : Phil
+run = pickup_rfork record { ptr = 1 ; left = record { ptr = 2 ; value = 0 } ; right = record { ptr = 3 ; value = 0 } } $ λ p → p
+
+--
+-- Coda Gear
+--
+
+data Code : Set  where
+   C_nop : Code
+   C_cas_int : Code
+   C_putdown_rfork : Code 
+   C_putdown_lfork : Code 
+   C_thinking : Code 
+   C_pickup_rfork : Code 
+   C_pickup_lfork : Code 
+   C_eating : Code 
+
+--
+-- all possible arguments in -APIs
+--
+
+record Phil-API : Set  where
+   field 
+      next : Code
+      impl : Phil
+
+--
+-- Data Gear
+--
+--      waiting / pointer / available
+--
+data Data : Set where
+   -- D_AtomicNat :  AtomicNat → ℕ → Data
+   D_AtomicNat :  AtomicNat → Data
+   D_Phil :      Phil → Data
+   D_Error :      Error → Data
+
+-- data API : Set where
+--    A_AtomicNat :  AtomicNat-API → API
+--    A_Phil :      Phil-API → API
+
+-- open import hoareBinaryTree
+
+data bt {n : Level} (A : Set n) : Set n where
+  leaf : bt A
+  node :  (key : ℕ) → (value : A) →
+    (left : bt A ) → (right : bt A ) → bt A
+
+updateTree : {n m : Level} {A : Set n} {t : Set m} → (tree : bt A) → (key : ℕ) → (value : A) → (empty : bt A → t ) → (next : A → bt A  → t ) → t
+updateTree = ?
+
+insertTree : {n m : Level} {A : Set n} {t : Set m} → (tree : bt A) → (key : ℕ) → (value : A) → (next : bt A → t ) → t
+insertTree = ?
+
+
+--
+-- second level stub
+--
+
+-- putdown_rfork : Phil → (? → t) → t
+-- putdown_rfork p next = goto p->lfork->cas( 0 , putdown_lfork, putdown_lfork ) , next
+
+Phil_putdown_rfork_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
+Phil_putdown_rfork_sub c next = next C_cas_int record c {
+    c_AtomicNat-API = record { impl = Phil.right phil ; value =  0 ; fail = C_putdown_lfork ; next = C_putdown_lfork } }  where
+    phil : Phil
+    phil = Phil-API.impl ( Context.c_Phil-API c )
+
+Phil_putdown_lfork_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
+Phil_putdown_lfork_sub c next = next C_cas_int record c { 
+    c_AtomicNat-API = record { impl = Phil.left phil ; value =  0 ; fail = C_thinking ; next = C_thinking } }  where
+    phil : Phil
+    phil = Phil-API.impl ( Context.c_Phil-API c )
+
+Phil_thiking : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
+Phil_thiking c next = next C_pickup_rfork c  
+
+Phil_pickup_lfork_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
+Phil_pickup_lfork_sub c next = next C_cas_int record c { 
+    c_AtomicNat-API = record { impl = Phil.left phil ; value =  Phil.ptr phil ; fail = C_pickup_lfork ; next = C_pickup_rfork } }  where
+    phil : Phil
+    phil = Phil-API.impl ( Context.c_Phil-API c )
+
+Phil_pickup_rfork_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
+Phil_pickup_rfork_sub c next = next C_cas_int record c { 
+    c_AtomicNat-API = record { impl = Phil.left phil ; value =  Phil.ptr phil ; fail = C_pickup_rfork ; next = C_eating } }  where
+    phil : Phil
+    phil = Phil-API.impl ( Context.c_Phil-API c )
+
+Phil_eating_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
+Phil_eating_sub c next =  next C_putdown_rfork c 
+
+code_table :  {n : Level} {t : Set n} → Code → Context → ( Code → Context → t) → t
+code_table C_nop  = λ c  next  → next C_nop c
+code_table C_cas_int  = AtomicInt_cas_stub
+code_table C_putdown_rfork = Phil_putdown_rfork_sub
+code_table C_putdown_lfork = Phil_putdown_lfork_sub
+code_table C_thinking = Phil_thiking
+code_table C_pickup_rfork = Phil_pickup_lfork_sub
+code_table C_pickup_lfork = Phil_pickup_rfork_sub
+code_table C_eating = Phil_eating_sub
+
+
+init-Phil-0 : (ps : List Context) → (left right : AtomicNat ) → List Context
+init-Phil-0 ps left right = new-data (c1 ps) ( λ ptr → D_Phil (p ptr) )  $ λ c ptr → record c { c_Phil-API = record { next = C_thinking ; impl = p ptr }} ∷ ps where
+    p : ℕ → Phil
+    p ptr = record  init-Phil { ptr = ptr ; left = left ; right = right }  
+    c1 :  List Context → Context
+    c1 [] =  init-context
+    c1 (c2 ∷ ct) =  c2
+
+init-AtomicNat1 :  {n : Level} {t : Set n} → Context  → ( Context →  AtomicNat → t ) → t
+init-AtomicNat1 c1  next = new-data c1  ( λ ptr → D_AtomicNat (a ptr) ) $ λ c2 ptr → next c2 (a ptr) where
+    a : ℕ → AtomicNat
+    a ptr = record { ptr = ptr ; value = 0 }
+
+init-Phil-1 : (c1 : Context) → Context
+init-Phil-1 c1 = record c1 { memory = mem2 $ mem1 $ mem ; mbase = n + 3 } where
+   n : ℕ
+   n = Context.mbase c1
+   left  = record { ptr = suc n ; value = 0}
+   right = record { ptr = suc (suc n) ; value = 0}
+   mem : bt Data
+   mem = insertTree ( Context.memory c1) (suc n) (D_AtomicNat left)
+      $ λ t →  t
+   mem1 : bt Data → bt Data
+   mem1 t = insertTree t (suc (suc n)) (D_AtomicNat right )
+      $ λ t →  t
+   mem2 : bt Data → bt Data
+   mem2 t = insertTree t (n + 3) (D_Phil record { ptr = n + 3 ; left = left ; right = right })  
+      $ λ t →  t
+     
+test-i0 : bt Data
+test-i0 =  Context.memory (init-Phil-1 init-context)
+
+make-phil : ℕ → Context
+make-phil zero = init-context
+make-phil (suc n) = init-Phil-1 ( make-phil n )
+
+test-i5 : bt Data
+test-i5 =  Context.memory (make-phil 5)
+
+-- loop exexution
+
+-- concurrnt execution
+
+-- state db ( binary tree of processes )
+
+-- depth first execution
+
+-- verify temporal logic poroerries
+
+
+
--- a/ModelChecking.agda	Sat Jul 20 17:01:50 2024 +0900
+++ b/ModelChecking.agda	Sun Aug 04 13:05:12 2024 +0900
@@ -1,3 +1,5 @@
+-- {-# OPTIONS --cubical-compatible --allow-unsolved-metas #-}
+{-# OPTIONS --cubical-compatible --safe #-}
 module ModelChecking where
 
 open import Level renaming (zero to Z ; suc to succ)
@@ -33,44 +35,12 @@
 f_set : {n : Level } {t : Set n} → AtomicNat → (value : ℕ) → ( AtomicNat → t ) → t
 f_set a v next = next record a { value = v }
 
-record Phil  : Set  where
-   field 
-      ptr : ℕ
-      left right : AtomicNat
-
-init-Phil : Phil
-init-Phil = record { ptr = 0 ; left = init-AtomicNat ; right = init-AtomicNat }
-
-pickup_rfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
-pickup_lfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
-eating : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
-putdown_rfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
-putdown_lfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
-thinking : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t
-
-pickup_rfork p next = f_set (Phil.right p) (Phil.ptr p) ( λ f → pickup_lfork record p { right = f } next )
-pickup_lfork p next = f_set (Phil.left p) (Phil.ptr p) ( λ f → eating record p { left = f } next )
-eating p next = putdown_rfork p next
-putdown_rfork p next = f_set (Phil.right p) 0 ( λ f → putdown_lfork record p { right = f } next )
-putdown_lfork p next = f_set (Phil.left p) 0 ( λ f → thinking record p { left = f } next )
-thinking p next = next p
-
-run : Phil
-run = pickup_rfork record { ptr = 1 ; left = record { ptr = 2 ; value = 0 } ; right = record { ptr = 3 ; value = 0 } } $ λ p → p
-
 --
 -- Coda Gear
 --
 
 data Code : Set  where
-   C_nop : Code
-   C_cas_int : Code
-   C_putdown_rfork : Code 
-   C_putdown_lfork : Code 
-   C_thinking : Code 
-   C_pickup_rfork : Code 
-   C_pickup_lfork : Code 
-   C_eating : Code 
+   CC_nop : Code
 
 --
 -- all possible arguments in -APIs
@@ -82,11 +52,6 @@
       value : ℕ
       impl : AtomicNat
 
-record Phil-API : Set  where
-   field 
-      next : Code
-      impl : Phil
-
 data Error : Set where
    E_panic : Error
    E_cas_fail : Error
@@ -96,17 +61,15 @@
 --
 --      waiting / pointer / available
 --
+
 data Data : Set where
    -- D_AtomicNat :  AtomicNat → ℕ → Data
-   D_AtomicNat :  AtomicNat → Data
-   D_Phil :      Phil → Data
-   D_Error :      Error → Data
+   CD_AtomicNat :  AtomicNat → Data
 
 -- data API : Set where
 --    A_AtomicNat :  AtomicNat-API → API
 --    A_Phil :      Phil-API → API
 
-open import hoareBinaryTree
 
 record Context  : Set  where
    field
@@ -116,11 +79,11 @@
       --  -API list (frame in Gears Agda )  --- a Data of API
       -- api : List API
       -- c_Phil-API :     Maybe Phil-API
-      c_Phil-API :     Phil-API
-      c_AtomicNat-API : AtomicNat-API
+      -- c_Phil-API :     ?
+      -- c_AtomicNat-API : AtomicNat-API
 
       mbase :     ℕ
-      memory :    bt Data
+      -- memory :    ?
       error :     Data
       fail_next :      Code
 
@@ -128,80 +91,29 @@
 -- second level stub
 --
 AtomicInt_cas_stub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
-AtomicInt_cas_stub {_} {t} c next = updateTree (Context.memory c) (AtomicNat.ptr ai) ( D_AtomicNat (record ai { value = AtomicNat-API.value api } ))
-     ( λ bt → next ( Context.fail c ) c  ) -- segmentation fault ( null pointer )
-     $ λ prev bt → f_cas prev bt  where
-    api : AtomicNat-API
-    api = Context.c_AtomicNat-API c
-    ai : AtomicNat
-    ai = AtomicNat-API.impl api
-    f_cas : Data  → bt Data  → t
-    f_cas (D_AtomicNat prev) bt with <-cmp ( AtomicNat.value  ai ) ( AtomicNat.value prev )
-    ... | tri≈ ¬a b ¬c  = next (AtomicNat-API.next api) ( record c { memory = bt ; c_AtomicNat-API = record api { impl = prev } }  ) -- update memory
-    ... | tri< a₁ ¬b ¬c = next (AtomicNat-API.fail api) c   --- cleaer API
-    ... | tri> ¬a ¬b _  = next (AtomicNat-API.fail api) c
-    f_cas a bt    = next ( Context.fail c ) c       -- type error / panic
-
--- putdown_rfork : Phil → (? → t) → t
--- putdown_rfork p next = goto p->lfork->cas( 0 , putdown_lfork, putdown_lfork ) , next
-
-Phil_putdown_rfork_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
-Phil_putdown_rfork_sub c next = next C_cas_int record c {
-    c_AtomicNat-API = record { impl = Phil.right phil ; value =  0 ; fail = C_putdown_lfork ; next = C_putdown_lfork } }  where
-    phil : Phil
-    phil = Phil-API.impl ( Context.c_Phil-API c )
+AtomicInt_cas_stub {_} {t} c next = ? 
 
-Phil_putdown_lfork_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
-Phil_putdown_lfork_sub c next = next C_cas_int record c { 
-    c_AtomicNat-API = record { impl = Phil.left phil ; value =  0 ; fail = C_thinking ; next = C_thinking } }  where
-    phil : Phil
-    phil = Phil-API.impl ( Context.c_Phil-API c )
-
-Phil_thiking : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
-Phil_thiking c next = next C_pickup_rfork c  
-
-Phil_pickup_lfork_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
-Phil_pickup_lfork_sub c next = next C_cas_int record c { 
-    c_AtomicNat-API = record { impl = Phil.left phil ; value =  Phil.ptr phil ; fail = C_pickup_lfork ; next = C_pickup_rfork } }  where
-    phil : Phil
-    phil = Phil-API.impl ( Context.c_Phil-API c )
-
-Phil_pickup_rfork_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
-Phil_pickup_rfork_sub c next = next C_cas_int record c { 
-    c_AtomicNat-API = record { impl = Phil.left phil ; value =  Phil.ptr phil ; fail = C_pickup_rfork ; next = C_eating } }  where
-    phil : Phil
-    phil = Phil-API.impl ( Context.c_Phil-API c )
-
-Phil_eating_sub : {n : Level} {t : Set n} → Context  → ( Code → Context → t ) → t
-Phil_eating_sub c next =  next C_putdown_rfork c 
 
 code_table :  {n : Level} {t : Set n} → Code → Context → ( Code → Context → t) → t
-code_table C_nop  = λ c  next  → next C_nop c
-code_table C_cas_int  = AtomicInt_cas_stub
-code_table C_putdown_rfork = Phil_putdown_rfork_sub
-code_table C_putdown_lfork = Phil_putdown_lfork_sub
-code_table C_thinking = Phil_thiking
-code_table C_pickup_rfork = Phil_pickup_lfork_sub
-code_table C_pickup_lfork = Phil_pickup_rfork_sub
-code_table C_eating = Phil_eating_sub
+code_table = ?
 
 step : {n : Level} {t : Set n} → List Context → (List Context → t) → t
 step {n} {t} [] next0 = next0 []
 step {n} {t} (p ∷ ps) next0 = code_table (Context.next p) p ( λ code np → next0 (update-context ps np ++ ( record np { next = code } ∷ [] )))  where
     update-context : List Context → Context  → List Context 
     update-context [] _ = []
-    update-context (c1 ∷ t) np = record c1 { memory = Context.memory np  ; mbase = Context.mbase np } ∷ t
+    update-context (c1 ∷ t) np = ? -- record c1 { memory = Context.memory np  ; mbase = Context.mbase np } ∷ t
 
 init-context : Context
 init-context = record {
-      next = C_nop
-    ; fail = C_nop
-    ; c_Phil-API = record { next = C_nop ; impl = init-Phil } 
-    ; c_AtomicNat-API = record { next = C_nop ; fail = C_nop ; value = 0 ; impl = init-AtomicNat } 
+      next = CC_nop
+    ; fail = CC_nop
+    -- ; c_Phil-API = ?
+    -- ; c_AtomicNat-API = record { next = CC_nop ; fail = CC_nop ; value = 0 ; impl = init-AtomicNat } 
     ; mbase = 0
-    ; memory = leaf
-    ; error = D_Error E_panic
-    ; fail_next = C_nop
+    -- ; memory = ?
+    ; error = ?
+    ; fail_next = CC_nop
   }
 
 alloc-data : {n : Level} {t : Set n} → ( c : Context ) → ( Context → ℕ → t ) → t
@@ -209,51 +121,61 @@
      mnext = suc ( Context.mbase c )
 
 new-data : {n : Level} {t : Set n} → ( c : Context ) → (ℕ → Data ) → ( Context → ℕ → t ) → t
-new-data  c x next  = alloc-data c $ λ c1 n → insertTree (Context.memory c1) n (x n) ( λ bt → next record c1 { memory = bt } n )
+new-data  c x next  = alloc-data c $ λ c1 n → ? -- insertTree (Context.memory c1) n (x n) ( λ bt → next record c1 { memory = bt } n )
 
 init-AtomicNat0 :  {n : Level} {t : Set n} → Context  → ( Context →  ℕ → t ) → t
-init-AtomicNat0 c1  next = new-data c1  ( λ ptr → D_AtomicNat (a ptr) ) $ λ c2 ptr → next c2 ptr where
-    a : ℕ → AtomicNat
-    a ptr = record { ptr = ptr ; value = 0 }
+init-AtomicNat0 c1  next = ?
+
+add< : { i : ℕ } (j : ℕ ) → i < suc i + j
+add<  {i} j = begin
+        suc i ≤⟨ m≤m+n (suc i) j ⟩
+        suc i + j ∎  where open ≤-Reasoning
+
+nat-<> : { x y : ℕ } → x < y → y < x → ⊥
+nat-<> {x} {y} x<y y<x with <-cmp x y
+... | tri< a ¬b ¬c = ⊥-elim ( ¬c y<x )
+... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c y<x )
+... | tri> ¬a ¬b c = ⊥-elim ( ¬a x<y )
 
-init-Phil-0 : (ps : List Context) → (left right : AtomicNat ) → List Context
-init-Phil-0 ps left right = new-data (c1 ps) ( λ ptr → D_Phil (p ptr) )  $ λ c ptr → record c { c_Phil-API = record { next = C_thinking ; impl = p ptr }} ∷ ps where
-    p : ℕ → Phil
-    p ptr = record  init-Phil { ptr = ptr ; left = left ; right = right }  
-    c1 :  List Context → Context
-    c1 [] =  init-context
-    c1 (c2 ∷ ct) =  c2
+nat-≤> : { x y : ℕ } → x ≤ y → y < x → ⊥
+nat-≤> {x} {y} x≤y y<x with <-cmp x y
+... | tri< a ¬b ¬c = ⊥-elim ( ¬c y<x )
+... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c y<x )
+... | tri> ¬a ¬b c = ?
 
-init-AtomicNat1 :  {n : Level} {t : Set n} → Context  → ( Context →  AtomicNat → t ) → t
-init-AtomicNat1 c1  next = new-data c1  ( λ ptr → D_AtomicNat (a ptr) ) $ λ c2 ptr → next c2 (a ptr) where
-    a : ℕ → AtomicNat
-    a ptr = record { ptr = ptr ; value = 0 }
+
+nat-<≡ : { x : ℕ } → x < x → ⊥
+nat-<≡  {x} x<x with <-cmp x x
+... | tri< a ¬b ¬c = ⊥-elim ( ¬c x<x )
+... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c x<x )
+... | tri> ¬a ¬b c = ⊥-elim ( ¬a x<x )
 
-init-Phil-1 : (c1 : Context) → Context
-init-Phil-1 c1 = record c1 { memory = mem2 $ mem1 $ mem ; mbase = n + 3 } where
-   n : ℕ
-   n = Context.mbase c1
-   left  = record { ptr = suc n ; value = 0}
-   right = record { ptr = suc (suc n) ; value = 0}
-   mem : bt Data
-   mem = insertTree ( Context.memory c1) (suc n) (D_AtomicNat left)
-      $ λ t →  t
-   mem1 : bt Data → bt Data
-   mem1 t = insertTree t (suc (suc n)) (D_AtomicNat right )
-      $ λ t →  t
-   mem2 : bt Data → bt Data
-   mem2 t = insertTree t (n + 3) (D_Phil record { ptr = n + 3 ; left = left ; right = right })  
-      $ λ t →  t
-     
-test-i0 : bt Data
-test-i0 =  Context.memory (init-Phil-1 init-context)
+nat-≡< : { x y : ℕ } → x ≡ y → x < y → ⊥
+nat-≡< refl lt = nat-<≡ lt
+
+lemma3 : {i j : ℕ} → 0 ≡ i → j < i → ⊥
+lemma3 refl ()
+lemma5 : {i j : ℕ} → i < 1 → j < i → ⊥
+lemma5 {i} {j} i<1 j<i with <-cmp j i
+... | tri< a ¬b ¬c = ⊥-elim ( ¬c ? )
+... | tri≈ ¬a b ¬c = ⊥-elim  (¬a j<i )
+... | tri> ¬a ¬b c = ⊥-elim ( ¬a j<i )
 
-make-phil : ℕ → Context
-make-phil zero = init-context
-make-phil (suc n) = init-Phil-1 ( make-phil n )
+¬x<x : {x : ℕ} → ¬ (x < x)
+¬x<x x<x = ?
 
-test-i5 : bt Data
-test-i5 =  Context.memory (make-phil 5)
+TerminatingLoopS : {l m : Level} {t : Set l} (Index : Set m ) → {Invraiant : Index → Set m } → ( reduce : Index → ℕ)
+   → (r : Index) → (p : Invraiant r)
+   → (loop : (r : Index)  → Invraiant r → (next : (r1 : Index)  → Invraiant r1 → reduce r1 < reduce r  → t ) → t) → t
+TerminatingLoopS {_} {_} {t} Index {Invraiant} reduce r p loop with <-cmp 0 (reduce r)
+... | tri≈ ¬a b ¬c = loop r p (λ r1 p1 lt → ⊥-elim (lemma3 b lt) )
+... | tri< a ¬b ¬c = loop r p (λ r1 p1 lt1 → TerminatingLoop1 (reduce r) r r1 (m≤n⇒m≤1+n lt1) p1 lt1 ) where
+    TerminatingLoop1 : (j : ℕ) → (r r1 : Index) → reduce r1 < suc j  → Invraiant r1 →  reduce r1 < reduce r → t
+    TerminatingLoop1 zero r r1 n≤j p1 lt = loop r1 p1 (λ r2 p1 lt1 → ⊥-elim (lemma5 n≤j lt1))
+    TerminatingLoop1 (suc j) r r1  n≤j p1 lt with <-cmp (reduce r1) (suc j)
+    ... | tri< a ¬b ¬c = TerminatingLoop1 j r r1 a p1 lt
+    ... | tri≈ ¬a b ¬c = loop r1 p1 (λ r2 p2 lt1 → TerminatingLoop1 j r1 r2 (subst (λ k → reduce r2 < k ) b lt1 ) p2 lt1 )
+    ... | tri> ¬a ¬b c =  ⊥-elim ( nat-≤> c n≤j )
 
 -- loop exexution
 
--- a/RBTree.agda	Sat Jul 20 17:01:50 2024 +0900
+++ b/RBTree.agda	Sun Aug 04 13:05:12 2024 +0900
@@ -1,5 +1,6 @@
-{-# OPTIONS  --allow-unsolved-metas #-}
--- {-# OPTIONS --cubical-compatible --allow-unsolved-metas #-}
+{-# OPTIONS  cubical-compatible --allow-unsolved-metas #-}
+-- {-# OPTIONS --cubical-compatible --safe #-}
+-- {-# OPTIONS --cubical-compatible  #-}
 module RBTree where
 
 open import Level hiding (suc ; zero ; _⊔_ )
--- a/logic.agda	Sat Jul 20 17:01:50 2024 +0900
+++ b/logic.agda	Sun Aug 04 13:05:12 2024 +0900
@@ -1,14 +1,11 @@
-{-# OPTIONS --safe --cubical-compatible #-}
+{-# OPTIONS --cubical-compatible --safe #-}
+
 module logic where
 
-open import Level 
-
+open import Level
 open import Relation.Nullary
-open import Relation.Binary hiding (_⇔_) 
-open import Relation.Binary.PropositionalEquality
-
+open import Relation.Binary hiding (_⇔_ )
 open import Data.Empty
-open import Data.Nat hiding (_⊔_)
 
 
 data Bool : Set where
@@ -49,45 +46,139 @@
 dont-orb {A} {B} (case2 b) ¬B = ⊥-elim ( ¬B b )
 dont-orb {A} {B} (case1 a) ¬B = a
 
-
 infixr  130 _∧_
 infixr  140 _∨_
 infixr  150 _⇔_
 
-_/\_ : Bool → Bool → Bool 
+_/\_ : Bool → Bool → Bool
 true /\ true = true
 _ /\ _ = false
 
-_<B?_ : ℕ → ℕ → Bool
-ℕ.zero <B? x = true
-ℕ.suc x <B? ℕ.zero = false
-ℕ.suc x <B? ℕ.suc xx = x <B? xx
-
--- _<BT_ : ℕ → ℕ → Set
--- ℕ.zero <BT ℕ.zero = ⊤
--- ℕ.zero <BT ℕ.suc b = ⊤
--- ℕ.suc a <BT ℕ.zero = ⊥
--- ℕ.suc a <BT ℕ.suc b = a <BT b
-
-
-_≟B_ : Decidable {A = Bool} _≡_
-true  ≟B true  = yes refl
-false ≟B false = yes refl
-true  ≟B false = no λ()
-false ≟B true  = no λ()
-
-_\/_ : Bool → Bool → Bool 
+_\/_ : Bool → Bool → Bool
 false \/ false = false
 _ \/ _ = true
 
-not_ : Bool → Bool 
+not : Bool → Bool
 not true = false
-not false = true 
+not false = true
 
-_<=>_ : Bool → Bool → Bool  
+_<=>_ : Bool → Bool → Bool
 true <=> true = true
 false <=> false = true
 _ <=> _ = false
 
 infixr  130 _\/_
 infixr  140 _/\_
+
+open import Relation.Binary.PropositionalEquality
+
+record Bijection {n m : Level} (R : Set n) (S : Set m) : Set (n Level.⊔ m)  where
+   field
+       fun←  :  S → R
+       fun→  :  R → S
+       fiso← : (x : R)  → fun← ( fun→ x )  ≡ x
+       fiso→ : (x : S ) → fun→ ( fun← x )  ≡ x
+
+injection :  {n m : Level} (R : Set n) (S : Set m) (f : R → S ) → Set (n Level.⊔ m)
+injection R S f = (x y : R) → f x ≡ f y → x ≡ y
+
+
+-- Cubical Agda has trouble with std-lib's Dec
+-- we sometimes use simpler version of Dec
+
+data Dec0 {n : Level} (A : Set n) : Set n where
+  yes0 : A → Dec0 A
+  no0  : (A → ⊥) → Dec0 A
+
+open _∧_ 
+∧-injective : {n m : Level} {A : Set n} {B : Set m} → {a b : A ∧ B}  → proj1 a ≡ proj1 b → proj2 a ≡ proj2 b → a ≡ b
+∧-injective refl refl = refl
+
+not-not-bool : { b : Bool } → not (not b) ≡ b
+not-not-bool {true} = refl
+not-not-bool {false} = refl
+
+¬t=f : (t : Bool ) → ¬ ( not t ≡ t)
+¬t=f true ()
+¬t=f false ()
+
+≡-Bool-func : {A B : Bool } → ( A ≡ true → B ≡ true ) → ( B ≡ true → A ≡ true ) → A ≡ B
+≡-Bool-func {true} {true} a→b b→a = refl
+≡-Bool-func {false} {true} a→b b→a with b→a refl
+... | ()
+≡-Bool-func {true} {false} a→b b→a with a→b refl
+... | ()
+≡-Bool-func {false} {false} a→b b→a = refl
+
+bool-≡-? : (a b : Bool) → Dec0 ( a ≡ b )
+bool-≡-? true true = yes0 refl
+bool-≡-? true false = no0 (λ ())
+bool-≡-? false true = no0 (λ ())
+bool-≡-? false false = yes0 refl
+
+¬-bool-t : {a : Bool} →  ¬ ( a ≡ true ) → a ≡ false
+¬-bool-t {true} ne = ⊥-elim ( ne refl )
+¬-bool-t {false} ne = refl
+
+¬-bool-f : {a : Bool} →  ¬ ( a ≡ false ) → a ≡ true
+¬-bool-f {true} ne = refl
+¬-bool-f {false} ne = ⊥-elim ( ne refl )
+
+¬-bool : {a : Bool} →  a ≡ false  → a ≡ true → ⊥
+¬-bool refl ()
+
+lemma-∧-0 : {a b : Bool} → a /\ b ≡ true → a ≡ false → ⊥
+lemma-∧-0 {true} {false} ()
+lemma-∧-0 {false} {true} ()
+lemma-∧-0 {false} {false} ()
+lemma-∧-0 {true} {true} eq1 ()
+
+lemma-∧-1 : {a b : Bool} → a /\ b ≡ true → b ≡ false → ⊥
+lemma-∧-1 {true} {false} ()
+lemma-∧-1 {false} {true} ()
+lemma-∧-1 {false} {false} ()
+lemma-∧-1 {true} {true} eq1 ()
+
+bool-and-tt : {a b : Bool} → a ≡ true → b ≡ true → ( a /\ b ) ≡ true
+bool-and-tt refl refl = refl
+
+bool-∧→tt-0 : {a b : Bool} → ( a /\ b ) ≡ true → a ≡ true
+bool-∧→tt-0 {true} {true} eq =  refl
+bool-∧→tt-0 {false} {_} ()
+
+bool-∧→tt-1 : {a b : Bool} → ( a /\ b ) ≡ true → b ≡ true
+bool-∧→tt-1 {true} {true} eq = refl
+bool-∧→tt-1 {true} {false} ()
+bool-∧→tt-1 {false} {false} ()
+
+bool-or-1 : {a b : Bool} → a ≡ false → ( a \/ b ) ≡ b
+bool-or-1 {false} {true} eq = refl
+bool-or-1 {false} {false} eq = refl
+bool-or-2 : {a b : Bool} → b ≡ false → (a \/ b ) ≡ a
+bool-or-2 {true} {false} eq = refl
+bool-or-2 {false} {false} eq = refl
+
+bool-or-3 : {a : Bool} → ( a \/ true ) ≡ true
+bool-or-3 {true} = refl
+bool-or-3 {false} = refl
+
+bool-or-31 : {a b : Bool} → b ≡ true  → ( a \/ b ) ≡ true
+bool-or-31 {true} {true} eq = refl
+bool-or-31 {false} {true} eq = refl
+
+bool-or-4 : {a : Bool} → ( true \/ a ) ≡ true
+bool-or-4 {true} = refl
+bool-or-4 {false} = refl
+
+bool-or-41 : {a b : Bool} → a ≡ true  → ( a \/ b ) ≡ true
+bool-or-41 {true} {b} eq = refl
+
+bool-and-1 : {a b : Bool} →  a ≡ false → (a /\ b ) ≡ false
+bool-and-1 {false} {b} eq = refl
+bool-and-2 : {a b : Bool} →  b ≡ false → (a /\ b ) ≡ false
+bool-and-2 {true} {false} eq = refl
+bool-and-2 {false} {false} eq = refl
+bool-and-2 {true} {true} ()
+bool-and-2 {false} {true} ()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nat.agda	Sun Aug 04 13:05:12 2024 +0900
@@ -0,0 +1,1030 @@
+{-# OPTIONS --cubical-compatible --safe #-}
+
+module nat where
+
+open import Data.Nat
+open import Data.Nat.Properties
+open import Data.Empty
+open import Relation.Nullary
+open import  Relation.Binary.PropositionalEquality
+open import  Relation.Binary.Core
+open import  Relation.Binary.Definitions
+open import  logic
+open import Level hiding ( zero ; suc )
+
+=→¬< : {x : ℕ  } → ¬ ( x < x )
+=→¬< {x} x<x with <-cmp x x
+... | tri< a ¬b ¬c = ⊥-elim ( ¬b refl )
+... | tri≈ ¬a b ¬c = ⊥-elim ( ¬a x<x )
+... | tri> ¬a ¬b c = ⊥-elim ( ¬b refl )
+
+>→¬< : {x y : ℕ  } → (x < y ) → ¬ ( y < x )
+>→¬< {x} {y} x<y y<x with <-cmp x y
+... | tri< a ¬b ¬c = ⊥-elim ( ¬c y<x )
+... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c y<x )
+... | tri> ¬a ¬b c = ⊥-elim ( ¬a x<y )
+
+nat-<> : { x y : ℕ } → x < y → y < x → ⊥
+nat-<> {x} {y} x<y y<x with <-cmp x y
+... | tri< a ¬b ¬c = ⊥-elim ( ¬c y<x )
+... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c y<x )
+... | tri> ¬a ¬b c = ⊥-elim ( ¬a x<y )
+
+a<sa : {la : ℕ} → la < suc la
+a<sa {zero} = s≤s z≤n
+a<sa {suc la} = s≤s a<sa
+
+refl-≤s : {x : ℕ } → x ≤ suc x
+refl-≤s {zero} = z≤n
+refl-≤s {suc x} = s≤s (refl-≤s {x})
+
+a≤sa : {x : ℕ } → x ≤ suc x
+a≤sa = refl-≤s
+
+nat-<≡ : { x : ℕ } → x < x → ⊥
+nat-<≡ {x} x<x with <-cmp x x
+... | tri< a ¬b ¬c = ⊥-elim ( ¬b refl )
+... | tri≈ ¬a b ¬c = ⊥-elim ( ¬a x<x )
+... | tri> ¬a ¬b c = ⊥-elim ( ¬a x<x )
+
+nat-≡< : { x y : ℕ } → x ≡ y → x < y → ⊥
+nat-≡< refl lt = nat-<≡ lt
+
+nat-≤> : { x y : ℕ } → x ≤ y → y < x → ⊥
+nat-≤>  {x} {y} x≤y y<x with <-cmp x y
+... | tri< a ¬b ¬c = ⊥-elim ( ¬c y<x )
+... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c y<x )
+... | tri> ¬a ¬b c = ⊥-elim (nat-<≡ (≤-trans c x≤y))
+
+≤-∨ : { x y : ℕ } → x ≤ y → ( (x ≡ y ) ∨ (x < y) )
+≤-∨ {x} {y} x≤y with <-cmp x y
+... | tri< a ¬b ¬c = case2 a
+... | tri≈ ¬a b ¬c = case1 b
+... | tri> ¬a ¬b c = ⊥-elim ( nat-<≡ (≤-trans c x≤y))
+
+<-∨ : { x y : ℕ } → x < suc y → ( (x ≡ y ) ∨ (x < y) )
+<-∨ {x} {y} x<sy with <-cmp x y
+... | tri< a ¬b ¬c = case2 a
+... | tri≈ ¬a b ¬c = case1 b
+... | tri> ¬a ¬b c = ⊥-elim ( nat-<≡ (≤-trans x<sy c ))
+
+¬a≤a : {la : ℕ} → suc la ≤ la → ⊥
+¬a≤a {x} sx≤x = ⊥-elim ( nat-≤> sx≤x a<sa )
+
+max : (x y : ℕ) → ℕ
+max zero zero = zero
+max zero (suc x) = (suc x)
+max (suc x) zero = (suc x)
+max (suc x) (suc y) = suc ( max x y )
+
+x≤max : (x y : ℕ) → x ≤ max x y
+x≤max zero zero = ≤-refl
+x≤max zero (suc x) = z≤n
+x≤max (suc x) zero = ≤-refl
+x≤max (suc x) (suc y) = s≤s( x≤max x y )
+
+y≤max : (x y : ℕ) → y ≤ max x y
+y≤max zero zero = ≤-refl
+y≤max zero (suc x) = ≤-refl
+y≤max (suc x) zero = z≤n
+y≤max (suc x) (suc y) = s≤s( y≤max x y )
+
+x≤y→max=y : (x y : ℕ) → x ≤ y → max x y ≡ y
+x≤y→max=y zero zero x≤y = refl
+x≤y→max=y zero (suc y) x≤y = refl
+x≤y→max=y (suc x) (suc y) lt with <-cmp x y
+... | tri< a ¬b ¬c = cong suc (x≤y→max=y x y (≤-trans a≤sa a))
+... | tri≈ ¬a refl ¬c = cong suc (x≤y→max=y x y ≤-refl )
+... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> c lt )
+
+y≤x→max=x : (x y : ℕ) → y ≤ x → max x y ≡ x
+y≤x→max=x zero zero y≤x = refl
+y≤x→max=x zero (suc y) ()
+y≤x→max=x (suc x) zero lt = refl
+y≤x→max=x (suc x) (suc y) lt with <-cmp y x
+... | tri< a ¬b ¬c = cong suc (y≤x→max=x x y (≤-trans a≤sa a))
+... | tri≈ ¬a refl ¬c = cong suc (y≤x→max=x x y ≤-refl )
+... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> c lt )
+
+
+-- _*_ : ℕ → ℕ → ℕ
+-- _*_ zero _ = zero
+-- _*_ (suc n) m = m + ( n * m )
+
+-- x ^ y
+exp : ℕ → ℕ → ℕ
+exp _ zero = 1
+exp n (suc m) = n * ( exp n m )
+
+div2 : ℕ → (ℕ ∧ Bool )
+div2 zero =  ⟪ 0 , false ⟫
+div2 (suc zero) =  ⟪ 0 , true ⟫
+div2 (suc (suc n)) =  ⟪ suc (proj1 (div2 n)) , proj2 (div2 n) ⟫ where
+    open _∧_
+
+div2-rev : (ℕ ∧ Bool ) → ℕ
+div2-rev ⟪ x , true ⟫ = suc (x + x)
+div2-rev ⟪ x , false ⟫ = x + x
+
+div2-eq : (x : ℕ ) → div2-rev ( div2 x ) ≡ x
+div2-eq zero = refl
+div2-eq (suc zero) = refl
+div2-eq (suc (suc x)) with div2 x in eq1
+... | ⟪ x1 , true ⟫ = begin -- eq1 : div2 x ≡ ⟪ x1 , true ⟫
+     div2-rev ⟪ suc x1 , true ⟫ ≡⟨⟩
+     suc (suc (x1 + suc x1)) ≡⟨ cong (λ k → suc (suc k )) (+-comm x1  _ ) ⟩
+     suc (suc (suc (x1 + x1))) ≡⟨⟩
+     suc (suc (div2-rev ⟪ x1 , true ⟫)) ≡⟨ cong (λ k → suc (suc (div2-rev k ))) (sym eq1) ⟩
+     suc (suc (div2-rev (div2 x)))      ≡⟨ cong (λ k → suc (suc k)) (div2-eq x) ⟩
+     suc (suc x) ∎  where open ≡-Reasoning
+... | ⟪ x1 , false ⟫ = begin
+     div2-rev ⟪ suc x1 , false ⟫ ≡⟨⟩
+     suc (x1 + suc x1) ≡⟨ cong (λ k → (suc k )) (+-comm x1  _ ) ⟩
+     suc (suc (x1 + x1)) ≡⟨⟩
+     suc (suc (div2-rev ⟪ x1 , false ⟫)) ≡⟨ cong (λ k → suc (suc (div2-rev k ))) (sym eq1) ⟩
+     suc (suc (div2-rev (div2 x)))      ≡⟨ cong (λ k → suc (suc k)) (div2-eq x) ⟩
+     suc (suc x) ∎  where open ≡-Reasoning
+
+sucprd : {i : ℕ } → 0 < i  → suc (pred i) ≡ i
+sucprd {suc i} 0<i = refl
+
+0<s : {x : ℕ } → zero < suc x
+0<s {_} = s≤s z≤n
+
+px<py : {x y : ℕ } → pred x  < pred y → x < y
+px<py {zero} {suc y} lt = 0<s
+px<py {suc x} {suc y} lt with <-cmp x y
+... | tri< a ¬b ¬c = s≤s a
+... | tri≈ ¬a b ¬c = ⊥-elim ( nat-≡< b lt )
+... | tri> ¬a ¬b c = ⊥-elim ( nat-<> c lt )
+
+minus : (a b : ℕ ) →  ℕ
+minus a zero = a
+minus zero (suc b) = zero
+minus (suc a) (suc b) = minus a b
+
+_-_ = minus
+
+sn-m=sn-m : {m n : ℕ } →  m ≤ n → suc n - m ≡ suc ( n - m )
+sn-m=sn-m {0} {n} m≤n = refl
+sn-m=sn-m {suc m} {suc n} le with <-cmp m n
+... | tri< a ¬b ¬c = sm00 where
+    sm00 : suc n - m ≡ suc ( n - m )
+    sm00 = sn-m=sn-m {m} {n} (≤-trans a≤sa a )
+... | tri≈ ¬a refl ¬c = sn-m=sn-m {m} {n} ≤-refl
+... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> c le )
+
+si-sn=i-n : {i n : ℕ } → n < i  → suc (i - suc n) ≡ (i - n)
+si-sn=i-n {i} {n} n<i = begin
+   suc (i - suc n) ≡⟨ sym (sn-m=sn-m n<i )  ⟩
+   suc i - suc n ≡⟨⟩
+   i - n
+   ∎  where
+      open ≡-Reasoning
+
+n-m<n : (n m : ℕ ) →  n - m ≤ n
+n-m<n zero zero = z≤n
+n-m<n (suc n) zero = s≤s (n-m<n n zero)
+n-m<n zero (suc m) = z≤n
+n-m<n (suc n) (suc m) = ≤-trans (n-m<n n m ) refl-≤s
+
+m-0=m : {m : ℕ } → m - zero ≡ m
+m-0=m {zero} = refl
+m-0=m {suc m} = cong suc (m-0=m {m})
+
+m-m=0 : {m : ℕ } → m - m ≡ zero
+m-m=0 {zero} = refl
+m-m=0 {suc m} = m-m=0 {m}
+
+refl-≤ : {x : ℕ } → x ≤ x
+refl-≤ {zero} = z≤n
+refl-≤ {suc x} = s≤s (refl-≤ {x})
+
+refl-≤≡ : {x y : ℕ } → x ≡ y → x ≤ y
+refl-≤≡ refl = refl-≤
+
+px≤x : {x  : ℕ } → pred x ≤ x
+px≤x {zero} = refl-≤
+px≤x {suc x} = refl-≤s
+
+px≤py : {x y : ℕ } → x ≤ y → pred x  ≤ pred y
+px≤py {zero} {zero} x≤y = refl-≤
+px≤py {suc x} {zero} ()
+px≤py {zero} {suc y} le = z≤n
+px≤py {suc x} {suc y} x≤y with <-cmp x y
+... | tri< a ¬b ¬c = ≤-trans a≤sa a
+... | tri≈ ¬a b ¬c = refl-≤≡ b
+... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> c x≤y )
+
+n-n-m=m : {m n : ℕ } → m ≤ n  → m ≡ (n - (n - m))
+n-n-m=m {0} {zero} le = refl
+n-n-m=m {0} {suc n} lt = begin
+    0 ≡⟨ sym (m-m=0 {suc n}) ⟩
+    suc n - suc n
+    ∎ where   open ≡-Reasoning
+n-n-m=m {suc m} {suc n} le = begin
+    suc m ≡⟨ cong suc ( n-n-m=m (px≤py le)) ⟩
+    suc (n - (n - m)) ≡⟨ sym (sn-m=sn-m (n-m<n n m)) ⟩
+    suc n - (n - m) ∎ where open ≡-Reasoning
+
+m+= : {i j  m : ℕ } → m + i ≡ m + j → i ≡ j
+m+= {i} {j} {zero} refl = refl
+m+= {i} {j} {suc m} eq = m+= {i} {j} {m} ( cong (λ k → pred k ) eq )
+
++m= : {i j  m : ℕ } → i + m ≡ j + m → i ≡ j
++m= {i} {j} {m} eq = m+= ( subst₂ (λ j k → j ≡ k ) (+-comm i _ ) (+-comm j _ ) eq )
+
+less-1 :  { n m : ℕ } → suc n < m → n < m
+less-1 sn<m = <-trans a<sa sn<m
+
+sa=b→a<b :  { n m : ℕ } → suc n ≡ m → n < m
+sa=b→a<b {n} {m} sn=m = subst (λ k → n < k ) sn=m a<sa
+
+minus+n : {x y : ℕ } → suc x > y  → minus x y + y ≡ x
+minus+n {x} {zero} _ = trans (sym (+-comm zero  _ )) refl
+minus+n {zero} {suc y} lt = ⊥-elim ( nat-≤> lt (≤-trans a<sa (s≤s (s≤s z≤n)) ))
+minus+n {suc x} {suc y} y<sx with <-cmp y (suc x)
+... | tri< a ¬b ¬c = begin
+  minus (suc x) (suc y) + suc y ≡⟨ +-comm _ (suc y)    ⟩
+  suc y + minus x y ≡⟨ cong ( λ k → suc k ) ( begin
+     y + minus x y ≡⟨ +-comm y  _ ⟩
+     minus x y + y ≡⟨ minus+n {x} {y} a  ⟩
+     x ∎  ) ⟩
+  suc x ∎  where open ≡-Reasoning
+... | tri≈ ¬a b ¬c = ⊥-elim ( nat-≡< b (px≤py y<sx ))
+... | tri> ¬a ¬b c = ⊥-elim ( nat-<> c (px≤py y<sx ))
+
++<-cong : {x y z : ℕ } → x < y →  z + x < z + y
++<-cong {x} {y} {zero} x<y = x<y
++<-cong {x} {y} {suc z} x<y = s≤s (+<-cong {x} {y} {z} x<y)
+
+<-minus-0 : {x y z : ℕ } → z + x < z + y → x < y
+<-minus-0 {x} {y} {z} x<y with <-cmp x y
+... | tri< a ¬b ¬c = a
+... | tri≈ ¬a b ¬c = ⊥-elim ( nat-≡< (cong (λ k → z + k ) b) x<y )
+... | tri> ¬a ¬b c = ⊥-elim ( nat-<> x<y (+<-cong {y} {x} {z} c))
+
+<-minus : {x y z : ℕ } → x + z < y + z → x < y
+<-minus {x} {y} {z} lt = <-minus-0 ( subst₂ ( λ j k → j < k ) (+-comm x _) (+-comm y _ ) lt )
+
+x≤x+y : {z y : ℕ } → z ≤ z + y
+x≤x+y {zero} {y} = z≤n
+x≤x+y {suc z} {y} = s≤s (x≤x+y {z} {y})
+
+x≤y+x : {z y : ℕ } → z ≤ y + z
+x≤y+x {z} {y} = subst (λ k → z ≤ k ) (+-comm _ y ) x≤x+y
+
+x≤x+sy : {x y : ℕ} → x < x + suc y
+x≤x+sy {x} {y} = begin
+       suc x ≤⟨ x≤x+y ⟩
+       suc x + y ≡⟨ cong (λ k → k + y) (+-comm 1 x ) ⟩
+       (x + 1) + y ≡⟨ (+-assoc x 1 _) ⟩
+       x + suc y ∎  where open ≤-Reasoning
+
+
+<-plus-0 : {x y z : ℕ } → x < y → z + x < z + y
+<-plus-0 = +<-cong
+
+<-plus : {x y z : ℕ } → x < y → x + z < y + z
+<-plus {x} {y} {z} x<y = subst₂ (λ j k → j < k ) (+-comm z x ) (+-comm z y ) ( <-plus-0 x<y )
+
+≤-plus-0 : {x y z : ℕ } → x ≤ y → z + x ≤ z + y
+≤-plus-0 {x} {y} {zero} lt = lt
+≤-plus-0 {x} {y} {suc z} lt = s≤s ( ≤-plus-0 {x} {y} {z} lt )
+
+≤-plus : {x y z : ℕ } → x ≤ y → x + z ≤ y + z
+≤-plus {x} {y} {z} x≤y = subst₂ (λ j k → j ≤ k ) (+-comm z x ) (+-comm z y ) ( ≤-plus-0 x≤y )
+
+x+y<z→x<z : {x y z : ℕ } → x + y < z → x < z
+x+y<z→x<z {x} {zero} {z} xy<z = subst (λ k → k < z ) (+-comm x zero ) xy<z
+x+y<z→x<z {x} {suc y} {z} xy<z = <-minus {x} {z} {suc y} (<-trans xy<z x≤x+sy )
+
+*≤ : {x y z : ℕ } → x ≤ y → x * z ≤ y * z
+*≤ lt = *-mono-≤ lt ≤-refl
+
+<to≤ : {x y  : ℕ } → x < y → x ≤ y
+<to≤ {x} {y} x<y with <-cmp x (suc y)
+... | tri< a ¬b ¬c = px≤py a
+... | tri≈ ¬a b ¬c = ⊥-elim ( nat-≡< b (≤-trans x<y a≤sa ))
+... | tri> ¬a ¬b c = ⊥-elim ( nat-<> c (≤-trans x<y a≤sa ))
+
+<sto≤ : {x y  : ℕ } → x < suc y → x ≤ y
+<sto≤ {x} {y} x<sy with <-cmp x y
+... | tri< a ¬b ¬c = <to≤ a
+... | tri≈ ¬a refl ¬c = ≤-refl
+... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> c x<sy )
+
+*< : {x y z : ℕ } → x < y → x * suc z < y * suc z
+*< {x} {zero} {z} ()
+*< {x} {suc y} {z} x<y = s≤s ( begin
+   x * suc z ≤⟨ lem01 ⟩
+   y * suc z  ≤⟨ x≤x+y ⟩
+   y * suc z + z  ≡⟨ +-comm _ z  ⟩
+   z + y * suc z ∎ ) where
+      open ≤-Reasoning
+      lem01 : x * suc z ≤ y * suc z
+      lem01 = *-mono-≤ {x} {y} {suc z} (<sto≤ x<y)  ≤-refl
+
+<to<s : {x y  : ℕ } → x < y → x < suc y
+<to<s x<y = <-trans x<y a<sa
+
+<tos<s : {x y  : ℕ } → x < y → suc x < suc y
+<tos<s x<y = s≤s x<y
+
+<∨≤ : ( x y : ℕ ) →  (x < y ) ∨ (y ≤ x)
+<∨≤ x y with <-cmp x y
+... | tri< a ¬b ¬c = case1 a
+... | tri≈ ¬a refl ¬c = case2 ≤-refl
+... | tri> ¬a ¬b c = case2 (<to≤ c)
+
+x<y→≤ : {x y : ℕ } → x < y →  x ≤ suc y
+x<y→≤ {x} {y} x<y with <-cmp x (suc y)
+... | tri< a ¬b ¬c = <to≤ a
+... | tri≈ ¬a b ¬c = refl-≤≡ b
+... | tri> ¬a ¬b c = ⊥-elim ( ¬a ( ≤-trans x<y a≤sa ))
+
+≤→= : {i j : ℕ} → i ≤ j → j ≤ i → i ≡ j
+≤→= {i} {j} i≤j j≤i with <-cmp i j
+... | tri< a ¬b ¬c = ⊥-elim ( nat-≤> j≤i a )
+... | tri≈ ¬a b ¬c = b
+... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> i≤j c )
+
+sx≤py→x≤y : {x y : ℕ } → suc x ≤ suc y → x  ≤ y
+sx≤py→x≤y = px≤py
+
+sx<py→x<y : {x y : ℕ } → suc x < suc y → x  < y
+sx<py→x<y {x} {y} sx<sy with <-cmp x y
+... | tri< a ¬b ¬c = a
+... | tri≈ ¬a b ¬c = ⊥-elim ( nat-≡< (cong suc b) sx<sy )
+... | tri> ¬a ¬b c = ⊥-elim ( nat-<> (s≤s c) sx<sy )
+
+sx≤y→x≤y : {x y : ℕ } → suc x ≤ y → x  ≤ y
+sx≤y→x≤y sx≤y = ≤-trans a≤sa sx≤y
+
+x<sy→x≤y : {x y : ℕ } → x < suc y → x  ≤ y
+x<sy→x≤y = <sto≤
+
+x≤y→x<sy : {x y : ℕ } → x ≤ y → x < suc y
+x≤y→x<sy {.zero} {y} z≤n = ≤-trans a<sa (s≤s z≤n)
+x≤y→x<sy {.(suc _)} {.(suc _)} (s≤s le) = s≤s ( x≤y→x<sy le)
+
+sx≤y→x<y : {x y : ℕ } → suc x ≤ y → x < y
+sx≤y→x<y sx≤y = sx≤y
+
+open import Data.Product
+
+i-j=0→i=j : {i j  : ℕ } → j ≤ i  → i - j ≡ 0 → i ≡ j
+i-j=0→i=j {i} {j} le j=0 = begin
+    i  ≡⟨ sym (m-0=m) ⟩
+    i - 0 ≡⟨ cong (λ k → i - k ) (sym j=0) ⟩
+    i - (i - j ) ≡⟨ sym (n-n-m=m le) ⟩
+    j ∎ where open ≡-Reasoning
+
+m*n=0⇒m=0∨n=0 : {i j : ℕ} → i * j ≡ 0 → (i ≡ 0) ∨ ( j ≡ 0 )
+m*n=0⇒m=0∨n=0 {zero} {j} eq = case1 refl
+m*n=0⇒m=0∨n=0 {suc i} {zero} eq = case2 refl
+
+
+minus+1 : {x y  : ℕ } → y ≤ x  → suc (minus x y)  ≡ minus (suc x) y
+minus+1 {zero} {zero} y≤x = refl
+minus+1 {suc x} {zero} y≤x = refl
+minus+1 {suc x} {suc y} y≤x = minus+1 {x} {y} (sx≤py→x≤y y≤x)
+
+minus+yz : {x y z : ℕ } → z ≤ y  → x + minus y z  ≡ minus (x + y) z
+minus+yz {zero} {y} {z} _ = refl
+minus+yz {suc x} {y} {z} z≤y = begin
+         suc x + minus y z ≡⟨ cong suc ( minus+yz z≤y ) ⟩
+         suc (minus (x + y) z) ≡⟨ minus+1 {x + y} {z} (≤-trans z≤y (subst (λ g → y ≤ g) (+-comm y x) x≤x+y) ) ⟩
+         minus (suc x + y) z ∎  where open ≡-Reasoning
+
+minus<=0 : {x y : ℕ } → x ≤ y → minus x y ≡ 0
+minus<=0 {0} {zero} le = refl
+minus<=0 {0} {suc y} le = refl
+minus<=0 {suc x} {suc y} le = minus<=0 {x} {y} (sx≤py→x≤y le)
+
+minus>0 : {x y : ℕ } → x < y → 0 < minus y x
+minus>0 {zero} {suc _} lt = lt
+minus>0 {suc x} {suc y} lt = minus>0 {x} {y} (sx<py→x<y lt)
+
+minus>0→x<y : {x y : ℕ } → 0 < minus y x  → x < y
+minus>0→x<y {x} {y} lt with <-cmp x y
+... | tri< a ¬b ¬c = a
+... | tri≈ ¬a refl ¬c = ⊥-elim ( nat-≡< (sym (minus<=0 {x} ≤-refl)) lt )
+... | tri> ¬a ¬b c = ⊥-elim ( nat-≡< (sym (minus<=0 {y} (≤-trans refl-≤s c ))) lt )
+
+minus+y-y : {x y : ℕ } → (x + y) - y  ≡ x
+minus+y-y {zero} {y} = minus<=0 {zero + y} {y} ≤-refl
+minus+y-y {suc x} {y} = begin
+         (suc x + y) - y ≡⟨ sym (minus+1 {_} {y} x≤y+x) ⟩
+         suc ((x + y) - y) ≡⟨ cong suc (minus+y-y {x} {y}) ⟩
+         suc x ∎  where open ≡-Reasoning
+
+minus+yx-yz : {x y z : ℕ } → (y + x) - (y + z)  ≡ x - z
+minus+yx-yz {x} {zero} {z} = refl
+minus+yx-yz {x} {suc y} {z} = minus+yx-yz {x} {y} {z}
+
+minus+xy-zy : {x y z : ℕ } → (x + y) - (z + y)  ≡ x - z
+minus+xy-zy {x} {y} {z} = subst₂ (λ j k → j - k ≡ x - z  ) (+-comm y x) (+-comm y z) (minus+yx-yz {x} {y} {z})
+
++cancel<l : (x z : ℕ ) {y : ℕ} → y + x < y + z → x < z
++cancel<l x z {zero} lt = lt
++cancel<l x z {suc y} lt = +cancel<l x z {y} (sx<py→x<y lt)
+
++cancel<r : (x z : ℕ ) {y : ℕ} → x + y < z + y → x < z
++cancel<r x z {y} lt = +cancel<l x z (subst₂ (λ j k → j < k ) (+-comm x _) (+-comm z _) lt )
+
+minus<z : {x y z : ℕ } → x < y → z ≤ x → x - z < y - z
+minus<z {x} {y} {z} x<y z≤x = +cancel<r _ _  ( begin
+    suc ( (x - z) + z  ) ≡⟨ cong suc (minus+n (s≤s z≤x) )  ⟩
+    suc x ≤⟨ x<y ⟩
+    y ≡⟨ sym ( minus+n (<-trans (s≤s z≤x) (s≤s x<y) )) ⟩
+    (y - z ) + z ∎ )  where open ≤-Reasoning
+
+
+y-x<y : {x y : ℕ } → 0 < x → 0 < y  → y - x  <  y
+y-x<y {x} {y} 0<x 0<y with <-cmp x (suc y)
+... | tri< a ¬b ¬c = +cancel<r (y - x) _ ( begin
+         suc ((y - x) + x) ≡⟨ cong suc (minus+n {y} {x} a ) ⟩
+         suc y  ≡⟨ +-comm 1 _ ⟩
+         y + suc 0  ≤⟨ +-mono-≤ ≤-refl 0<x ⟩
+         y + x ∎ )  where open ≤-Reasoning
+... | tri≈ ¬a refl ¬c = subst ( λ k → k < y ) (sym (minus<=0 {y} {x} refl-≤s )) 0<y
+... | tri> ¬a ¬b c = subst ( λ k → k < y ) (sym (minus<=0 {y} {x} (≤-trans (≤-trans refl-≤s refl-≤s) c))) 0<y -- suc (suc y) ≤ x → y ≤ x
+
+open import Relation.Binary.Definitions
+
+distr-minus-* : {x y z : ℕ } → (minus x y) * z ≡ minus (x * z) (y * z)
+distr-minus-* {x} {zero} {z} = refl
+distr-minus-* {x} {suc y} {z} with <-cmp x y
+distr-minus-* {x} {suc y} {z} | tri< a ¬b ¬c = begin
+          minus x (suc y) * z
+        ≡⟨ cong (λ k → k * z ) (minus<=0 {x} {suc y} (x<y→≤ a)) ⟩
+           0 * z
+        ≡⟨ sym (minus<=0 {x * z} {z + y * z} le ) ⟩
+          minus (x * z) (z + y * z)
+        ∎  where
+            open ≡-Reasoning
+            le : x * z ≤ z + y * z
+            le  = ≤-trans lemma (subst (λ k → y * z ≤ k ) (+-comm _ z ) (x≤x+y {y * z} {z} ) ) where
+               lemma : x * z ≤ y * z
+               lemma = *≤ {x} {y} {z} (<to≤ a)
+distr-minus-* {x} {suc y} {z} | tri≈ ¬a refl ¬c = begin
+          minus x (suc y) * z
+        ≡⟨ cong (λ k → k * z ) (minus<=0 {x} {suc y} refl-≤s ) ⟩
+           0 * z
+        ≡⟨ sym (minus<=0 {x * z} {z + y * z} (lt {x} {z} )) ⟩
+          minus (x * z) (z + y * z)
+        ∎  where
+            open ≡-Reasoning
+            lt : {x z : ℕ } →  x * z ≤ z + x * z
+            lt {zero} {zero} = z≤n
+            lt {suc x} {zero} = lt {x} {zero}
+            lt {x} {suc z} = ≤-trans lemma refl-≤s where
+               lemma : x * suc z ≤   z + x * suc z
+               lemma = subst (λ k → x * suc z ≤ k ) (+-comm _ z) (x≤x+y {x * suc z} {z})
+distr-minus-* {x} {suc y} {z} | tri> ¬a ¬b c = +m= {_} {_} {suc y * z} ( begin
+           minus x (suc y) * z + suc y * z
+        ≡⟨ sym (proj₂ *-distrib-+ z  (minus x (suc y) )  _) ⟩
+           ( minus x (suc y) + suc y ) * z
+        ≡⟨ cong (λ k → k * z) (minus+n {x} {suc y} (s≤s c))  ⟩
+           x * z
+        ≡⟨ sym (minus+n {x * z} {suc y * z} (s≤s (lt c))) ⟩
+           minus (x * z) (suc y * z) + suc y * z
+        ∎ ) where
+            open ≡-Reasoning
+            lt : {x y z : ℕ } → suc y ≤ x → z + y * z ≤ x * z
+            lt {x} {y} {z} le = *≤ le
+
+distr-minus-*' : {z x y : ℕ } → z * (minus x y)  ≡ minus (z * x) (z * y)
+distr-minus-*' {z} {x} {y} = begin
+        z * (minus x y) ≡⟨ *-comm _ (x - y) ⟩
+        (minus x y) * z ≡⟨ distr-minus-* {x} {y} {z} ⟩
+        minus (x * z) (y * z) ≡⟨ cong₂ (λ j k → j - k ) (*-comm x z ) (*-comm y z) ⟩
+        minus (z * x) (z * y) ∎  where open ≡-Reasoning
+
+minus- : {x y z : ℕ } → suc x > z + y → minus (minus x y) z ≡ minus x (y + z)
+minus- {x} {y} {z} gt = +m= {_} {_} {z} ( begin
+           minus (minus x y) z + z
+        ≡⟨ minus+n {_} {z} lemma ⟩
+           minus x y
+        ≡⟨ +m= {_} {_} {y} ( begin
+              minus x y + y
+           ≡⟨ minus+n {_} {y} lemma1 ⟩
+              x
+           ≡⟨ sym ( minus+n {_} {z + y} gt ) ⟩
+              minus x (z + y) + (z + y)
+           ≡⟨ sym ( +-assoc (minus x (z + y)) _  _ ) ⟩
+              minus x (z + y) + z + y
+           ∎ ) ⟩
+           minus x (z + y) + z
+        ≡⟨ cong (λ k → minus x k + z ) (+-comm _ y )  ⟩
+           minus x (y + z) + z
+        ∎  ) where
+             open ≡-Reasoning
+             lemma1 : suc x > y
+             lemma1 = x+y<z→x<z (subst (λ k → k < suc x ) (+-comm z _ ) gt )
+             lemma : suc (minus x y) > z
+             lemma = <-minus {_} {_} {y} ( subst ( λ x → z + y < suc x ) (sym (minus+n {x} {y}  lemma1 ))  gt )
+
+sn≤1→n=0 : {n : ℕ } → suc n ≤ 1 → n ≡ 0
+sn≤1→n=0 {n} sn≤1 with <-cmp n 0
+... | tri≈ ¬a b ¬c = b
+... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> c sn≤1 )
+
+minus-* : {M k n : ℕ } → n < k  → minus k (suc n) * M ≡ minus (minus k n * M ) M
+minus-* {zero} {k} {n} lt = begin
+           minus k (suc n) * zero
+        ≡⟨ *-comm (minus k (suc n)) zero ⟩
+           zero * minus k (suc n)
+        ≡⟨⟩
+           0 * minus k n
+        ≡⟨ *-comm 0 (minus k n) ⟩
+           minus (minus k n * 0 ) 0
+        ∎  where
+        open ≡-Reasoning
+minus-* {suc m} {k} {n} lt with <-cmp k 1
+minus-* {suc m} {k} {n} lt | tri< a ¬b ¬c = ⊥-elim ( nat-≤> (sx≤py→x≤y a) (≤-trans  (s≤s z≤n) lt) )
+minus-* {suc m} {k} {n} lt | tri≈ ¬a refl ¬c =  subst (λ k → minus 0 k * suc m ≡ minus (minus 1 k * suc m) (suc m)) (sym n=0) lem  where
+    n=0 : n ≡ 0
+    n=0 = sn≤1→n=0 lt
+    lem : minus 0 0 * suc m ≡ minus (minus 1 0 * suc m) (suc m)
+    lem = begin
+        minus 0 0 * suc m ≡⟨⟩
+        0 ≡⟨ sym ( minus<=0 {suc m} {suc m} ≤-refl ) ⟩
+        minus (suc m) (suc m) ≡⟨ cong (λ k → minus k (suc m)) (+-comm 0 (suc m) ) ⟩
+        minus (suc m + 0) (suc m) ≡⟨⟩
+        minus (minus 1 0 * suc m) (suc m) ∎ where open ≡-Reasoning
+minus-* {suc m} {k} {n} lt | tri> ¬a ¬b c = begin
+           minus k (suc n) * M
+        ≡⟨ distr-minus-* {k} {suc n} {M}  ⟩
+           minus (k * M ) ((suc n) * M)
+        ≡⟨⟩
+           minus (k * M ) (M + n * M  )
+        ≡⟨ cong (λ x → minus (k * M) x) (+-comm M _ ) ⟩
+           minus (k * M ) ((n * M) + M )
+        ≡⟨ sym ( minus- {k * M} {n * M} (lemma lt) ) ⟩
+           minus (minus (k * M ) (n * M)) M
+        ≡⟨ cong (λ x → minus x M ) ( sym ( distr-minus-* {k} {n} )) ⟩
+           minus (minus k n * M ) M
+        ∎  where
+             M = suc m
+             lemma : {n k m : ℕ } → n < k  → suc (k * suc m) > suc m + n * suc m
+             lemma {n} {k} {m} lt = ≤-plus-0 {_} {_} {1} (*≤ lt ) 
+             open ≡-Reasoning
+
+x=y+z→x-z=y : {x y z : ℕ } → x ≡ y + z → x - z ≡ y
+x=y+z→x-z=y {x} {zero} {.x} refl = minus<=0 {x} {x} refl-≤ -- x ≡ suc (y + z) → (x ≡ y + z → x - z ≡ y)   → (x - z) ≡ suc y
+x=y+z→x-z=y {suc x} {suc y} {zero} eq = begin -- suc x ≡ suc (y + zero) → (suc x - zero) ≡ suc y
+       suc x - zero ≡⟨ refl ⟩
+       suc x  ≡⟨ eq ⟩
+       suc y + zero ≡⟨ +-comm _ zero ⟩
+       suc y ∎  where open ≡-Reasoning
+x=y+z→x-z=y {suc x} {suc y} {suc z} eq = x=y+z→x-z=y {x} {suc y} {z} ( begin
+       x ≡⟨ cong pred eq ⟩
+       pred (suc y + suc z) ≡⟨ +-comm _ (suc z)  ⟩
+       suc z + y ≡⟨ cong suc ( +-comm _ y ) ⟩
+       suc y + z ∎  ) where open ≡-Reasoning
+
+m*1=m : {m : ℕ } → m * 1 ≡ m
+m*1=m {zero} = refl
+m*1=m {suc m} = cong suc m*1=m
+
++-cancel-1 : (x y z : ℕ ) → x + y  ≡ x + z  → y ≡ z
++-cancel-1 zero y z eq = eq
++-cancel-1 (suc x) y z eq = +-cancel-1 x y z (cong pred eq )
+
++-cancel-0 : (x y z : ℕ ) → y + x ≡ z + x → y ≡ z
++-cancel-0 x y z eq = +-cancel-1 x y z (trans (+-comm x y) (trans eq (sym (+-comm x z)) ))
+
+*-cancel-left : {x y z : ℕ } → x > 0 → x * y ≡ x * z → y ≡ z
+*-cancel-left {suc x} {zero} {zero} lt eq = refl
+*-cancel-left {suc x} {zero} {suc z} lt eq = ⊥-elim ( nat-≡< eq (s≤s (begin
+  x * zero  ≡⟨ *-comm x _ ⟩
+  zero  ≤⟨ z≤n ⟩
+  z + x * suc z ∎ ))) where open ≤-Reasoning
+*-cancel-left {suc x} {suc y} {zero} lt eq = ⊥-elim ( nat-≡< (sym eq) (s≤s (begin
+  x * zero  ≡⟨ *-comm x _ ⟩
+  zero  ≤⟨ z≤n ⟩
+  _ ∎ ))) where open ≤-Reasoning
+*-cancel-left {suc x} {suc y} {suc z} lt eq with cong pred eq
+... | eq1 =  cong suc (*-cancel-left {suc x} {y} {z} lt (+-cancel-0 x _ _ (begin
+   y + x * y + x ≡⟨ +-assoc y _ _ ⟩
+   y + (x * y + x) ≡⟨ cong (λ k → y + (k + x)) (*-comm x _)  ⟩
+   y + (y * x + x) ≡⟨ cong (_+_ y) (+-comm _ x) ⟩
+   y + (x + y * x ) ≡⟨ refl ⟩
+   y + suc y * x ≡⟨ cong (_+_ y) (*-comm (suc y) _)  ⟩
+   y + x * suc y ≡⟨ eq1 ⟩
+   z + x * suc z ≡⟨ refl ⟩
+   _ ≡⟨ sym ( cong (_+_ z) (*-comm (suc z) _) ) ⟩
+   _ ≡⟨ sym ( cong (_+_ z) (+-comm _ x)) ⟩
+   z + (z * x + x) ≡⟨ sym ( cong (λ k → z + (k + x)) (*-comm x _) ) ⟩
+   z + (x * z + x) ≡⟨ sym ( +-assoc z _ _) ⟩
+   z + x * z + x  ∎ ))) where open ≡-Reasoning
+
+record Finduction {n m : Level} (P : Set n ) (Q : P → Set m ) (f : P → ℕ) : Set  (n Level.⊔ m) where
+  field
+    fzero   : {p : P} → f p ≡ zero → Q p
+    pnext : (p : P ) → P
+    decline : {p : P} → 0 < f p  → f (pnext p) < f p
+    ind : {p : P} → Q (pnext p) → Q p
+
+y<sx→y≤x : {x y : ℕ} → y < suc x → y ≤ x
+y<sx→y≤x = x<sy→x≤y
+
+fi0 : (x : ℕ) → x ≤ zero → x ≡ zero
+fi0 .0 z≤n = refl
+
+f-induction : {n m : Level} {P : Set n } → {Q : P → Set m }
+  → (f : P → ℕ)
+  → Finduction P Q f
+  → (p : P ) → Q p
+f-induction {n} {m} {P} {Q} f I p with <-cmp 0 (f p)
+... | tri> ¬a ¬b ()
+... | tri≈ ¬a b ¬c = Finduction.fzero I (sym b)
+... | tri< lt _ _ = f-induction0 p (f p) (<to≤ (Finduction.decline I lt)) where
+   f-induction0 : (p : P) → (x : ℕ) → (f (Finduction.pnext I p)) ≤ x → Q p
+   f-induction0 p zero le = Finduction.ind I (Finduction.fzero I (fi0 _ le))
+   f-induction0 p (suc x) le with <-cmp (f (Finduction.pnext I p)) (suc x)
+   ... | tri< a ¬b ¬c = f-induction0 p x (px≤py a)
+   ... | tri≈ ¬a b ¬c = Finduction.ind I (f-induction0 (Finduction.pnext I p) x (y<sx→y≤x f1)) where
+       f1 : f (Finduction.pnext I (Finduction.pnext I p)) < suc x
+       f1 = subst (λ k → f (Finduction.pnext I (Finduction.pnext I p)) < k ) b ( Finduction.decline I {Finduction.pnext I p}
+         (subst (λ k → 0 < k ) (sym b) (s≤s z≤n ) ))
+   ... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> le c )
+ 
+
+record Ninduction {n m : Level} (P : Set n ) (Q : P → Set m ) (f : P → ℕ) : Set  (n Level.⊔ m) where
+  field
+    pnext : (p : P ) → P
+    fzero   : {p : P} → f (pnext p) ≡ zero → Q p
+    decline : {p : P} → 0 < f p  → f (pnext p) < f p
+    ind : {p : P} → Q (pnext p) → Q p
+
+s≤s→≤ : { i j : ℕ} → suc i ≤ suc j → i ≤ j
+s≤s→≤ = sx≤py→x≤y
+
+n-induction : {n m : Level} {P : Set n } → {Q : P → Set m }
+  → (f : P → ℕ)
+  → Ninduction P Q f
+  → (p : P ) → Q p
+n-induction {n} {m} {P} {Q} f I p  = f-induction0 p (f (Ninduction.pnext I p)) ≤-refl where
+   f-induction0 : (p : P) → (x : ℕ) → (f (Ninduction.pnext I p)) ≤ x  →  Q p
+   f-induction0 p zero lt = Ninduction.fzero I {p} (fi0 _ lt)
+   f-induction0 p (suc x) le with <-cmp (f (Ninduction.pnext I p)) (suc x)
+   ... | tri< a  ¬b ¬c = f-induction0 p x (px≤py a)
+   ... | tri≈ ¬a b ¬c = Ninduction.ind I (f-induction0 (Ninduction.pnext I p) x (s≤s→≤ nle) ) where
+      f>0 :  0 < f (Ninduction.pnext I p)
+      f>0 = subst (λ k → 0 < k ) (sym b) ( s≤s z≤n )
+      nle : suc (f (Ninduction.pnext I (Ninduction.pnext I p))) ≤ suc x
+      nle = subst (λ k → suc (f (Ninduction.pnext I (Ninduction.pnext I p))) ≤ k) b (Ninduction.decline I {Ninduction.pnext I p} f>0 )
+   ... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> le c )
+ 
+
+record Factor (n m : ℕ ) : Set where
+   field
+      factor : ℕ
+      remain : ℕ
+      is-factor : factor * n + remain ≡ m
+
+record Factor< (n m : ℕ ) : Set where
+   field
+      factor : ℕ
+      remain : ℕ
+      is-factor : factor * n + remain ≡ m
+      remain<n : remain < n
+
+record Dividable (n m : ℕ ) : Set where
+   field
+      factor : ℕ
+      is-factor : factor * n + 0 ≡ m
+
+open Factor
+
+DtoF : {n m : ℕ} → Dividable n m → Factor n m
+DtoF {n} {m} record { factor = f ; is-factor = fa } = record { factor = f ; remain = 0 ; is-factor = fa }
+
+FtoD : {n m : ℕ} → (fc : Factor n m) → remain fc ≡ 0 → Dividable n m
+FtoD {n} {m} record { factor = f ; remain = r ; is-factor = fa } refl = record { factor = f ; is-factor = fa }
+
+--divdable^2 : ( n k : ℕ ) → Dividable k ( n * n ) → Dividable k n
+--divdable^2 n k dn2 = {!!}
+
+decf : { n k : ℕ } → ( x : Factor k (suc n) ) → Factor k n
+decf {n} {k} record { factor = f ; remain = r ; is-factor = fa } =
+ decf1 {n} {k} f r fa where
+  decf1 : { n k : ℕ } → (f r : ℕ) → (f * k + r ≡ suc n)  → Factor k n
+  decf1 {n} {k} f (suc r) fa  =  -- this case must be the first
+     record { factor = f ; remain = r ; is-factor = ( begin -- fa : f * k + suc r ≡ suc n
+        f * k + r ≡⟨ cong pred ( begin
+          suc ( f * k + r ) ≡⟨ +-comm _ r ⟩
+          r + suc (f * k)  ≡⟨ sym (+-assoc r 1 _) ⟩
+          (r + 1) + f * k ≡⟨ cong (λ t → t + f * k ) (+-comm r 1) ⟩
+          (suc r ) + f * k ≡⟨ +-comm (suc r) _ ⟩
+          f * k + suc r  ≡⟨ fa ⟩
+          suc n ∎ ) ⟩
+        n ∎ ) }  where open ≡-Reasoning
+  decf1 {n} {zero} (suc f) zero fa  = ⊥-elim ( nat-≡< fa (
+        begin suc (suc f * zero + zero) ≡⟨ cong suc (+-comm _ zero)  ⟩
+        suc (f * 0) ≡⟨ cong suc (*-comm f zero)  ⟩
+        suc zero ≤⟨ s≤s z≤n ⟩
+        suc n ∎ )) where open ≤-Reasoning
+  decf1 {n} {suc k} (suc f) zero fa  =
+     record { factor = f ; remain = k ; is-factor = ( begin -- fa : suc (k + f * suc k + zero) ≡ suc n
+        f * suc k + k ≡⟨ +-comm _ k ⟩
+        k + f * suc k ≡⟨ +-comm zero _ ⟩
+        (k + f * suc k) + zero  ≡⟨ cong pred fa ⟩
+        n ∎ ) }  where open ≡-Reasoning
+
+div0 :  {k : ℕ} → Dividable k 0
+div0 {k} = record { factor = 0; is-factor = refl }
+
+div= :  {k : ℕ} → Dividable k k
+div= {k} = record { factor = 1; is-factor = ( begin
+        k + 0 * k + 0  ≡⟨ trans ( +-comm _ 0) ( +-comm _ 0) ⟩
+        k ∎ ) }  where open ≡-Reasoning
+
+div1 : { k : ℕ } → k > 1 →  ¬  Dividable k 1
+div1 {k} k>1 record { factor = f1 ; is-factor = fa } = ⊥-elim ( nat-≡< (sym fa) ( begin
+     2 ≤⟨ k>1 ⟩
+     k ≡⟨ +-comm 0 _ ⟩
+     k + 0 ≡⟨ refl  ⟩
+     1 * k ≤⟨ *-mono-≤ {1} {f1} (lem1 _ fa) ≤-refl ⟩
+     f1 * k ≡⟨ +-comm 0 _ ⟩
+     f1 * k + 0 ∎  )) where 
+        open ≤-Reasoning
+        lem1 :  (f1 : ℕ) → f1 * k + 0 ≡ 1 → 1 ≤ f1
+        lem1 zero ()
+        lem1 (suc f1) eq = s≤s z≤n
+  
+div+div : { i j k : ℕ } →  Dividable k i →  Dividable k j → Dividable k (i + j) ∧ Dividable k (j + i)
+div+div {i} {j} {k} di dj = ⟪ div+div1 , subst (λ g → Dividable k g) (+-comm i j) div+div1 ⟫ where
+      fki = Dividable.factor di
+      fkj = Dividable.factor dj
+      div+div1 : Dividable k (i + j)
+      div+div1 = record { factor = fki + fkj  ; is-factor = ( begin
+          (fki + fkj) * k + 0 ≡⟨ +-comm _ 0 ⟩
+          (fki + fkj) * k  ≡⟨ *-distribʳ-+ k fki _ ⟩
+          fki * k + fkj * k  ≡⟨ cong₂ ( λ i j → i + j ) (+-comm 0 (fki * k)) (+-comm 0 (fkj * k)) ⟩
+          (fki * k + 0) + (fkj * k + 0) ≡⟨ cong₂ ( λ i j → i + j ) (Dividable.is-factor di) (Dividable.is-factor dj) ⟩
+          i + j  ∎ ) } where
+             open ≡-Reasoning
+
+div-div : { i j k : ℕ } → k > 1 →  Dividable k i →  Dividable k j → Dividable k (i - j) ∧ Dividable k (j - i)
+div-div {i} {j} {k} k>1 di dj = ⟪ div-div1 di dj , div-div1 dj di ⟫ where
+      div-div1 : {i j : ℕ } → Dividable k i →  Dividable k j → Dividable k (i - j)
+      div-div1 {i} {j} di dj = record { factor = fki - fkj  ; is-factor = ( begin
+          (fki - fkj) * k + 0 ≡⟨ +-comm _ 0 ⟩
+          (fki - fkj) * k  ≡⟨ distr-minus-* {fki} {fkj}  ⟩
+          (fki * k) - (fkj * k)  ≡⟨ cong₂ ( λ i j → i - j ) (+-comm 0 (fki * k)) (+-comm 0 (fkj * k)) ⟩
+          (fki * k + 0) - (fkj * k + 0) ≡⟨ cong₂ ( λ i j → i - j ) (Dividable.is-factor di) (Dividable.is-factor dj) ⟩
+          i - j  ∎ ) } where
+             open ≡-Reasoning
+             fki = Dividable.factor di
+             fkj = Dividable.factor dj
+
+open _∧_
+
+div+1 : { i k : ℕ } → k > 1 →  Dividable k i →  ¬ Dividable k (suc i)
+div+1 {i} {k} k>1 d d1 = div1 k>1 div+11 where
+   div+11 : Dividable k 1
+   div+11 = subst (λ g → Dividable k g) (minus+y-y {1} {i} ) ( proj2 (div-div k>1 d d1  ) )
+
+div<k : { m k : ℕ } → k > 1 → m > 0 →  m < k →  ¬ Dividable k m
+div<k {m} {k} k>1 m>0 m<k d = ⊥-elim ( nat-≤> (div<k1 (Dividable.factor d) (Dividable.is-factor d)) m<k ) where
+    div<k1 : (f : ℕ ) → f * k + 0 ≡ m → k ≤ m
+    div<k1 zero eq = ⊥-elim (nat-≡< eq m>0 )
+    div<k1 (suc f) eq = begin
+          k ≤⟨ x≤x+y ⟩
+          k + (f * k + 0) ≡⟨ sym (+-assoc k _ _) ⟩
+          k + f * k + 0 ≡⟨ eq ⟩
+          m ∎  where open ≤-Reasoning
+
+0<factor : { m k : ℕ } → k > 0 → m > 0 →  (d :  Dividable k m ) → Dividable.factor d > 0
+0<factor {m} {k} k>0 m>0 d with Dividable.factor d in eq1
+... | zero = ⊥-elim ( nat-≡< ff1 m>0 ) where
+    ff1 : 0 ≡ m
+    ff1 = begin
+          0 ≡⟨⟩
+          0 * k + 0 ≡⟨ cong  (λ j → j * k + 0) (sym eq1) ⟩
+          Dividable.factor d * k + 0 ≡⟨ Dividable.is-factor d  ⟩
+          m ∎  where open ≡-Reasoning
+... | suc t = s≤s z≤n
+
+div→k≤m : { m k : ℕ } → k > 1 → m > 0 →  Dividable k m → m ≥ k
+div→k≤m {m} {k} k>1 m>0 d with <-cmp m k
+... | tri< a ¬b ¬c = ⊥-elim ( div<k k>1 m>0 a d )
+... | tri≈ ¬a refl ¬c = ≤-refl
+... | tri> ¬a ¬b c = <to≤ c
+
+div1*k+0=k : {k : ℕ } → 1 * k + 0 ≡ k
+div1*k+0=k {k} =  begin
+   1 * k + 0 ≡⟨ cong (λ g → g + 0) (+-comm _ 0) ⟩
+   k + 0 ≡⟨ +-comm _ 0 ⟩
+   k  ∎ where open ≡-Reasoning
+
+
+factor< : {k m : ℕ} → k > 1 → Factor< k m
+factor< {k} {m} k>1 = n-induction {_} {_} {ℕ} {λ m → Factor< k m} F I m where
+    F : ℕ → ℕ 
+    F m = m
+    F0 : ( m : ℕ ) → F (m - k) ≡ 0 → Factor< k m
+    F0 0 eq = record { factor = 0 ; remain = 0 ; is-factor = refl ; remain<n = <-trans a<sa k>1 }
+    F0 (suc m) eq with <-cmp k (suc m)
+    ... | tri< a ¬b ¬c = record { factor = 1 ; remain = 0 ; is-factor = lem00 ; remain<n = <-trans a<sa k>1 } where
+         lem00 :  k + zero + 0 ≡ suc m
+         lem00 = begin  -- minus (suc m) k ≡ 0
+            k + zero + 0 ≡⟨ +-comm (k + 0) _  ⟩
+            k + 0 ≡⟨ +-comm k _  ⟩
+            k ≡⟨ sym ( i-j=0→i=j (≤-trans a≤sa a) eq ) ⟩
+            suc m ∎ where open ≡-Reasoning
+    ... | tri≈ ¬a b ¬c = record { factor = 1 ; remain = 0 ; is-factor = trans (trans (+-comm (k + 0) _) (+-comm k 0)) b ; remain<n = <-trans a<sa k>1 }
+    ... | tri> ¬a ¬b c = record { factor = 0 ; remain = suc m ; is-factor = refl ; remain<n = c } 
+    ind : {m : ℕ} → Factor< k (m - k) → Factor< k m
+    ind {m} record { factor = f ; remain = r ; is-factor = isf ; remain<n = r<n } with <-cmp k (suc m)
+    ... | tri≈ ¬a b ¬c = record { factor = 0 ; remain = m ; is-factor = refl ; remain<n = subst (λ j → m < j) (sym b) a<sa } 
+    ... | tri> ¬a ¬b c = record { factor = 0 ; remain = m ; is-factor = refl ; remain<n = <-trans a<sa c } 
+    ... | tri< a ¬b ¬c = record { factor = suc f ; remain = r ; is-factor = lem00 ; remain<n = r<n } where
+          k<sm : k < suc m
+          k<sm = a
+          lem00 : k + f * k + r ≡ m
+          lem00 = begin
+             k + f * k + r  ≡⟨ +-assoc k _ _  ⟩
+             k + (f * k + r)  ≡⟨ +-comm k _  ⟩
+             (f * k + r) + k  ≡⟨ cong (λ i → i + k ) isf ⟩
+             (m - k) + k  ≡⟨ minus+n k<sm  ⟩
+             m ∎ where open ≡-Reasoning
+    decl : {m  : ℕ } → 0 < m → m - k < m
+    decl {m} 0<m = y-x<y (<-trans a<sa k>1 ) 0<m 
+    I : Ninduction ℕ  _  F
+    I = record {
+              pnext = λ p → p - k
+            ; fzero = λ {m} eq → F0 m eq
+            ; decline = λ {m} lt → decl lt
+            ; ind = λ {p} prev → ind prev
+       } 
+
+Factor<→¬k≤m : {k m : ℕ} → k ≤ m  → (x : Factor< k m ) → Factor<.factor x > 0
+Factor<→¬k≤m {k} {m} k≤m x with Factor<.factor x in eqx
+... | zero = ⊥-elim ( nat-≤> k≤m (begin
+     suc m  ≡⟨ cong suc (sym (Factor<.is-factor x)) ⟩
+     suc (Factor<.factor x * k + Factor<.remain x)  ≡⟨ cong (λ j → suc (j * k + _)) eqx ⟩
+     suc (0 * k + Factor<.remain x)  ≡⟨ refl ⟩
+     suc (Factor<.remain x)  ≤⟨ Factor<.remain<n x ⟩
+     k ∎ ) ) where open ≤-Reasoning
+... | suc fa = s≤s z≤n
+
+Factor<-inject : {k m : ℕ} → k > 1 → (x y : Factor< k m) → (Factor<.factor x ≡ Factor<.factor y ) ∧ (Factor<.remain x ≡ Factor<.remain y ) 
+Factor<-inject {k} {m} k>1 x y = n-induction {_} {_} {ℕ} 
+      {λ m → (x y : Factor< k m) → (Factor<.factor x ≡ Factor<.factor y ) ∧ (Factor<.remain x ≡ Factor<.remain y ) } F I m x y where
+    F : ℕ → ℕ 
+    F m = m
+    f00 : (m : ℕ ) → ( k ≡ suc m ) → (x y : Factor< k (suc m)) → (Factor<.factor x ≡ Factor<.factor y ) ∧ (Factor<.remain x ≡ Factor<.remain y )  
+    f00 m lem00 x y = ⟪ trans (lem02 x) (sym (lem02 y)) , trans (lem01 x) (sym (lem01 y)) ⟫ where
+         lem02 :  (f : Factor< k (suc m)) → Factor<.factor f ≡ 1
+         lem02 f with <-cmp (Factor<.factor f) 1
+         ... | tri< a ¬b ¬c = ⊥-elim ( nat-≡< (Factor<.is-factor f) (begin
+             suc (Factor<.factor f * k + Factor<.remain f)  ≤⟨ s≤s (≤-plus {_} {_} {Factor<.remain f} (*≤ (px≤py a)) ) ⟩
+             suc (0 * k + Factor<.remain f)  ≡⟨⟩
+             suc (0 + Factor<.remain f)  ≡⟨⟩
+             suc (Factor<.remain f)  ≤⟨ Factor<.remain<n f ⟩
+             k  ≡⟨ lem00 ⟩
+             suc m ∎ )) where open ≤-Reasoning
+         ... | tri≈ ¬a b ¬c = b
+         ... | tri> ¬a ¬b c = ⊥-elim ( nat-≡< (sym (Factor<.is-factor f)) (begin -- 1 < Factor<. factor f, fa * k + r > k ≡ suc m
+             suc (suc m) ≡⟨ cong suc (sym lem00) ⟩
+             suc k ≡⟨ sym (+-comm k 1) ⟩
+             k + 1 <⟨ <-plus-0 k>1  ⟩
+             k + k  ≡⟨ cong (λ j → k + j) (+-comm 0 _ ) ⟩
+             k + (k + 0)  ≡⟨⟩
+             k + (k + 0 * k)  ≡⟨ refl ⟩
+             2 * k ≤⟨ *≤ c ⟩ 
+             Factor<.factor f * k ≤⟨ x≤x+y   ⟩ 
+             Factor<.factor f * k + Factor<.remain f ∎ ) ) where open ≤-Reasoning
+         lem03 : k ≡ 1 * k
+         lem03 = +-comm 0 k 
+         lem01 :  (f : Factor< k (suc m)) → Factor<.remain f ≡ 0
+         lem01 f = +-cancel-1 _ _ _ ( begin
+             Factor<.factor f * k + Factor<.remain f  ≡⟨ Factor<.is-factor f ⟩
+             suc m  ≡⟨ sym lem00 ⟩
+             k  ≡⟨ +-comm 0 k ⟩
+             k + 0  ≡⟨ cong (λ j → j + 0) lem03  ⟩
+             1 * k + 0  ≡⟨ cong (λ j → j * k + 0) (sym (lem02 f))  ⟩
+             Factor<.factor f * k + 0  ∎ ) where open ≡-Reasoning
+    F0 : ( m : ℕ ) → F (m - k) ≡ 0 → (x y : Factor< k m) → (Factor<.factor x ≡ Factor<.factor y ) ∧ (Factor<.remain x ≡ Factor<.remain y )  
+    F0 0 eq x y = ⟪ trans (lem00 x) (sym (lem00 y)) , trans (lem01 x) (sym (lem01 y)) ⟫ where
+         lem01 : (f : Factor< k 0) → Factor<.remain f ≡ 0
+         lem01 f with Factor<.remain f in eq1
+         ... | zero = refl
+         ... | suc n = ⊥-elim ( nat-≡< (sym (Factor<.is-factor f)) (begin
+             suc 0 ≤⟨ s≤s z≤n ⟩
+             suc n ≡⟨ sym eq1 ⟩
+             Factor<.remain f ≡⟨ refl ⟩
+             0 + Factor<.remain f ≤⟨ x≤y+x ⟩
+             Factor<.factor f * k + Factor<.remain f  ∎ ) ) where open ≤-Reasoning
+         lem00 : (f : Factor< k 0) → Factor<.factor f ≡ 0
+         lem00 f with m*n=0⇒m=0∨n=0 {Factor<.factor f} {k} (trans (+-comm 0 (Factor<.factor f * k) ) (subst (λ j → _ + j ≡ 0) (lem01 f) (Factor<.is-factor f))) 
+         ... | case1 fa=0 = fa=0
+         ... | case2 k=0 = ⊥-elim (nat-≡< (sym k=0) (<-trans a<sa k>1) )
+    F0 (suc m) eq x y with <-cmp k (suc m)
+    ... | tri< a ¬b ¬c = ⊥-elim ( ¬b lem00 ) where 
+         lem00 :  k ≡ suc m
+         lem00 = begin  
+            k ≡⟨ sym ( i-j=0→i=j (≤-trans a≤sa a) eq ) ⟩
+            suc m ∎ where open ≡-Reasoning
+    ... | tri≈ ¬a b ¬c = f00 m b x y
+    ... | tri> ¬a ¬b c = ⟪ trans ( lem00 x ) (sym (lem00 y)) , trans (lem01 x) (sym (lem01 y)) ⟫ where
+         lem00 : (f : Factor< k (suc m)) → Factor<.factor f ≡ 0
+         lem00 f with Factor<.factor f in eq1
+         ... | zero = refl
+         ... | suc fa = ⊥-elim ( nat-≡< (sym (Factor<.is-factor f)) (begin
+             suc (suc m) ≤⟨ c ⟩
+             k  ≤⟨  x≤x+y ⟩
+             k + Factor<.remain f  ≡⟨ cong (λ j → j + _) (+-comm 0 k)  ⟩
+             suc 0 * k + Factor<.remain f  ≤⟨ ≤-plus {_} {_} {Factor<.remain f} (*≤ {suc 0} {suc fa} {k} (s≤s z≤n)) ⟩
+             suc fa * k + Factor<.remain f  ≡⟨ cong (λ j → j * k + Factor<.remain f) (sym eq1)   ⟩
+             Factor<.factor f * k + Factor<.remain f  ∎ ) ) where open ≤-Reasoning
+         lem01 : (f : Factor< k (suc m)) → Factor<.remain f ≡ (suc m)
+         lem01 f = begin 
+             Factor<.remain f ≡⟨ refl ⟩
+             0 * k + Factor<.remain f ≡⟨ cong (λ j → j * k + Factor<.remain f) (sym (lem00 f))  ⟩
+             Factor<.factor f * k + Factor<.remain f ≡⟨ Factor<.is-factor f ⟩
+             suc m ∎ where open ≡-Reasoning
+    ind : {m : ℕ} 
+        → ( (x y : Factor< k (m - k)) → (Factor<.factor x ≡ Factor<.factor y ) ∧ (Factor<.remain x ≡ Factor<.remain y ) )
+        → (x y : Factor< k m) → (Factor<.factor x ≡ Factor<.factor y ) ∧ (Factor<.remain x ≡ Factor<.remain y )
+    ind {m} prev x y with <∨≤ m k
+    ... | case1 m<k = ⟪ trans (lem00 x) (sym (lem00 y)) , trans (lem01 x) (sym (lem01 y)) ⟫ where
+         lem00 : (x : Factor< k m ) → Factor<.factor x ≡ 0    
+         lem00 x with Factor<.factor x in eqx
+         ... | zero = refl
+         ... | suc fa = ⊥-elim ( nat-≤> (begin
+             k ≤⟨ x≤x+y  ⟩ 
+             k +  (fa * k + Factor<.remain x) ≡⟨ sym (+-assoc k _ _) ⟩
+             ( k +  fa * k )  + Factor<.remain x ≡⟨ refl ⟩
+             suc fa * k  + Factor<.remain x ≡⟨ cong (λ j → j * k + Factor<.remain x) (sym eqx) ⟩
+             Factor<.factor x * k  + Factor<.remain x ≡⟨ Factor<.is-factor x ⟩
+             m ∎  )
+           m<k ) where open ≤-Reasoning
+         lem01 : (f : Factor< k m) → Factor<.remain f ≡ m
+         lem01 f = begin 
+             Factor<.remain f ≡⟨ refl ⟩
+             0 * k + Factor<.remain f ≡⟨ cong (λ j → j * k + Factor<.remain f) (sym (lem00 f))  ⟩
+             Factor<.factor f * k + Factor<.remain f ≡⟨ Factor<.is-factor f ⟩
+             m ∎ where open ≡-Reasoning
+    ... | case2 k≤m = px=py x y k≤m where
+         lem07 : (x : Factor< k m ) → {fa : ℕ } → suc fa ≡ Factor<.factor x →  fa *  k + Factor<.remain x ≡ m - k
+         lem07 x {fa} eq1 = begin
+              fa * k + Factor<.remain x ≡⟨ sym (minus+y-y {_} {k} ) ⟩
+              (fa * k + Factor<.remain x + k ) - k ≡⟨ cong (λ j → j - k) ( begin 
+                  fa * k + Factor<.remain x + k ≡⟨ +-assoc (fa * k) _ _ ⟩
+                  fa * k + (Factor<.remain x + k)   ≡⟨ cong (λ j → fa * k + j) (+-comm _ k) ⟩
+                  fa * k + (k + Factor<.remain x )   ≡⟨ sym (+-assoc (fa * k) k _ ) ⟩
+                  (fa * k + k) + Factor<.remain x    ≡⟨ cong (λ j → j + Factor<.remain x ) (+-comm (fa * k) k) ⟩
+                  suc fa * k + Factor<.remain x   ≡⟨ cong (λ j → j * k + _) (eq1) ⟩ 
+                  Factor<.factor x * k + Factor<.remain x ∎ ) ⟩
+              (Factor<.factor x * k + Factor<.remain x) - k  ≡⟨ cong (λ j → j - k ) (Factor<.is-factor x) ⟩
+              m - k ∎ where open ≡-Reasoning
+         px=py : (x y : Factor< k m) → k ≤ m → (Factor<.factor x ≡ Factor<.factor y ) ∧ (Factor<.remain x ≡ Factor<.remain y ) 
+         px=py x y k≤m with Factor<.factor x in eqx | Factor<.factor y in eqy
+         ... | zero | _ = ⊥-elim ( nat-≡< (sym eqx) (Factor<→¬k≤m k≤m x) )
+         ... | _ | zero = ⊥-elim ( nat-≡< (sym eqy) (Factor<→¬k≤m k≤m y) )
+         ... | suc fx | suc fy with  prev 
+             record { factor = fx ; remain = Factor<.remain x ; is-factor = lem07 x (sym eqx) ; remain<n = Factor<.remain<n x }
+             record { factor = fy ; remain = Factor<.remain y ; is-factor = lem07 y (sym eqy) ; remain<n = Factor<.remain<n y }
+         ... | ⟪ eqf , eqr ⟫ = ⟪ cong suc eqf , eqr ⟫
+    decl : {m  : ℕ } → 0 < m → m - k < m
+    decl {m} 0<m = y-x<y (<-trans a<sa k>1 ) 0<m 
+    I : Ninduction ℕ  _  F
+    I = record {
+              pnext = λ p → p - k
+            ; fzero = λ {m} eq → F0 m eq
+            ; decline = λ {m} lt → decl lt
+            ; ind = λ {p} prev → ind prev
+       } 
+
+F<toD : {n m : ℕ} → (fc : Factor< n m) → Factor<.remain fc ≡ 0 → Dividable n m
+F<toD {n} {m} record { factor = f ; remain = r ; is-factor = fa ; remain<n = _ } refl 
+    = record { factor = f ; is-factor = fa }
+
+DtoF< : {n m : ℕ} → Dividable n m → 0 < n → Factor< n m
+DtoF< {n} {m} record { factor = f ; is-factor = fa } 0<n = record { factor = f ; is-factor = fa  ; remain = 0 ; remain<n = 0<n }
+
+F<to¬D : {n m nx : ℕ} → (fc : Factor< n m) → 1 < n → Factor<.remain fc ≡ suc nx → ¬ Dividable n m
+F<to¬D {n} {m} fc 1<n eq div = ⊥-elim ( nat-≡< (sym (proj2 ( Factor<-inject {n} {m} 1<n  fc (DtoF< div (<-trans a<sa 1<n) )))) 0<r  ) where
+      0<r : 0 < Factor<.remain fc 
+      0<r = subst ( λ k → 0 < k ) (sym eq) (s≤s z≤n)
+
+--
+-- we can use factor<  and check Factor.remain ≡ 0
+--     Factor.remain ≡ 0   →   Dividable k m
+--     ¬ Factor.remain ≡ 0 → ¬ Dividable k m
+--
+decD : {k m : ℕ} → k > 1 → Dec0 (Dividable k m )
+decD {k} {m} k>1 = dec0 (factor< {k} {m} k>1) where
+    dec0 : Factor< k m → Dec0 (Dividable k m)
+    dec0 fc with Factor<.remain fc in eq1
+    ... | zero = yes0 record { factor = Factor<.factor fc ; is-factor = trans (cong (λ j → Factor<.factor fc * k + j) (sym eq1))  (Factor<.is-factor fc)  }
+    ... | suc t = no0 ( λ dv → F<to¬D fc k>1 eq1 dv )
+
+
+