-- This focuses more on the programming and type and programming -- side of lean than proving type. All done here can be done in haskell. -- Pat = Pranshu's nat inductive Pat where | zero : Pat | succ (p : Pat) : Pat -- ntp stands for nat to pat def ntp (n : Nat) : Pat := match n with | 0 => Pat.zero | n'+1 => Pat.succ (ntp n') -- ptn = pat to nat def ptn (p : Pat) : Nat := match p with | Pat.zero => 0 | Pat.succ n => 1 + ptn n -- True #eval let a := 10 ; (ptn (ntp a)) == a -- TODO prove properly using theorem or something -- in haskell this would be -- data Pat = Zero | Succ Pat def isZero (p : Pat) : Bool := match p with | Pat.zero => true | Pat.succ _ => false -- This is true #eval isZero Pat.zero ------- Now I make basic functions ------- def plus (l : Pat) (r : Pat) : Pat := match l with | Pat.zero => r | Pat.succ p => plus p (Pat.succ r) -- (Pat.succ Pat.zero) #eval plus Pat.zero (Pat.succ Pat.zero) -- (Pat.succ Pat.zero) #eval plus (Pat.succ Pat.zero) Pat.zero -- (Pat.succ (Pat.succ Pat.zero)) #eval plus (Pat.succ Pat.zero) (Pat.succ Pat.zero) -- Pred is like `- 1` def pred (p : Pat) : Pat := match p with | Pat.zero => Pat.zero | Pat.succ k => k def sub (l : Pat) (r : Pat) : Pat := match r with | Pat.zero => l | Pat.succ p => pred (sub l p) def greater_than (p : Pat) (k : Pat) : Bool := match sub p k with | Pat.zero => false | _ => true -- False #eval greater_than (ntp 2) (ntp 3) -- -- ERROR 'failed to prove termination' -- def div (n : Pat) (k : Pat) : Pat := -- if greater_than k n -- then Pat.zero -- else Pat.succ (div (sub n k) k) -- termination_by?