packages feed

target-0.2.0.0: test/Expr.hs

{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-@ LIQUID "--idirs=../src" @-}
module Expr where

import           Data.Set                         (Set, (\\))
import qualified Data.Set                         as Set
import           GHC.Generics

import           Test.LiquidCheck
import           Test.LiquidCheck.Eval            (setSym)
import           Test.LiquidCheck.Expr            (app)

import           BasicTypes                       (TupleSort (..))
import           Control.Applicative
import           Control.Monad.State
import qualified Data.HashMap.Strict              as HM
import qualified Data.Map                         as M
import           Data.Monoid
import           Data.Proxy
import           Language.Fixpoint.Types          (Sort (..))
import           Language.Haskell.Liquid.PredType
import           Language.Haskell.Liquid.Types    (RType (..))
import           Test.LiquidCheck
import           Test.LiquidCheck.Gen             (GenState (..))
import           Test.LiquidCheck.Util
import           TysWiredIn                       (listTyCon, tupleTyCon)

data Expr = Var Char
          | Lam Char Expr
          | App Expr Expr
          deriving (Generic, Show)

hasDepth d (Var c)   = d == 1
hasDepth d (Lam c e) = hasDepth (d-1) e
hasDepth d (App f e) = hasDepth (d-1) f || hasDepth (d-1) e

{-@ measure freeVars :: Expr -> (Set Char)
    freeVars (Var v)   = (Set_sng v)
    freeVars (Lam v e) = (Set_dif (freeVars e) (Set_sng v))
    freeVars (App x y) = (Set_cup (freeVars x) (freeVars y))
  @-}

{-@ measure isLam :: Expr -> Prop
    isLam (Var v)   = false
    isLam (Lam v e) = true
    isLam (App x y) = false
  @-}

{-@ data Expr = Var (x1 :: Char)
              | Lam (x2 :: Char) (x3 :: Expr)
              | App (x4 :: Expr) (x5 :: Expr)
  @-}

{-@ type Closed = {v:Expr | (Set_emp (freeVars v))} @-}

instance Constrain Expr

{-@ measure prop :: Bool -> Prop
    prop (True)  = true
    prop (False) = false
  @-}
{-@ type Valid = {v:Bool | (prop v)} @-}

freeVars (Var v)   = Set.singleton v
freeVars (Lam v e) = freeVars e \\ Set.singleton v
freeVars (App x y) = freeVars x `Set.union` freeVars y

{-@ inv :: Closed -> Valid @-}
inv e = Set.null $ freeVars e 

closed = inv

{- subst :: e1:Closed -> n:Char -> e2:Closed
          -> {v:Closed | (if (Set_mem n (freeVars e2))
                          then (freeVars v) = (Set_cup (Set_dif (freeVars e2)
                                                                (Set_sng n))
                                                       (freeVars e1))
                          else (freeVars v) = (freeVars e2))}
  @-}
{-@ subst :: e1:Closed -> n:Char -> e2:Closed -> Closed @-}
subst :: Expr -> Char -> Expr -> Expr
subst e1 v e2@(Var v')
  = if v == v' then e1 else e2
subst e1 v e2@(Lam v' e')
  | v == v'             = e2
  | v' `Set.member` fvs = subst e1 v (freshen e2)
  | otherwise           = Lam v' (subst e1 v e')
  where
    fvs = freeVars e1
subst e v (App e1 e2)
  = App e1' e2'
  where
    e1' = subst e v e1
    e2' = subst e v e2

{-@ freshen :: e:{Expr | (isLam e)} -> {v:Expr | (freeVars v) = (freeVars e)} @-}
freshen (Lam v e) = Lam v' (subst (Var v') v e)
  where
    v' = fresh v (freeVars e)

{-@ fresh :: n:Char -> ns:Set Char -> {v:Char | not (v == n || (Set_mem v ns))} @-}
fresh :: Char -> Set Char -> Char
fresh v vs = succ $ Set.findMax (Set.insert v vs)

--instance (Ord a, Constrain a) => Constrain (Set a) where
--  getType _ = FObj "Data.Set.Base.Set"
--  gen p d (RApp c ts ps r)
--    = do tyi <- gets tyconInfo
--         let listRTyCon  = tyi HM.! listTyCon
--         gen (Proxy :: Proxy [a]) d (RApp listRTyCon ts [] mempty)
--  stitch  d t = stitch d t >>= \(xs :: [a]) -> return $ Set.fromList xs
--  toExpr  s = app setSym [toExpr x | x <- Set.toList s]

  encode v t = undefined

liquidTests :: [(String, Test)]
liquidTests = [ ("inv",     T inv)
              , ("freshen", T freshen)
--              , ("fresh",   T fresh)
              , ("subst",   T subst)]