Skip to content
This repository has been archived by the owner on Jun 9, 2021. It is now read-only.

Improved support for IntMod type in symbolic backends #93

Merged
merged 12 commits into from
Nov 3, 2020
4 changes: 3 additions & 1 deletion cryptol-saw-core/src/Verifier/SAW/Cryptol.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,7 @@ asCryptolTypeValue v =
case v of
SC.VBoolType -> return C.tBit
SC.VIntType -> return C.tInteger
SC.VIntModType n -> return (C.tIntMod (C.tNum n))
SC.VArrayType v1 v2 -> do
t1 <- asCryptolTypeValue v1
t2 <- asCryptolTypeValue v2
Expand Down Expand Up @@ -1461,7 +1462,7 @@ exportValue ty v = case ty of
V.VInteger (case v of SC.VInt x -> x; _ -> error "exportValue: expected integer")

TV.TVIntMod _modulus ->
V.VInteger (case v of SC.VInt x -> x; _ -> error "exportValue: expected integer")
V.VInteger (case v of SC.VIntMod _ x -> x; _ -> error "exportValue: expected intmod")

TV.TVArray{} -> error $ "exportValue: (on array type " ++ show ty ++ ")"

Expand Down Expand Up @@ -1533,6 +1534,7 @@ exportFirstOrderValue fv =
case fv of
FOVBit b -> V.VBit b
FOVInt i -> V.VInteger i
FOVIntMod _ i -> V.VInteger i
FOVWord w x -> V.word V.Concrete (toInteger w) x
FOVVec t vs
| t == FOTBit -> V.VWord len (V.ready (V.LargeBitsVal len (V.finiteSeqMap V.Concrete . map (V.ready . V.VBit . fvAsBool) $ vs)))
Expand Down
1 change: 1 addition & 0 deletions cryptol-saw-core/src/Verifier/SAW/TypedTerm.hs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ cryptolTypeOfFirstOrderType fot =
case fot of
FOTBit -> C.tBit
FOTInt -> C.tInteger
FOTIntMod n -> C.tIntMod (C.tNum n)
FOTVec n t -> C.tSeq (C.tNum n) (cryptolTypeOfFirstOrderType t)
FOTTuple ts -> C.tTuple (map cryptolTypeOfFirstOrderType ts)
FOTArray a b ->
Expand Down
25 changes: 15 additions & 10 deletions saw-core-aig/src/Verifier/SAW/Simulator/BitBlast.hs
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,8 @@ beConstMap be =
, ("Prelude.bvToInt" , bvToIntOp be)
, ("Prelude.sbvToInt", sbvToIntOp be)
-- Integers mod n
, ("Prelude.IntMod" , constFun (TValue VIntType))
, ("Prelude.toIntMod" , toIntModOp)
, ("Prelude.fromIntMod", constFun (VFun force))
, ("Prelude.fromIntMod", fromIntModOp)
, ("Prelude.intModEq" , intModEqOp be)
, ("Prelude.intModAdd" , intModBinOp (+))
, ("Prelude.intModSub" , intModBinOp (-))
Expand Down Expand Up @@ -353,27 +352,33 @@ toIntModOp :: BValue l
toIntModOp =
Prims.natFun $ \n -> return $
Prims.intFun "toIntModOp" $ \x -> return $
VInt (x `mod` toInteger n)
VIntMod n (x `mod` toInteger n)

fromIntModOp :: BValue l
fromIntModOp =
constFun $
Prims.intModFun "fromIntModOp" $ \x -> return $
VInt x

intModEqOp :: AIG.IsAIG l g => g s -> BValue (l s)
intModEqOp be =
constFun $
Prims.intFun "intModEqOp" $ \x -> return $
Prims.intFun "intModEqOp" $ \y -> return $
Prims.intModFun "intModEqOp" $ \x -> return $
Prims.intModFun "intModEqOp" $ \y -> return $
VBool (AIG.constant be (x == y))

intModBinOp :: (Integer -> Integer -> Integer) -> BValue l
intModBinOp f =
Prims.natFun $ \n -> return $
Prims.intFun "intModBinOp x" $ \x -> return $
Prims.intFun "intModBinOp y" $ \y -> return $
VInt (f x y `mod` toInteger n)
Prims.intModFun "intModBinOp x" $ \x -> return $
Prims.intModFun "intModBinOp y" $ \y -> return $
VIntMod n (f x y `mod` toInteger n)

intModUnOp :: (Integer -> Integer) -> BValue l
intModUnOp f =
Prims.natFun $ \n -> return $
Prims.intFun "intModUnOp" $ \x -> return $
VInt (f x `mod` toInteger n)
Prims.intModFun "intModUnOp" $ \x -> return $
VIntMod n (f x `mod` toInteger n)

----------------------------------------

