-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Abstract values are not preserved by certain calls to bvAdd
#248
Comments
My guess is that the problem here is that the abstract value is stored on the |
Indeed, this diff fixes this particular test case. We should think about how to more carefully preserve abstract values for the rest of diff --git a/what4/src/What4/Expr/Builder.hs b/what4/src/What4/Expr/Builder.hs
index 258562c9..827d7071 100644
--- a/what4/src/What4/Expr/Builder.hs
+++ b/what4/src/What4/Expr/Builder.hs
@@ -576,9 +576,17 @@ semiRingLit sb sr x = do
sbMakeExpr :: ExprBuilder t st fs -> App (Expr t) tp -> IO (Expr t tp)
sbMakeExpr sym a = do
+ let v = abstractEval exprAbsValue a
+ sbMakeExprWithAbs sym a v
+
+sbMakeExprWithAbs ::
+ ExprBuilder t st fs ->
+ App (Expr t) tp ->
+ AbstractValue tp ->
+ IO (Expr t tp)
+sbMakeExprWithAbs sym a v = do
s <- readIORef (sbCurAllocator sym)
pc <- curProgramLoc sym
- let v = abstractEval exprAbsValue a
when (isNonLinearApp a) $
atomicModifyIORef' (sbNonLinearOps sym) (\n -> (n+1,()))
case appType a of
@@ -1226,6 +1234,14 @@ sum' ::
sum' sym s = sbMakeExpr sym $ SemiRingSum s
{-# INLINE sum' #-}
+sumWithAbs ::
+ ExprBuilder t st fs ->
+ WeightedSum (Expr t) sr ->
+ AbstractValue (SR.SemiRingBase sr) ->
+ IO (Expr t (SR.SemiRingBase sr))
+sumWithAbs sym s = sbMakeExprWithAbs sym $ SemiRingSum s
+{-# INLINE sumWithAbs #-}
+
scalarMul ::
ExprBuilder t st fs ->
SR.SemiRingRepr sr ->
@@ -1399,7 +1415,9 @@ semiRingAdd sym sr x y =
(SR_Constant xc, SR_Sum ys) ->
sum' sym (WSum.addConstant sr ys xc)
(SR_Sum xs, SR_Constant yc) ->
- sum' sym (WSum.addConstant sr xs yc)
+ case abs of
+ Just a -> sumWithAbs sym (WSum.addConstant sr xs yc) a
+ Nothing -> sum' sym (WSum.addConstant sr xs yc)
(SR_Constant xc, _)
| Just (BaseIte _ _ cond a b) <- asApp y
@@ -1427,6 +1445,15 @@ semiRingAdd sym sr x y =
isConstantSemiRingExpr (viewSemiRing sr -> SR_Constant _) = True
isConstantSemiRingExpr _ = False
+ absx = getAbsValue x
+ absy = getAbsValue y
+ abs :: Maybe (AbstractValue (SR.SemiRingBase sr))
+ abs =
+ case sr of
+ SR.SemiRingIntegerRepr -> Nothing
+ SR.SemiRingRealRepr -> Nothing
+ SR.SemiRingBVRepr fv w -> Just $ BVD.add absx absy
+
semiRingMul ::
ExprBuilder t st fs ->
SR.SemiRingRepr sr -> |
Good catch. My experience with abstract domains is that they are somewhat fragile for reasons like this, and one usually needs to annotate an expression if you want to have any reasonable guarantees that the abstract domain will be preserved. (See also #40, which is about a proposed refactoring to make issues like this one easier to spot.) Of course, we should strive to do better, and if there are simple ways to improve things, we should do it. We have a long way to go in order to cover every |
This test fails, when it should succeed:
There's something wrong with this case in
semiRingAdd
:what4/what4/src/What4/Expr/Builder.hs
Line 1401 in e46dff4
Note that this doesn't occur if you assign abstract values individually to
x2A
andx2B
.The text was updated successfully, but these errors were encountered: