z3-408.2: test/Z3/Base/Spec.hs
-- TODO: Create a context for all the tests, use push; ...; pop to rollback
module Z3.Base.Spec
( spec )
where
import Test.Hspec
import Test.QuickCheck ( property )
import Test.QuickCheck.Monadic
import qualified Z3.Base as Z3
withContext :: ActionWith Z3.Context -> IO ()
withContext k = do
ctx <- Z3.withConfig Z3.mkContext
k ctx
anyZ3Error :: Selector Z3.Z3Error
anyZ3Error = const True
spec :: Spec
spec = around withContext $ do
context "Propositional Logic and Equality" $ do
specify "mkBool" $ \ctx -> property $ \b ->
monadicIO $ do
x::Maybe Bool <- run $ do
ast <- Z3.mkBool ctx b
Z3.getBoolValue ctx ast
assert $ x == Just b
context "Numerals" $ do
specify "mkInt" $ \ctx -> property $ \(i :: Integer) ->
monadicIO $ do
x::Integer <- run $ do
ast <- Z3.mkInteger ctx i;
Z3.getInt ctx ast;
assert $ x == i
context "AST Equality and Substitution" $ do
specify "isEqAST" $ \ctx ->
monadicIO $ do
(r1, r2) <- run $ do
x1 <- Z3.mkFreshIntVar ctx "x1"
x2 <- Z3.mkFreshIntVar ctx "x2"
x3 <- Z3.mkFreshIntVar ctx "x3"
s <- Z3.mkAdd ctx [x1, x2]
s' <- Z3.mkAdd ctx [x1, x2]
s23 <- Z3.mkAdd ctx [x2, x3]
r1 <- Z3.isEqAST ctx s s'
r2 <- Z3.isEqAST ctx s s23
return (r1, r2)
assert r1
assert (not r2)
specify "substitute" $ \ctx ->
monadicIO $ do
r <- run $ do
x1 <- Z3.mkFreshIntVar ctx "x1"
x2 <- Z3.mkFreshIntVar ctx "x2"
x3 <- Z3.mkFreshIntVar ctx "x3"
x4 <- Z3.mkFreshIntVar ctx "x4"
s12 <- Z3.mkAdd ctx [x1, x2]
s34 <- Z3.mkAdd ctx [x3, x4]
s34' <- Z3.substitute ctx s12 [(x1, x3), (x2, x4)]
Z3.isEqAST ctx s34 s34'
assert r
context "Bit-vectors" $ do
specify "mkBvmul" $ \ctx ->
let bad = do {
x <- Z3.mkFreshIntVar ctx "x";
Z3.mkBvmul ctx x x
}
in
bad `shouldThrow` anyZ3Error