Expand Down
30 changes: 22 additions & 8 deletions saw-core-sbv/src/Verifier/SAW/Simulator/SBV.hs
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,7 @@ constMap =
, ("Prelude.bvToInt" , bvToIntOp)
, ("Prelude.sbvToInt", sbvToIntOp)
-- Integers mod n
, ("Prelude.IntMod" , constFun (TValue VIntType))
, ("Prelude.toIntMod" , constFun (VFun force))
, ("Prelude.toIntMod" , toIntModOp)
, ("Prelude.fromIntMod", fromIntModOp)
, ("Prelude.intModEq" , intModEqOp)
, ("Prelude.intModAdd" , intModBinOp svPlus)
Expand Down Expand Up @@ -262,6 +261,8 @@ flattenSValue v = do
return (concat xss, concat ss)
VBool sb -> return ([sb], "")
VInt si -> return ([si], "")
VIntMod 0 si -> return ([si], "")
VIntMod n si -> return ([svRem si (svInteger KUnbounded (toInteger n))], "")
VWord sw -> return (if intSizeOf sw > 0 then [sw] else [], "")
VCtorApp i (V.toList->ts) -> do (xss, ss) <- unzip <$> traverse (force >=> flattenSValue) ts
return (concat xss, "_" ++ identName i ++ concat ss)
Expand Down Expand Up @@ -434,6 +435,12 @@ svShiftR b x i = svIte b (svNot (svShiftRight (svNot x) i)) (svShiftRight x i)
------------------------------------------------------------
-- Integers mod n

toIntModOp :: SValue
toIntModOp =
Prims.natFun' "toIntMod" $ \n -> pure $
Prims.intFun "toIntMod" $ \x -> pure $
VIntMod n x

fromIntModOp :: SValue
fromIntModOp =
Prims.natFun $ \n -> return $
Expand All @@ -443,23 +450,23 @@ fromIntModOp =
intModEqOp :: SValue
intModEqOp =
Prims.natFun $ \n -> return $
Prims.intFun "intModEqOp" $ \x -> return $
Prims.intFun "intModEqOp" $ \y -> return $
Prims.intModFun "intModEqOp" $ \x -> return $
Prims.intModFun "intModEqOp" $ \y -> return $
let modulus = literalSInteger (toInteger n)
in VBool (svEqual (svRem (svMinus x y) modulus) (literalSInteger 0))

intModBinOp :: (SInteger -> SInteger -> SInteger) -> SValue
intModBinOp f =
Prims.natFun $ \n -> return $
Prims.intFun "intModBinOp x" $ \x -> return $
Prims.intFun "intModBinOp y" $ \y -> return $
VInt (normalizeIntMod n (f x y))
Prims.intModFun "intModBinOp x" $ \x -> return $
Prims.intModFun "intModBinOp y" $ \y -> return $
VIntMod n (normalizeIntMod n (f x y))

intModUnOp :: (SInteger -> SInteger) -> SValue
intModUnOp f =
Prims.natFun $ \n -> return $
Prims.intFun "intModUnOp" $ \x -> return $
VInt (normalizeIntMod n (f x))
VIntMod n (normalizeIntMod n (f x))

normalizeIntMod :: Natural -> SInteger -> SInteger
normalizeIntMod n x =
Expand Down Expand Up @@ -584,6 +591,9 @@ parseUninterpreted cws nm ty =
VIntType
-> return $ vInteger $ mkUninterpreted KUnbounded cws nm

VIntModType n
-> return $ VIntMod n $ mkUninterpreted KUnbounded cws nm

(VVecType n VBoolType)
-> return $ vWord $ mkUninterpreted (KBounded False (fromIntegral n)) cws nm

Expand Down Expand Up @@ -630,6 +640,8 @@ vAsFirstOrderType v =
-> return FOTBit
VIntType
-> return FOTInt
VIntModType n
-> return (FOTIntMod n)
VVecType n v2
-> FOTVec n <$> vAsFirstOrderType v2
VUnitType
Expand Down Expand Up @@ -701,6 +713,7 @@ newVarsForType v nm =
newVars :: FirstOrderType -> StateT Int IO (Labeler, Symbolic SValue)
newVars FOTBit = nextId <&> \s-> (BoolLabel s, vBool <$> existsSBool s)
newVars FOTInt = nextId <&> \s-> (IntegerLabel s, vInteger <$> existsSInteger s)
newVars (FOTIntMod n) = nextId <&> \s-> (IntegerLabel s, VIntMod n <$> existsSInteger s)
robdockins marked this conversation as resolved.
Show resolved Hide resolved
newVars (FOTVec n FOTBit) =
if n == 0
then nextId <&> \s-> (WordLabel s, return (vWord (literalSWord 0 0)))
Expand All @@ -722,6 +735,7 @@ newVars (FOTRec tm) = do
newCodeGenVars :: (Natural -> Bool) -> FirstOrderType -> StateT Int IO (SBVCodeGen SValue)
newCodeGenVars _checkSz FOTBit = nextId <&> \s -> (vBool <$> svCgInput KBool s)
newCodeGenVars _checkSz FOTInt = nextId <&> \s -> (vInteger <$> svCgInput KUnbounded s)
newCodeGenVars _checkSz (FOTIntMod _) = nextId <&> \s -> (vInteger <$> svCgInput KUnbounded s)
robdockins marked this conversation as resolved.
Show resolved Hide resolved
newCodeGenVars checkSz (FOTVec n FOTBit)
| n == 0 = nextId <&> \_ -> return (vWord (literalSWord 0 0))
| checkSz n = nextId <&> \s -> vWord <$> cgInputSWord s (fromIntegral n)
Expand Down
Loading