-
Notifications
You must be signed in to change notification settings - Fork 273
SMT cache values and handle z3 errors #6215
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
SMT cache values and handle z3 errors #6215
Conversation
b51b88d
to
b34eb03
Compare
Codecov Report
@@ Coverage Diff @@
## develop #6215 +/- ##
===========================================
+ Coverage 75.12% 75.20% +0.07%
===========================================
Files 1458 1458
Lines 161402 161431 +29
===========================================
+ Hits 121261 121408 +147
+ Misses 40141 40023 -118
Continue to review full report at Codecov.
|
b34eb03
to
96898d4
Compare
@peterschrammel @tautschnig I would appreciate codeowner review (and ideally approved) here. I've tried to explain in the PR why this is done this way and what problem it solves. I'm also aware of critique regarding handling specific |
src/solvers/smt2/smt2_dec.cpp
Outdated
} | ||
} | ||
} | ||
|
||
// If the result is satisfiable don't bother updating the assignments and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be is NOT satisfiable
?
This was previously unimplemented, which put null expressions into the trace steps and resulted in the elements of arrays not being printed when the trace is printed.
96898d4
to
76c8183
Compare
This is a fix for how we parse Z3 array output to reconstruct values in traces. This is specific bug fix for Z3 array output.
This removes the labels on some tests that used to have the broken-smt-backend flag but now pass.
Add two regression tests to check for array output in traces.
Due to how we call z3 it is possible to have values that contain quantifiers appear in the results. However, z3 cannot give a real value in response to a "(get-value |XXX|)" request. This catches these any simply ignores them, allowing the rest of the code to continue. Note that this becomes necessary to handle since cbmc now produces quantifiers in expressions sent to z3.
This fixes some of the cases where `z3` returns an error instead of a value for some of the values cbmc is attempting to get.
76c8183
to
e66aa29
Compare
Add a new regression test for error handling for z3 output that came from a Issue diffblue#5970
These various tests are either broken with error or timeout on SMT backends, in particular cprover-smt or z3. # Please enter the commit message for your changes. Lines starting
@@ -283,6 +283,7 @@ exprt smt2_convt::get(const exprt &expr) const | |||
|
|||
if(it!=identifier_map.end()) | |||
return it->second.value; | |||
return expr; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's wrong for get
to return the symbol that it's asked to provide a model for.
The API is meant to return nil
when no value is available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears to have been caught from another PR/merging problem with git (and is already merged in #6210 ). That said, this fixes missing symbols in arrays when printing traces from SMT solvers.
This is a horrible hack to work around a bug in Z3. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate that "maybe do something else" is not a particularly helpful review comment but some general thoughts:
- In SMT-LIB 2.* there is little standarization of the representation of models and values. For simple variables it is simple but for things like arrays and quantifiers it rapidly gets less obvious.
- This may change in SMT-LIB 3.0. One of the reasons for adding things like lambdas to the language is to help create a way of outputting arrays and quantifiers.
- As such the output is quite solver-specific.
(get-model)
is a generally preferred interface than(get-value)
.
So, maybe the correct way to handle this is to call (get-model)
and then do a solver-specific parsing of what you get?
@@ -1,4 +1,4 @@ | |||
CORE | |||
CORE broken-z3-smt-backend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this break?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These appear to have been broken before, previous version of cbmc
have errors here.
Broadly I agree on the points raised by both @kroening and @martin-cs , the ideal would be to do something better and not have this hack. However, the main concern here (and hence my raising this PR with the above comments/discussion) is that we are already sending "bad" input to |
This PR contains a fix for problems due to
cbmc
being able to send expressions with quantifiers toz3
. This creates a problem where asat
result can be followed by an attempt to(get-value |XXX|)
for various identifiersXXX
. However, whenz3
has a quantifier in one of these identifiers this raises an error.This PR addresses this problem by doing three things:
(assert |XXX|)
via theset_to
function that is in turn referring to something indefined_expressions
, then we also store what value we set this identifier to inset_values
. (This covers various expressions, but most importantly here quantifier questions whichz3
will fail to handle with(get-value |XXX|)
.)z3
has determined the result issat
, then we ignore this error. This would lead to us missing results from the(get-value ...)
expressions except forsat
because we stored it in theset_values
in 1 (above), then use this instead of parsing and checking the result from the solver. This also solves the problem withz3
not being able to return the result and it being skipped in 2 (above).