packages feed

liquidhaskell-0.7.0.0: tests/elim/Ackermann0_inline.hs

-- | Proving ackermann properties from
-- | http://www.cs.yorku.ca/~gt/papers/Ackermann-function.pdf

{-@ LIQUID "--higherorder"     @-}
{-@ LIQUID "--totality"        @-}
{- LIQUID "--maxparams=5"     @-}
{-@ LIQUID "--eliminate"       @-}
{- LIQUID "--scrape-internals" @-}


module Ackermann where

import Proves
-- import Helper

-- | First ackermann definition

{-@ axiomatize ack @-}
{-@ ack :: n:Nat -> x:Nat -> Nat / [n, x] @-}
ack :: Int -> Int -> Int
ack n x
  | n == 0
  = x + 2
  | x == 0
  = 2
  | otherwise
  = ack (n-1) (ack n (x-1))

-- | Second ackermann definition

{-@ axiomatize iack @-}
{-@ iack :: Nat -> Nat -> Nat -> Nat @-}
{- measure iack :: Int -> Int -> Int -> Int @-}
{- iack :: h:Nat -> n:Nat -> x:Nat -> {v:Nat | v == iack h n x && v == if h == 0 then x else ack n (iack (h-1) n x) } @-}
iack :: Int -> Int -> Int -> Int
iack h n x
  = if h == 0 then x else ack n (iack (h-1) n x)

-- | Equivalence of definitions

{-@ def_eq :: n:Nat -> x:Nat -> {v:Proof | ack (n+1) x == iack x n 2 }  / [x]@-}
def_eq :: Int -> Int -> Proof
def_eq n x
  = undefined

lemma3_eq :: Int -> Int -> Int -> Proof
{-@ lemma3_eq :: n:Nat -> x:Nat -> y:{Nat | x <= y} -> {v:Proof | ack n x <= ack n y} / [y] @-}
lemma3_eq n x y
  = undefined



-- | Lemma 2.4
{-@ type Pos = {v:Int | 0 < v } @-}

lemma4 :: Int -> Int -> Proof
{-@ lemma4 :: x:Pos -> n:Nat -> {v:Proof | ack n x < ack (n+1) x } @-}
lemma4 x n
  = undefined


lemma4_eq     :: Int -> Int -> Bool
{-@ lemma4_eq :: n:Nat -> x:Nat -> {v:Bool | ack n x <= ack (n+1) x } @-}
lemma4_eq n x
  = undefined


-- Lemma 2.7

lemma7 :: Int -> Int -> Int -> Bool
{-@ lemma7 :: h:Nat -> n:Nat -> x:Nat
           -> {v:Bool | iack h n x <= iack h (n+1) x } @-}
lemma7 h n x
  | x == 0 , h == 0
  = proof (
     iack 0 n 0 ==! (0 :: Int)
                ==! iack 0 (n+1) 0 )
  | h == 0
  = proof (
      iack 0 n x ==! x
                 ==! iack 0 (n+1) x )
  | h > 0
  = proof (
      ((
      iack h n x ==! ack n (iack (h-1) n x)
                 <=! ack (n+1) (iack (h-1) n x) ) (lemma4_eq n (iack (h-1) n x))
                 <=! ack (n+1) (iack (h-1) (n+1) x) ) (lemma7 (h-1) n x
                                                     &&& lemma3_eq (n+1) (iack (h-1) n x) (iack (h-1) (n+1) x)
                                                      )
                 <=! iack h (n+1) x )