liquidhaskell-0.8.0.2: tests/pos/IndEven.hs
{-# LANGUAGE GADTs #-}
{-@ LIQUID "--exact-data-con" @-}
{-@ LIQUID "--higherorder" @-}
{-@ LIQUID "--automatic-instances=liquidinstances" @-}
module Ev where
{-@ data Peano [toNat] @-}
data Peano where
Z :: Peano
S :: Peano -> Peano
data EvProp where
Ev :: Peano -> EvProp
data Ev where
EZ :: Ev
ESS :: Peano -> Ev -> Ev
{-@ data Ev [evNat] where
EZ :: Prop (Ev Z)
| ESS :: n:Peano -> Prop (Ev n) -> Prop (Ev (S (S n)))
@-}
{-@ test :: n:Peano -> Prop (Ev (S (S n))) -> Prop (Ev n) @-}
test :: Peano -> Ev -> Ev
test n (ESS m q) = q
{-@ reflect isEven @-}
isEven :: Peano -> Bool
isEven Z = True
isEven (S Z) = False
isEven (S (S n)) = isEven n
{-@ thm1 :: n:{Peano | isEven n} -> Prop (Ev n) @-}
thm1 :: Peano -> Ev
thm1 Z = EZ
thm1 (S (S n)) = ESS n (thm1 n)
{-@ thm2 :: n:Peano -> pf:(Prop (Ev n)) -> {isEven n} / [evNat pf] @-}
thm2 :: Peano -> Ev -> ()
thm2 n EZ = ()
thm2 n (ESS m pf) = thm2 m pf
--------------------------------------------------------------------------------
-- | Syntactic sugar for prelude -----------------------------------------------
--------------------------------------------------------------------------------
{-@ measure prop :: a -> b @-}
{-@ type Prop E = {v:_ | prop v = E} @-}
--------------------------------------------------------------------------------
-- | Crufty termination stuff [How to auto-generate?] --------------------------
--------------------------------------------------------------------------------
{-@ measure toNat @-}
{-@ toNat :: Peano -> Nat @-}
toNat :: Peano -> Int
toNat Z = 0
toNat (S n) = 1 + toNat n
{-@ measure evNat @-}
{-@ evNat :: Ev -> Nat @-}
evNat :: Ev -> Int
evNat EZ = 0
evNat (ESS _ p) = 1 + evNat p
-- G := p : {prop p = Even (S (S n)) /\ prop p = Even (S (S m))}
-- ; q : {prop q = Even m}
-- ==> n = m
-- ==> prop q = Even n