packages feed

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