liquidhaskell-0.8.10.7: benchmarks/haskell16/pos/tmp/MonoidPeano.hs
{-#LH LIQUID "--higherorder" @-}
{-#LH LIQUID "--totality" @-}
{-#LH LIQUID "--exact-data-cons" @-}
{-#LH LIQUID "--higherorderqs" @-}
module Peano where
import Prelude hiding (plus)
-- import Proves
import 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
infixl 3 ==.
(==.) :: a -> a -> a
x ==. _ = x
data Peano = Z | S Peano
{-#LH data Peano [toInt] = Z | S {prev :: Peano} @-}
{-#LH measure toInt @-}
toInt :: Peano -> Int
{-#LH toInt :: Peano -> Nat @-}
toInt Z = 0
toInt (S n) = 1 + toInt n
{-#LH axiomatize plus @-}
plus :: Peano -> Peano -> Peano
plus Z m = m
plus (S n) m = S (plus n m)
{-#LH zeroL :: n:Peano -> { plus Z n == n } @-}
zeroL n
= plus Z n
==! n
*** QED
{-#LH zeroR :: n:Peano -> { plus n Z == n } @-}
zeroR Z
= plus Z Z
==! Z
*** QED
zeroR (S n)
= plus (S n) Z
==! S (plus n Z)
==! S n ∵ zeroR n
*** QED
{-#LH plusSuccR :: n:Peano -> m:Peano -> { plus n (S m) = S (plus n m) } @-}
plusSuccR Z m
= plus Z (S m)
==! S m
==! S (plus Z m)
*** QED
plusSuccR (S n) m
= plus (S n) (S m)
==! S (plus n (S m))
==! S (S (plus n m)) ∵ plusSuccR n m
==! S (plus (S n) m)
*** QED
{-#LH plusComm :: a:_ -> b:_ -> {plus a b == plus b a} @-}
plusComm Z b
= plus Z b
==! plus b Z ∵ zeroR b
*** QED
plusComm (S a) b
= plus (S a) b
==! S (plus a b)
==! S (plus b a) ∵ plusComm a b
==! plus b (S a) ∵ plusSuccR b a
*** QED
{-#LH plusAssoc :: a:_ -> b:_ -> c:_ -> {plus (plus a b) c == plus a (plus b c) } @-}
plusAssoc Z b c
= plus (plus Z b) c
==! plus b c
==! plus Z (plus b c)
*** QED
plusAssoc (S a) b c
= plus (plus (S a) b) c
==! plus (S (plus a b)) c
==! S (plus (plus a b) c)
==! S (plus a (plus b c)) ∵ plusAssoc a b c
==! plus (S a) (plus b c)
*** QED