grisette-0.2.0.0: test/Grisette/Backend/SBV/Data/SMT/LoweringTests.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Grisette.Backend.SBV.Data.SMT.LoweringTests where
import Control.Monad.Trans
import Data.Bits
import Data.Dynamic
import qualified Data.HashMap.Strict as M
import Data.Proxy
import qualified Data.SBV as SBV
import qualified Data.SBV.Control as SBV
import Grisette.Backend.SBV.Data.SMT.Lowering
import Grisette.Backend.SBV.Data.SMT.Solving
import Grisette.Backend.SBV.Data.SMT.SymBiMap
import Grisette.Core.Data.BV
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.InternedCtors
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.SomeTerm
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.Term
import Test.Tasty
import Test.Tasty.HUnit
testUnaryOpLowering ::
forall a b as n.
( HasCallStack,
SupportedPrim a,
SBV.EqSymbolic (TermTy n b),
Typeable (TermTy n a),
SBV.SymVal as,
TermTy n a ~ SBV.SBV as,
Show as
) =>
GrisetteSMTConfig n ->
(Term a -> Term b) ->
String ->
(TermTy n a -> TermTy n b) ->
Assertion
testUnaryOpLowering config f name sbvfun = do
let a :: Term a = ssymTerm "a"
let fa :: Term b = f a
SBV.runSMTWith (sbvConfig config) $ do
(m, lt) <- lowerSinglePrim config fa
let sbva :: Maybe (TermTy n a) = M.lookup (SomeTerm a) (biMapToSBV m) >>= fromDynamic
case sbva of
Nothing -> lift $ assertFailure "Failed to extract the term"
Just sbvav -> SBV.query $ do
SBV.constrain $ lt SBV..== sbvfun sbvav
satres <- SBV.checkSat
case satres of
SBV.Sat -> return ()
_ -> lift $ assertFailure $ "Lowering for " ++ name ++ " generated unsolvable formula"
SBV.runSMTWith (sbvConfig config) $ do
(m, lt) <- lowerSinglePrim config fa
let sbvv :: Maybe (TermTy n a) = M.lookup (SomeTerm a) (biMapToSBV m) >>= fromDynamic
case sbvv of
Nothing -> lift $ assertFailure "Failed to extract the term"
Just sbvvv -> SBV.query $ do
SBV.constrain $ lt SBV../= sbvfun sbvvv
r <- SBV.checkSat
case r of
SBV.Sat -> do
counterExample <- SBV.getValue sbvvv
lift $ assertFailure $ "Translation counter example found: " ++ show counterExample
SBV.Unsat -> return ()
_ -> lift $ assertFailure $ "Lowering for " ++ name ++ " generated unknown formula"
testUnaryOpLowering' ::
forall a b as n tag.
( HasCallStack,
UnaryOp tag a b,
SBV.EqSymbolic (TermTy n b),
Typeable (TermTy n a),
SBV.SymVal as,
TermTy n a ~ SBV.SBV as,
Show as
) =>
GrisetteSMTConfig n ->
tag ->
(TermTy n a -> TermTy n b) ->
Assertion
testUnaryOpLowering' config t = testUnaryOpLowering @a @b @as config (constructUnary t) (show t)
testBinaryOpLowering ::
forall a b c as bs n.
( HasCallStack,
SupportedPrim a,
SupportedPrim b,
SBV.EqSymbolic (TermTy n c),
Typeable (TermTy n a),
Typeable (TermTy n b),
SBV.SymVal as,
SBV.SymVal bs,
Show as,
Show bs,
TermTy n a ~ SBV.SBV as,
TermTy n b ~ SBV.SBV bs
) =>
GrisetteSMTConfig n ->
(Term a -> Term b -> Term c) ->
String ->
(TermTy n a -> TermTy n b -> TermTy n c) ->
Assertion
testBinaryOpLowering config f name sbvfun = do
let a :: Term a = ssymTerm "a"
let b :: Term b = ssymTerm "b"
let fab :: Term c = f a b
SBV.runSMTWith (sbvConfig config) $ do
(m, lt) <- lowerSinglePrim config fab
let sbva :: Maybe (TermTy n a) = M.lookup (SomeTerm a) (biMapToSBV m) >>= fromDynamic
let sbvb :: Maybe (TermTy n b) = M.lookup (SomeTerm b) (biMapToSBV m) >>= fromDynamic
case (sbva, sbvb) of
(Just sbvav, Just sbvbv) -> SBV.query $ do
SBV.constrain $ lt SBV..== sbvfun sbvav sbvbv
satres <- SBV.checkSat
case satres of
SBV.Sat -> return ()
_ -> lift $ assertFailure $ "Lowering for " ++ name ++ " generated unsolvable formula"
_ -> lift $ assertFailure "Failed to extract the term"
SBV.runSMTWith (sbvConfig config) $ do
(m, lt) <- lowerSinglePrim config fab
let sbva :: Maybe (TermTy n a) = M.lookup (SomeTerm a) (biMapToSBV m) >>= fromDynamic
let sbvb :: Maybe (TermTy n b) = M.lookup (SomeTerm b) (biMapToSBV m) >>= fromDynamic
case (sbva, sbvb) of
(Just sbvav, Just sbvbv) -> SBV.query $ do
SBV.constrain $ lt SBV../= sbvfun sbvav sbvbv
r <- SBV.checkSat
case r of
SBV.Sat -> do
counterExampleA <- SBV.getValue sbvav
counterExampleB <- SBV.getValue sbvbv
lift $ assertFailure $ "Translation counter example found: " ++ show (counterExampleA, counterExampleB)
SBV.Unsat -> return ()
_ -> lift $ assertFailure $ "Lowering for " ++ name ++ " generated unknown formula"
_ -> lift $ assertFailure "Failed to extract the term"
testBinaryOpLowering' ::
forall a b c as bs n tag.
( HasCallStack,
BinaryOp tag a b c,
SBV.EqSymbolic (TermTy n c),
Typeable (TermTy n a),
Typeable (TermTy n b),
SBV.SymVal as,
SBV.SymVal bs,
Show as,
Show bs,
TermTy n a ~ SBV.SBV as,
TermTy n b ~ SBV.SBV bs
) =>
GrisetteSMTConfig n ->
tag ->
(TermTy n a -> TermTy n b -> TermTy n c) ->
Assertion
testBinaryOpLowering' config t = testBinaryOpLowering @a @b @c @as @bs config (constructBinary t) (show t)
testTernaryOpLowering ::
forall a b c d as bs cs n.
( HasCallStack,
SupportedPrim a,
SupportedPrim b,
SupportedPrim c,
SBV.EqSymbolic (TermTy n d),
Typeable (TermTy n a),
Typeable (TermTy n b),
Typeable (TermTy n c),
SBV.SymVal as,
SBV.SymVal bs,
SBV.SymVal cs,
Show as,
Show bs,
Show cs,
TermTy n a ~ SBV.SBV as,
TermTy n b ~ SBV.SBV bs,
TermTy n c ~ SBV.SBV cs
) =>
GrisetteSMTConfig n ->
(Term a -> Term b -> Term c -> Term d) ->
String ->
(TermTy n a -> TermTy n b -> TermTy n c -> TermTy n d) ->
Assertion
testTernaryOpLowering config f name sbvfun = do
let a :: Term a = ssymTerm "a"
let b :: Term b = ssymTerm "b"
let c :: Term c = ssymTerm "c"
let fabc :: Term d = f a b c
SBV.runSMTWith (sbvConfig config) $ do
(m, lt) <- lowerSinglePrim config fabc
let sbva :: Maybe (TermTy n a) = M.lookup (SomeTerm a) (biMapToSBV m) >>= fromDynamic
let sbvb :: Maybe (TermTy n b) = M.lookup (SomeTerm b) (biMapToSBV m) >>= fromDynamic
let sbvc :: Maybe (TermTy n c) = M.lookup (SomeTerm c) (biMapToSBV m) >>= fromDynamic
case (sbva, sbvb, sbvc) of
(Just sbvav, Just sbvbv, Just sbvcv) -> SBV.query $ do
SBV.constrain $ lt SBV..== sbvfun sbvav sbvbv sbvcv
satres <- SBV.checkSat
case satres of
SBV.Sat -> return ()
_ -> lift $ assertFailure $ "Lowering for " ++ name ++ " generated unsolvable formula"
_ -> lift $ assertFailure "Failed to extract the term"
SBV.runSMTWith (sbvConfig config) $ do
(m, lt) <- lowerSinglePrim config fabc
let sbva :: Maybe (TermTy n a) = M.lookup (SomeTerm a) (biMapToSBV m) >>= fromDynamic
let sbvb :: Maybe (TermTy n b) = M.lookup (SomeTerm b) (biMapToSBV m) >>= fromDynamic
let sbvc :: Maybe (TermTy n c) = M.lookup (SomeTerm c) (biMapToSBV m) >>= fromDynamic
case (sbva, sbvb, sbvc) of
(Just sbvav, Just sbvbv, Just sbvcv) -> SBV.query $ do
SBV.constrain $ lt SBV../= sbvfun sbvav sbvbv sbvcv
r <- SBV.checkSat
case r of
SBV.Sat -> do
counterExampleA <- SBV.getValue sbvav
counterExampleB <- SBV.getValue sbvbv
counterExampleC <- SBV.getValue sbvcv
lift $
assertFailure $
"Translation counter example found: "
++ show (counterExampleA, counterExampleB, counterExampleC)
SBV.Unsat -> return ()
_ -> lift $ assertFailure $ "Lowering for " ++ name ++ " generated unknown formula"
_ -> lift $ assertFailure "Failed to extract the term"
testTernaryOpLowering' ::
forall a b c d as bs cs n tag.
( HasCallStack,
TernaryOp tag a b c d,
SBV.EqSymbolic (TermTy n d),
Typeable (TermTy n a),
Typeable (TermTy n b),
Typeable (TermTy n c),
SBV.SymVal as,
SBV.SymVal bs,
SBV.SymVal cs,
Show as,
Show bs,
Show cs,
TermTy n a ~ SBV.SBV as,
TermTy n b ~ SBV.SBV bs,
TermTy n c ~ SBV.SBV cs
) =>
GrisetteSMTConfig n ->
tag ->
(TermTy n a -> TermTy n b -> TermTy n c -> TermTy n d) ->
Assertion
testTernaryOpLowering' config t = testTernaryOpLowering @a @b @c @d @as @bs @cs config (constructTernary t) (show t)
loweringTests :: TestTree
loweringTests =
let unboundedConfig = precise SBV.z3
boundedConfig = approx (Proxy @5) SBV.z3
in testGroup
"LoweringTests"
[ testGroup
"Bool Lowering"
[ testCase "Not" $ do
testUnaryOpLowering @Bool @Bool unboundedConfig notTerm "not" SBV.sNot,
testCase "And" $ do
testBinaryOpLowering @Bool @Bool @Bool unboundedConfig andTerm "and" (SBV..&&)
testBinaryOpLowering @Bool @Bool @Bool
unboundedConfig
andTerm
"and"
(\x y -> SBV.sNot (x SBV..<+> y) SBV..&& (x SBV..|| y)),
testCase "Or" $ do
testBinaryOpLowering @Bool @Bool @Bool unboundedConfig orTerm "or" (SBV..||)
testBinaryOpLowering @Bool @Bool @Bool
unboundedConfig
orTerm
"or"
(\x y -> (x SBV..<+> y) SBV..|| (x SBV..&& y)),
testCase "Eqv" $ do
testBinaryOpLowering @Bool @Bool @Bool unboundedConfig eqvTerm "eqv" (SBV..==)
testBinaryOpLowering @Bool @Bool @Bool
unboundedConfig
eqvTerm
"eqv"
(\x y -> SBV.sNot (x SBV..<+> y)),
testCase "ITE" $ do
testTernaryOpLowering @Bool @Bool @Bool @Bool unboundedConfig iteTerm "ite" SBV.ite
testTernaryOpLowering @Bool @Bool @Bool @Bool
unboundedConfig
iteTerm
"ite"
(\c x y -> (c SBV..=> x) SBV..&& (SBV.sNot c SBV..=> y))
],
testGroup
"Integer Lowering"
[ testCase "Add" $ do
testBinaryOpLowering @Integer @Integer @Integer unboundedConfig addNumTerm "(+)" (+)
testBinaryOpLowering @Integer @Integer @Integer
unboundedConfig
addNumTerm
"(+)"
(\x y -> (x + 1) * (y + 1) - x * y - 1)
testBinaryOpLowering @Integer @Integer @Integer boundedConfig addNumTerm "(+)" (+)
testBinaryOpLowering @Integer @Integer @Integer
boundedConfig
addNumTerm
"(+)"
(\x y -> (x + 1) * (y + 1) - x * y - 1),
testCase "Uminus" $ do
testUnaryOpLowering @Integer @Integer unboundedConfig uminusNumTerm "negate" negate
testUnaryOpLowering @Integer @Integer
unboundedConfig
uminusNumTerm
"negate"
(\x -> (x + 1) * (x + 1) - 3 * x - x * x - 1)
testUnaryOpLowering @Integer @Integer boundedConfig uminusNumTerm "negate" negate
testUnaryOpLowering @Integer @Integer
boundedConfig
uminusNumTerm
"negate"
(\x -> (x + 1) * (x + 1) - 3 * x - x * x - 1),
testCase "Abs" $ do
testUnaryOpLowering @Integer @Integer unboundedConfig absNumTerm "abs" abs
testUnaryOpLowering @Integer @Integer boundedConfig absNumTerm "abs" abs,
testCase "Signum" $ do
testUnaryOpLowering @Integer @Integer unboundedConfig signumNumTerm "signum" signum
testUnaryOpLowering @Integer @Integer boundedConfig signumNumTerm "signum" signum,
testCase "Times" $ do
testBinaryOpLowering @Integer @Integer @Integer unboundedConfig timesNumTerm "(*)" (*)
testBinaryOpLowering @Integer @Integer @Integer
unboundedConfig
timesNumTerm
"(*)"
(\x y -> (x + 1) * (y + 1) - x - y - 1)
testBinaryOpLowering @Integer @Integer @Integer boundedConfig timesNumTerm "(*)" (*)
testBinaryOpLowering @Integer @Integer @Integer
boundedConfig
timesNumTerm
"(*)"
(\x y -> (x + 1) * (y + 1) - x - y - 1),
testCase "Lt" $ do
testBinaryOpLowering @Integer @Integer @Bool unboundedConfig ltNumTerm "(<)" (SBV..<)
testBinaryOpLowering @Integer @Integer @Bool
unboundedConfig
ltNumTerm
"(<)"
(\x y -> x * 2 - x SBV..< y * 2 - y)
testBinaryOpLowering @Integer @Integer @Bool boundedConfig ltNumTerm "(<)" (SBV..<)
testBinaryOpLowering @Integer @Integer @Bool
boundedConfig
ltNumTerm
"(<=)"
(\x y -> x * 2 - x SBV..< y * 2 - y),
testCase "Le" $ do
testBinaryOpLowering @Integer @Integer @Bool unboundedConfig leNumTerm "(<=)" (SBV..<=)
testBinaryOpLowering @Integer @Integer @Bool
unboundedConfig
leNumTerm
"(<=)"
(\x y -> x * 2 - x SBV..<= y * 2 - y)
testBinaryOpLowering @Integer @Integer @Bool boundedConfig leNumTerm "(<=)" (SBV..<=)
testBinaryOpLowering @Integer @Integer @Bool
boundedConfig
leNumTerm
"(<=)"
(\x y -> x * 2 - x SBV..<= y * 2 - y),
testCase "Div" $ do
testBinaryOpLowering @Integer @Integer @Integer unboundedConfig divIntegralTerm "div" SBV.sDiv
testBinaryOpLowering @Integer @Integer @Integer boundedConfig divIntegralTerm "div" SBV.sDiv,
testCase "Mod" $ do
testBinaryOpLowering @Integer @Integer @Integer unboundedConfig modIntegralTerm "mod" SBV.sMod
testBinaryOpLowering @Integer @Integer @Integer boundedConfig modIntegralTerm "mod" SBV.sMod,
testCase "Quot" $ do
testBinaryOpLowering @Integer @Integer @Integer unboundedConfig quotIntegralTerm "quot" SBV.sQuot
testBinaryOpLowering @Integer @Integer @Integer boundedConfig quotIntegralTerm "quot" SBV.sQuot,
testCase "Rem" $ do
testBinaryOpLowering @Integer @Integer @Integer unboundedConfig remIntegralTerm "rem" SBV.sRem
testBinaryOpLowering @Integer @Integer @Integer boundedConfig remIntegralTerm "rem" SBV.sRem
],
testGroup
"IntN Lowering"
[ testCase "Add" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) unboundedConfig addNumTerm "(+)" (+)
testBinaryOpLowering @(IntN 5) @(IntN 5)
unboundedConfig
addNumTerm
"(+)"
(\x y -> (x + 1) * (y + 1) - x * y - 1),
testCase "Uminus" $ do
testUnaryOpLowering @(IntN 5) unboundedConfig uminusNumTerm "negate" negate
testUnaryOpLowering @(IntN 5)
unboundedConfig
uminusNumTerm
"negate"
(\x -> (x + 1) * (x + 1) - 3 * x - x * x - 1),
testCase "Abs" $ do
testUnaryOpLowering @(IntN 5) unboundedConfig absNumTerm "abs" abs,
testCase "Signum" $ do
testUnaryOpLowering @(IntN 5) unboundedConfig signumNumTerm "signum" signum,
testCase "Times" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) unboundedConfig timesNumTerm "(*)" (*)
testBinaryOpLowering @(IntN 5) @(IntN 5)
unboundedConfig
timesNumTerm
"(*)"
(\x y -> (x + 1) * (y + 1) - x - y - 1),
testCase "Lt" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) unboundedConfig ltNumTerm "(<)" (SBV..<)
testBinaryOpLowering @(IntN 5) @(IntN 5)
unboundedConfig
ltNumTerm
"(<)"
(\x y -> x * 2 - x SBV..< y * 2 - y),
testCase "Le" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) unboundedConfig leNumTerm "(<=)" (SBV..<=)
testBinaryOpLowering @(IntN 5) @(IntN 5)
unboundedConfig
leNumTerm
"(<=)"
(\x y -> x * 2 - x SBV..<= y * 2 - y),
testCase "Extract" $ do
testUnaryOpLowering @(IntN 5) @(IntN 1)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @1))
"select"
(SBV.bvExtract @0 @0 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 1)
unboundedConfig
(bvselectTerm (Proxy @1) (Proxy @1))
"select"
(SBV.bvExtract @1 @1 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 1)
unboundedConfig
(bvselectTerm (Proxy @2) (Proxy @1))
"select"
(SBV.bvExtract @2 @2 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 1)
unboundedConfig
(bvselectTerm (Proxy @3) (Proxy @1))
"select"
(SBV.bvExtract @3 @3 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 1)
unboundedConfig
(bvselectTerm (Proxy @4) (Proxy @1))
"select"
(SBV.bvExtract @4 @4 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 2)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @2))
"select"
(SBV.bvExtract @1 @0 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 2)
unboundedConfig
(bvselectTerm (Proxy @1) (Proxy @2))
"select"
(SBV.bvExtract @2 @1 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 2)
unboundedConfig
(bvselectTerm (Proxy @2) (Proxy @2))
"select"
(SBV.bvExtract @3 @2 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 2)
unboundedConfig
(bvselectTerm (Proxy @3) (Proxy @2))
"select"
(SBV.bvExtract @4 @3 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 3)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @3))
"select"
(SBV.bvExtract @2 @0 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 3)
unboundedConfig
(bvselectTerm (Proxy @1) (Proxy @3))
"select"
(SBV.bvExtract @3 @1 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 3)
unboundedConfig
(bvselectTerm (Proxy @2) (Proxy @3))
"select"
(SBV.bvExtract @4 @2 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 4)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @4))
"select"
(SBV.bvExtract @3 @0 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 4)
unboundedConfig
(bvselectTerm (Proxy @1) (Proxy @4))
"select"
(SBV.bvExtract @4 @1 @5 Proxy Proxy)
testUnaryOpLowering @(IntN 5) @(IntN 5)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @5))
"select"
id,
testCase "Extension" $ do
testUnaryOpLowering @(IntN 5) @(IntN 6)
unboundedConfig
(bvzeroExtendTerm (Proxy @6))
"bvzeroExtend"
SBV.zeroExtend
testUnaryOpLowering @(IntN 5) @(IntN 10)
unboundedConfig
(bvzeroExtendTerm (Proxy @10))
"bvzeroExtend"
SBV.zeroExtend
testUnaryOpLowering @(IntN 5) @(IntN 6)
unboundedConfig
(bvsignExtendTerm (Proxy @6))
"bvsignExtend"
SBV.signExtend
testUnaryOpLowering @(IntN 5) @(IntN 10)
unboundedConfig
(bvsignExtendTerm (Proxy @10))
"bvsignExtend"
SBV.signExtend,
testCase "Concat" $ do
testBinaryOpLowering @(IntN 4) @(IntN 5) @(IntN 9)
unboundedConfig
bvconcatTerm
"bvconcat"
(SBV.#),
testCase "AndBits" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) unboundedConfig andBitsTerm "(.&.)" (.&.),
testCase "OrBits" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) unboundedConfig orBitsTerm "(.|.)" (.|.),
testCase "XorBits" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) unboundedConfig xorBitsTerm "xor" xor,
testCase "ComplementBits" $ do
testUnaryOpLowering @(IntN 5) unboundedConfig complementBitsTerm "complement" complement,
testCase "ShiftBits" $ do
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` 0) "shift" id
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` 1) "shift" (`shift` 1)
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` 2) "shift" (`shift` 2)
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` 3) "shift" (`shift` 3)
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` 4) "shift" (`shift` 4)
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` 5) "shift" (`shift` 5)
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` 5) "shift" (const 0)
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` (-1)) "shift" (`shift` (-1))
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` (-2)) "shift" (`shift` (-2))
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` (-3)) "shift" (`shift` (-3))
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` (-4)) "shift" (`shift` (-4))
testUnaryOpLowering @(IntN 5) unboundedConfig (`shiftBitsTerm` (-5)) "shift" (`shift` (-5))
testUnaryOpLowering @(IntN 5)
unboundedConfig
(`shiftBitsTerm` (-5))
"shift"
(\x -> SBV.ite (x SBV..>= 0) 0 (-1)),
testCase "RotateBits" $ do
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` 0) "rotate" id
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` 1) "rotate" (`rotate` 1)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` 2) "rotate" (`rotate` 2)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` 3) "rotate" (`rotate` 3)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` 4) "rotate" (`rotate` 4)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` 5) "rotate" (`rotate` 5)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` 5) "rotate" id
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-1)) "rotate" (`rotate` (-1))
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-1)) "rotate" (`rotate` 4)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-2)) "rotate" (`rotate` (-2))
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-2)) "rotate" (`rotate` 3)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-3)) "rotate" (`rotate` (-3))
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-3)) "rotate" (`rotate` 2)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-4)) "rotate" (`rotate` (-4))
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-4)) "rotate" (`rotate` 1)
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-5)) "rotate" (`rotate` (-5))
testUnaryOpLowering @(IntN 5) unboundedConfig (`rotateBitsTerm` (-5)) "rotate" id,
testCase "Div - bounded" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) @(IntN 5) unboundedConfig divBoundedIntegralTerm "div" SBV.sDiv
testBinaryOpLowering @(IntN 5) @(IntN 5) @(IntN 5) boundedConfig divBoundedIntegralTerm "div" SBV.sDiv,
testCase "Mod - bounded" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) @(IntN 5) unboundedConfig modBoundedIntegralTerm "mod" SBV.sMod
testBinaryOpLowering @(IntN 5) @(IntN 5) @(IntN 5) boundedConfig modBoundedIntegralTerm "mod" SBV.sMod,
testCase "Quot - bounded" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) @(IntN 5) unboundedConfig quotBoundedIntegralTerm "quot" SBV.sQuot
testBinaryOpLowering @(IntN 5) @(IntN 5) @(IntN 5) boundedConfig quotBoundedIntegralTerm "quot" SBV.sQuot,
testCase "Rem - bounded" $ do
testBinaryOpLowering @(IntN 5) @(IntN 5) @(IntN 5) unboundedConfig remBoundedIntegralTerm "rem" SBV.sRem
testBinaryOpLowering @(IntN 5) @(IntN 5) @(IntN 5) boundedConfig remBoundedIntegralTerm "rem" SBV.sRem
],
testGroup
"WordN"
[ testCase "Add" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) unboundedConfig addNumTerm "(+)" (+)
testBinaryOpLowering @(WordN 5) @(WordN 5)
unboundedConfig
addNumTerm
"(+)"
(\x y -> (x + 1) * (y + 1) - x * y - 1),
testCase "Uminus" $ do
testUnaryOpLowering @(WordN 5) unboundedConfig uminusNumTerm "negate" negate
testUnaryOpLowering @(WordN 5)
unboundedConfig
uminusNumTerm
"negate"
(\x -> (x + 1) * (x + 1) - 3 * x - x * x - 1),
testCase "Abs" $ do
testUnaryOpLowering @(WordN 5) unboundedConfig absNumTerm "abs" abs,
testCase "Signum" $ do
testUnaryOpLowering @(WordN 5) unboundedConfig signumNumTerm "signum" signum,
testCase "Times" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) unboundedConfig timesNumTerm "(*)" (*)
testBinaryOpLowering @(WordN 5) @(WordN 5)
unboundedConfig
timesNumTerm
"(*)"
(\x y -> (x + 1) * (y + 1) - x - y - 1),
testCase "Lt" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) unboundedConfig ltNumTerm "(<)" (SBV..<)
testBinaryOpLowering @(WordN 5) @(WordN 5)
unboundedConfig
ltNumTerm
"(<)"
(\x y -> x * 2 - x SBV..< y * 2 - y),
testCase "Le" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) unboundedConfig leNumTerm "(<=)" (SBV..<=)
testBinaryOpLowering @(WordN 5) @(WordN 5)
unboundedConfig
leNumTerm
"(<=)"
(\x y -> x * 2 - x SBV..<= y * 2 - y),
testCase "Extract" $ do
testUnaryOpLowering @(WordN 5) @(WordN 1)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @1))
"select"
(SBV.bvExtract @0 @0 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 1)
unboundedConfig
(bvselectTerm (Proxy @1) (Proxy @1))
"select"
(SBV.bvExtract @1 @1 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 1)
unboundedConfig
(bvselectTerm (Proxy @2) (Proxy @1))
"select"
(SBV.bvExtract @2 @2 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 1)
unboundedConfig
(bvselectTerm (Proxy @3) (Proxy @1))
"select"
(SBV.bvExtract @3 @3 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 1)
unboundedConfig
(bvselectTerm (Proxy @4) (Proxy @1))
"select"
(SBV.bvExtract @4 @4 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 2)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @2))
"select"
(SBV.bvExtract @1 @0 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 2)
unboundedConfig
(bvselectTerm (Proxy @1) (Proxy @2))
"select"
(SBV.bvExtract @2 @1 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 2)
unboundedConfig
(bvselectTerm (Proxy @2) (Proxy @2))
"select"
(SBV.bvExtract @3 @2 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 2)
unboundedConfig
(bvselectTerm (Proxy @3) (Proxy @2))
"select"
(SBV.bvExtract @4 @3 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 3)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @3))
"select"
(SBV.bvExtract @2 @0 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 3)
unboundedConfig
(bvselectTerm (Proxy @1) (Proxy @3))
"select"
(SBV.bvExtract @3 @1 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 3)
unboundedConfig
(bvselectTerm (Proxy @2) (Proxy @3))
"select"
(SBV.bvExtract @4 @2 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 4)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @4))
"select"
(SBV.bvExtract @3 @0 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 4)
unboundedConfig
(bvselectTerm (Proxy @1) (Proxy @4))
"select"
(SBV.bvExtract @4 @1 @5 Proxy Proxy)
testUnaryOpLowering @(WordN 5) @(WordN 5)
unboundedConfig
(bvselectTerm (Proxy @0) (Proxy @5))
"select"
id,
testCase "Extension" $ do
testUnaryOpLowering @(WordN 5) @(WordN 6)
unboundedConfig
(bvzeroExtendTerm (Proxy @6))
"bvzeroExtend"
SBV.zeroExtend
testUnaryOpLowering @(WordN 5) @(WordN 10)
unboundedConfig
(bvzeroExtendTerm (Proxy @10))
"bvzeroExtend"
SBV.zeroExtend
testUnaryOpLowering @(WordN 5) @(WordN 6)
unboundedConfig
(bvsignExtendTerm (Proxy @6))
"bvsignExtend"
SBV.signExtend
testUnaryOpLowering @(WordN 5) @(WordN 10)
unboundedConfig
(bvsignExtendTerm (Proxy @10))
"bvsignExtend"
SBV.signExtend,
testCase "Concat" $ do
testBinaryOpLowering @(WordN 4) @(WordN 5) @(WordN 9)
unboundedConfig
bvconcatTerm
"bvconcat"
(SBV.#),
testCase "AndBits" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) unboundedConfig andBitsTerm "(.&.)" (.&.),
testCase "OrBits" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) unboundedConfig orBitsTerm "(.|.)" (.|.),
testCase "XorBits" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) unboundedConfig xorBitsTerm "xor" xor,
testCase "ComplementBits" $ do
testUnaryOpLowering @(WordN 5) unboundedConfig complementBitsTerm "complement" complement,
testCase "ShiftBits" $ do
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` 0) "shift" id
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` 1) "shift" (`shift` 1)
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` 2) "shift" (`shift` 2)
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` 3) "shift" (`shift` 3)
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` 4) "shift" (`shift` 4)
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` 5) "shift" (`shift` 5)
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` 5) "shift" (const 0)
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` (-1)) "shift" (`shift` (-1))
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` (-2)) "shift" (`shift` (-2))
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` (-3)) "shift" (`shift` (-3))
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` (-4)) "shift" (`shift` (-4))
testUnaryOpLowering @(WordN 5) unboundedConfig (`shiftBitsTerm` (-5)) "shift" (`shift` (-5))
testUnaryOpLowering @(WordN 5)
unboundedConfig
(`shiftBitsTerm` (-5))
"shift"
(\x -> SBV.ite (x SBV..>= 0) 0 (-1)),
testCase "RotateBits" $ do
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` 0) "rotate" id
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` 1) "rotate" (`rotate` 1)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` 2) "rotate" (`rotate` 2)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` 3) "rotate" (`rotate` 3)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` 4) "rotate" (`rotate` 4)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` 5) "rotate" (`rotate` 5)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` 5) "rotate" id
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-1)) "rotate" (`rotate` (-1))
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-1)) "rotate" (`rotate` 4)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-2)) "rotate" (`rotate` (-2))
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-2)) "rotate" (`rotate` 3)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-3)) "rotate" (`rotate` (-3))
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-3)) "rotate" (`rotate` 2)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-4)) "rotate" (`rotate` (-4))
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-4)) "rotate" (`rotate` 1)
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-5)) "rotate" (`rotate` (-5))
testUnaryOpLowering @(WordN 5) unboundedConfig (`rotateBitsTerm` (-5)) "rotate" id,
testCase "Div" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) @(WordN 5) unboundedConfig divIntegralTerm "div" SBV.sDiv
testBinaryOpLowering @(WordN 5) @(WordN 5) @(WordN 5) boundedConfig divIntegralTerm "div" SBV.sDiv,
testCase "Mod" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) @(WordN 5) unboundedConfig modIntegralTerm "mod" SBV.sMod
testBinaryOpLowering @(WordN 5) @(WordN 5) @(WordN 5) boundedConfig modIntegralTerm "mod" SBV.sMod,
testCase "Quot" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) @(WordN 5) unboundedConfig quotIntegralTerm "quot" SBV.sQuot
testBinaryOpLowering @(WordN 5) @(WordN 5) @(WordN 5) boundedConfig quotIntegralTerm "quot" SBV.sQuot,
testCase "Rem" $ do
testBinaryOpLowering @(WordN 5) @(WordN 5) @(WordN 5) unboundedConfig remIntegralTerm "rem" SBV.sRem
testBinaryOpLowering @(WordN 5) @(WordN 5) @(WordN 5) boundedConfig remIntegralTerm "rem" SBV.sRem
]
]