packages feed

liquidhaskell-0.8.10.7: benchmarks/popl18/ple/pos/Peano.hs

{-@ LIQUID "--reflection" @-}
{-@ LIQUID "--ple"        @-}

module Peano where

import Prelude hiding (plus)

import Language.Haskell.Liquid.ProofCombinators

-- Why do we need these?
zeroR     :: Peano -> Proof
zeroL     :: Peano -> Proof
plusAssoc :: Peano -> Peano -> Peano -> Proof
plusComm  :: Peano -> Peano -> Proof
plusSuccR :: Peano -> Peano -> Proof


data Peano = Z | S Peano

{-@ data Peano [toInt] @-} 

{-@ measure toInt @-}
toInt :: Peano -> Int

{-@ toInt :: Peano -> Nat @-}
toInt Z     = 0
toInt (S n) = 1 + toInt n

{-@ axiomatize plus @-}
plus :: Peano -> Peano -> Peano
plus Z m     = m
plus (S n) m = S (plus n m)

{-@ zeroL :: n:Peano -> { plus Z n == n }  @-}
zeroL n = trivial 

{-@ zeroR :: n:Peano -> { plus n Z == n }  @-}
zeroR Z     = trivial 
zeroR (S n) = zeroR n

{-@ plusSuccR :: n:Peano -> m:Peano -> { plus n (S m) = S (plus n m) } @-}
plusSuccR Z     _ = trivial
plusSuccR (S n) m = plusSuccR n m

{-@ plusComm :: a:_ -> b:_  -> {plus a b == plus b a} @-}
plusComm Z b = zeroR b
plusComm (S a) b = plusComm a b &&& plusSuccR b a

{-@ plusAssoc :: a:_ -> b:_ -> c:_ -> {plus (plus a b) c == plus a (plus b c) } @-}
plusAssoc Z _ _     = trivial
plusAssoc (S a) b c = plusAssoc a b c