packages feed

liquidhaskell-0.8.10.7: tests/ple/pos/tmp.hs

{-@ LIQUID "--reflection"     @-}
{-@ LIQUID "--ple"            @-}
{-@ LIQUID "--no-termination" @-}

module Tutorial6 where

import Prelude hiding (lookup)

data Wff = Var Int
         | Not Wff
         | Wff :|: Wff
         | Wff :&: Wff
         deriving (Eq, Ord)

data NNF = Atom Bool Int
         | NOr NNF NNF
         | NAnd NNF NNF

{-@ reflect toWff @-}
toWff :: NNF -> Wff
toWff (Atom True i) = Var i
toWff (Atom False i) = Not (Var i)
toWff (NOr f g) = toWff f :|: toWff g
toWff (NAnd f g) = toWff f :&: toWff g

{-@ reflect lookup @-}
lookup :: [a] -> a -> Int -> a
lookup []     def _ = def
lookup (v:_)  _   0 = v
lookup (_:vs) def k = lookup vs def (k-1)

{-@ reflect eval @-}
eval :: [Bool] -> Wff -> Bool
eval s (Var i)   = lookup s False i
eval s (f :&: g) = eval s f && eval s g
eval s (f :|: g) = (eval s f) || (eval s g)
eval s (Not f)   = not (eval s f)

{-@ reflect evalNNF @-}
evalNNF :: [Bool] -> NNF -> Bool
evalNNF s (Atom True i)  = lookup s False i
evalNNF s (Atom False i) = not (lookup s False i)
evalNNF s (NOr p q)      = evalNNF s p || evalNNF s q
evalNNF s (NAnd p q)     = evalNNF s p && evalNNF s q

{-@ toNNF :: s:[Bool] -> p:Wff -> { q: NNF | eval s p = evalNNF s q } @-}
toNNF :: [Bool] -> Wff -> NNF
toNNF _ (Var i)  = Atom True i
toNNF s (Not p)         = case p of
                            Not p -> let glub = toNNF s p in glub
                            _     -> undefined
toNNF _ _        = undefined