z3-encoding-0.3.0.0: src/Z3/Base/Logic.hs
-- | Predicates
module Z3.Base.Logic (Pred(..)) where
import Z3.Monad
import Z3.Base.Class
import Z3.Base.Atom
data Pred t ty a where
PTrue :: Pred t ty a
PFalse :: Pred t ty a
PConj :: Pred t ty a -> Pred t ty a -> Pred t ty a
PDisj :: Pred t ty a -> Pred t ty a -> Pred t ty a
PXor :: Pred t ty a -> Pred t ty a -> Pred t ty a
PNeg :: Pred t ty a -> Pred t ty a
PForAll :: String -> ty -> Pred t ty a -> Pred t ty a
PExists :: String -> ty -> Pred t ty a -> Pred t ty a
PExists2 :: String -> String -> ty -> Pred t ty a -> Pred t ty a
PImpli :: Pred t ty a -> Pred t ty a -> Pred t ty a
PIff :: Pred t ty a -> Pred t ty a -> Pred t ty a
PAtom :: Atom -> Pred t ty a
-- User-extension
PExt :: a -> Pred t ty a
instance (Z3Sorted t, Z3Sorted ty, Z3Encoded a) => Z3Encoded (Pred t ty a) where
encode PTrue = mkTrue
encode PFalse = mkFalse
encode (PConj p1 p2) = do
a1 <- encode p1
a2 <- encode p2
mkAnd [a1, a2]
encode (PDisj p1 p2) = do
a1 <- encode p1
a2 <- encode p2
mkOr [a1, a2]
encode (PXor p1 p2) = do
a1 <- encode p1
a2 <- encode p2
mkXor a1 a2
encode (PNeg p) = encode p >>= mkNot
encode (PForAll x ty p) = do
sym <- mkStringSymbol x
xsort <- sortOf ty
-- "0" is de brujin idx for current binder
-- it is passed to Z3 which returns an intenal (idx :: AST)
-- This (idx :: AST) will be used to replace the variable
-- in the abstraction body when encountered, thus it is stored
-- in context by bindVal we provide
-- XXX: we should save and restore qualifier context here
idx <- mkBound 0 xsort
local $ do
bindVal x idx xsort
body <- encode p
-- The first [] is [Pattern], which is not really useful here
mkForall [] [sym] [xsort] body
encode (PExists x ty p) = do
sym <- mkStringSymbol x
xsort <- sortOf ty
idx <- mkBound 0 xsort
local $ do
bindVal x idx xsort
a <- encode p
mkExists [] [sym] [xsort] a
-- HACK
encode (PExists2 x y ty p) = do
sym1 <- mkStringSymbol x
sym2 <- mkStringSymbol y
xsort <- sortOf ty
idx1 <- mkBound 0 xsort
idx2 <- mkBound 1 xsort
local $ do
bindVal x idx1 xsort
bindVal y idx2 xsort
a <- encode p
mkExists [] [sym1, sym2] [xsort, xsort] a
encode (PImpli p1 p2) = do
a1 <- encode p1
a2 <- encode p2
mkImplies a1 a2
encode (PIff p1 p2) = do
a1 <- encode p1
a2 <- encode p2
mkIff a1 a2
encode (PAtom a) = encode a
encode (PExt ext) = encode ext