Skip to content

Commit b49f187

Browse files
committed
saw-core: Fix handling of atWithDefault for infinite bit sequences
When calling `atWithDefault n d v i`, `d` should be returned if `i` is less than `n`. `atWithDefault` is implemented as a primitive, so we must ensure that this is done in `saw-core`'s `atWithDefaultOp` function. While `atWithDefaultOp` was handling this correctly for generic infinite sequences, it was _not_ correctly handling the special case of infinite bit sequences. This led to the issues reported in #1768. This patch fixes #1768 by introducing a `bpBvAtWithDefault` combinator that implements the defaulting behavior above in terms of `bpBvAt`. I've added a test case to demonstrate that the test case from #1768 now works as expected.
1 parent 200d0e5 commit b49f187

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

intTests/test1768/test.cry

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
f : [2] -> [10]
2+
f x = take y
3+
where
4+
y = x # y

intTests/test1768/test.saw

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import "test.cry";
2+
print {{ f 0b11 }};
3+
print {{ f 0b10 }};
4+
print {{ f 0b00 }};
5+
sat z3 {{ \x -> f x == zero }};

intTests/test1768/test.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
set -e
2+
3+
$SAW test.saw

saw-core/src/Verifier/SAW/Simulator/Prims.hs

+18-2
Original file line numberDiff line numberDiff line change
@@ -769,21 +769,37 @@ atWithDefaultOp bp =
769769
VNat i ->
770770
case x of
771771
VVector xv -> lift (force (vecIdx d xv (fromIntegral i))) -- FIXME dangerous fromIntegral
772-
VWord xw -> lift (VBool <$> bpBvAt bp xw (fromIntegral i)) -- FIXME dangerous fromIntegral
772+
VWord xw -> lift (bpBvAtWithDefault bp (fromIntegral n) (force d) xw (fromIntegral i)) -- FIXME dangerous fromIntegral
773773
_ -> throwE "atOp: expected vector"
774774
VBVToNat _sz i | bpIsSymbolicEvaluator bp -> do
775775
iv <- lift (toBits (bpUnpack bp) i)
776776
case x of
777777
VVector xv ->
778778
lift $ selectV (lazyMuxValue bp tp) (fromIntegral n - 1) (force . vecIdx d xv) iv -- FIXME dangerous fromIntegral
779779
VWord xw ->
780-
lift $ selectV (lazyMuxValue bp tp) (fromIntegral n - 1) (liftM VBool . bpBvAt bp xw) iv -- FIXME dangerous fromIntegral
780+
lift $ selectV (lazyMuxValue bp tp) (fromIntegral n - 1) (bpBvAtWithDefault bp (fromIntegral n) (force d) xw) iv -- FIXME dangerous fromIntegral
781781
_ -> throwE "atOp: expected vector"
782782

783783
VIntToNat _i | bpIsSymbolicEvaluator bp -> panic "atWithDefault: symbolic integer TODO"
784784

785785
_ -> throwE $ "atOp: expected Nat, got " <> Text.pack (show idx)
786786

787+
-- | @bpBvAtWithDefault bp w d vw i@ returns @bpBvAt bp vw i@ if @i@ is less
788+
-- than @w@ (the bit width of @vw@). Otherwise, it returns @d@.
789+
bpBvAtWithDefault ::
790+
VMonad l =>
791+
BasePrims l ->
792+
Int ->
793+
MValue l ->
794+
VWord l ->
795+
Int ->
796+
MValue l
797+
bpBvAtWithDefault bp w d vw i
798+
| i < w
799+
= VBool <$> bpBvAt bp vw i
800+
| otherwise
801+
= d
802+
787803
-- upd :: (n :: Nat) -> (a :: sort 0) -> Vec n a -> Nat -> a -> Vec n a;
788804
updOp :: (VMonadLazy l, Show (Extra l)) => BasePrims l -> Prim l
789805
updOp bp =

0 commit comments

Comments
 (0)