liquidhaskell-0.8.10.7: tests/pos/T1874.hs
module T1874 where
{-@ LIQUID "--exact-data-cons" @-}
{-@ LIQUID "--reflection" @-}
{-@ LIQUID "--ple" @-}
import Language.Haskell.Liquid.ProofCombinators
data Ty = TInt | TFun Ty Ty
{-@
type FunTy = { t : Ty | isFunTy t }
data Ty = TInt | TFun Ty Ty
@-}
{-@ measure isFunTy @-}
isFunTy :: Ty -> Bool
isFunTy (TFun _ _) = True
isFunTy _ = False
{- reflect funResTy @-}
{-@ measure funResTy @-}
{-@ funResTy :: FunTy -> Ty @-}
funResTy :: Ty -> Ty
funResTy (TFun _ b) = b
{-@ measure funArgTy @-}
{-@ funArgTy :: FunTy -> Ty @-}
funArgTy :: Ty -> Ty
funArgTy (TFun a _) = a
{-@
type FunExp = { e : Exp | isFunTy (exprType e) }
type ExpT T = { e : Exp | T = exprType e }
data Exp
= Var Ty Int
| Lam Ty Exp
| App (e1 :: FunExp) (ExpT (funArgTy (exprType e1)))
@-}
data Exp
= Var Ty Int
| Lam Ty Exp
| App Exp Exp
{-@ measure exprType @-}
exprType :: Exp -> Ty
exprType (Var ty _) = ty
exprType (Lam ty e) = TFun ty (exprType e)
exprType (App e1 _) = funResTy (exprType e1)
{-@ typeAppLam_prop :: ty:Ty -> e0:Exp -> e1:Exp -> { exprType (App (Lam ty e0) e1) = exprType e0 } @-}
typeAppLam_prop :: Ty -> Exp -> Exp -> Proof
typeAppLam_prop _ _ _ = trivial *** QED
{-@ step :: e:Exp -> Maybe (ExpT (exprType e)) @-}
step :: Exp -> Maybe Exp
step e0 = case e0 of
Var{} -> Nothing
Lam{} -> Nothing
App e1 e2 -> case step e1 of
Just e1' -> Just (App e1' e2)
Nothing -> case step e2 of
Just e2' -> Just (App e1 e2')
Nothing -> case e1 of
Lam ty e11 ->
Just e11 -- ? typeAppLam_prop ty e11 e2
_ -> Nothing