liquidhaskell-0.8.0.2: tests/neg/EvalQuery.hs
{-@ LIQUID "--exact-data-con" @-}
{-@ LIQUID "--higherorder" @-}
{-@ LIQUID "--no-termination" @-}
{-@ LIQUID "--automatic-instances=liquidinstances" @-}
module Query where
data Atom = VarX
| VarY
| Const Int
data Query = Le Atom Atom
| And Query Query
| Or Query Query
{-@ data Blob = B { xVal :: Int, yVal :: Int } @-}
data Blob = B { xVal :: Int, yVal :: Int }
{-@ reflect evalA @-}
evalA :: Blob -> Atom -> Int
evalA b VarX = xVal b
evalA b VarY = yVal b
evalA _ (Const n) = n
{-@ reflect evalQ @-}
evalQ :: Blob -> Query -> Bool
evalQ b (Le a1 a2) = (evalA b a1) <= (evalA b a2)
evalQ b (And q1 q2) = (evalQ b q1) && (evalQ b q2)
evalQ b (Or q1 q2) = (evalQ b q1) || (evalQ b q2)
{-@ filterQ :: q:Query -> [Blob] -> [{b:Blob | evalQ b q}] @-}
filterQ :: Query -> [Blob] -> [Blob]
filterQ q [] = []
filterQ q (b:bs)
| evalQ b q = b : filterQ q bs
| otherwise = filterQ q bs
{-@ test1 :: [Blob] -> [{v: Blob | xVal v <= 5}] @-}
test1 = filterQ q1
where
q1 = (VarX `Le` (Const 10))
{-@ test2 :: [Blob] -> [{v: Blob | xVal v <= 10 && yVal v <= 20}] @-}
test2 = filterQ q2
where
q2 = (VarX `Le` (Const 10)) `And` (VarY `Le` (Const 20))