Conversation
axic
left a comment
There was a problem hiding this comment.
Since the interface selection is done as if (z3) use_z3 elseif (cvc4) use_cvc4 else use_file the cmake should be updated to reflect that.
e.g. no point displaying the warning if z3 is not found and no point checking for cvc4 if z3 is found.
|
This was done in preparation for the next step when we use both, in which case it makes sense to check for CVC4 even if Z3 is found. |
|
@axic Committed a fix. Will squash after review is finished |
|
The makefile changes look good. |
| return arguments[0]; | ||
| } | ||
|
|
||
| CVC4::Type CVC4Interface::cvc4Sort(Sort _sort) |
There was a problem hiding this comment.
Ok, noticed this follows the naming convention from Z3. I may just do a name refactoring as a separate step on all three (z3, smt, cvc4).
| return make_pair(result, values); | ||
| } | ||
|
|
||
| CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr) |
There was a problem hiding this comment.
This seems to be a lot of copy paste from Z3, not sure how this could be shared between the two, but probably at least the arity map could be?
There was a problem hiding this comment.
Perhaps we should have a validate() function on Expression which does the arity validation.
There was a problem hiding this comment.
True, that could be shared. But same case with the rest, I mean, the goal of the function is exactly to translate from Solidity's internal SMT representation to Z3/CVC4
There was a problem hiding this comment.
I was mostly wondering how could we improve this, but as part of this PR I would say the only thing to do is pull out the arity validation to the Expression class (and also check it in SMTLibInterface, which currently ignores it due to the flexible nature of S-expressions), that is a low hanging fruit.
There was a problem hiding this comment.
Probably bool valid() const is a good idea, which then can be part of an assertion (solAssert(_expr.isValid(), "") in the interfaces.
There was a problem hiding this comment.
Yep. I would also give as parameter the size of the arguments vector that the interface computed
| } | ||
| } | ||
|
|
||
| pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const& _expressionsToEvaluate) |
There was a problem hiding this comment.
This seems to be a copy of Z3's too, but not sure how it can be refactored.
There was a problem hiding this comment.
Also not sure how this could be refactored. The structure is the same, and the changes are exactly what are actually different between Z3 and CVC4: results enums, methods to get models, etc
5e573f0 to
970af2b
Compare
libsolidity/formal/SolverInterface.h
Outdated
|
|
||
| /// Checks whether this operator has a valid arity based on its name. | ||
| /// _arity is the arity of the operator in the solver. | ||
| bool isValid(unsigned _arity) const |
There was a problem hiding this comment.
Shouldn't this be only dependant on the internal state (m_arguments.size())?
There was a problem hiding this comment.
It is indirectly. Z3 and CVC4 interfaces use the _expr.arguments to build the correspondent vector of arguments. It should be the same in the end, it just checks one more thing this way
There was a problem hiding this comment.
I'm not sure if it is better this way or to have two different assertions. I think this isValid would need to be local to the Expression class.
There was a problem hiding this comment.
Makes sense. I'll make it two assertions then, to keep it safe
There was a problem hiding this comment.
Actually I don't think we need the second assertion.
|
Also needs a changelog entry. |
libsolidity/formal/CVC4Interface.cpp
Outdated
| CVC4Interface::CVC4Interface(): | ||
| m_solver(&m_context) | ||
| { | ||
| m_solver.setOption("produce-models", true); |
There was a problem hiding this comment.
Better to just call reset here?
libsolidity/formal/CVC4Interface.cpp
Outdated
| { | ||
| m_solver.assertFormula(toCVC4Expr(_expr)); | ||
| } | ||
| catch (CVC4::TypeCheckingException &) |
There was a problem hiding this comment.
No space in front of &. Also should use const&.
|
Added Changelog entry and fixed review suggestions |
2aeec85 to
f3ef945
Compare
|
We may want to change that to only validate if the name is a |
libsolidity/formal/SolverInterface.h
Outdated
| /// Checks whether this operator has a valid arity based on its name. | ||
| bool isValid() const | ||
| { | ||
| static std::map<std::string, unsigned> operatorsArity{ |
libsolidity/formal/SolverInterface.h
Outdated
| Expression& operator=(Expression const&) = default; | ||
| Expression& operator=(Expression&&) = default; | ||
|
|
||
| /// Checks whether this operator has a valid arity based on its name. |
There was a problem hiding this comment.
The comments suggests that the name of the function is not the best ;)
hasCorrectArity?
| else if (n == "*") | ||
| return m_context.mkExpr(CVC4::kind::MULT, arguments[0], arguments[1]); | ||
| else if (n == "/") | ||
| return m_context.mkExpr(CVC4::kind::INTS_DIVISION_TOTAL, arguments[0], arguments[1]); |
There was a problem hiding this comment.
I remember the rounding was weird for negative integers in z3, so I think we added a higher-level workaround for signed integers.
What happens at division by zero?
There was a problem hiding this comment.
The workaround was added in SMTChecker, right?
INTS_DIVISION_TOTAL returns 0 for division by 0.
|
@axic Good catch, SMTLib will return for constants before, but not for new functions. |
|
@chriseth OK to merge now? @leonardoalt can you rebase to ensure the changelog entry is in the right spot? |
|
Ok to merge. We are basically still in the same mode, since we need to create the bugfix release, but let's try anyway. |
|
@chriseth rebased and applied changes, please review |
| void pop() override; | ||
|
|
||
| Expression newFunction(std::string _name, Sort _domain, Sort _codomain) override; | ||
| Expression newInteger(std::string _name) override; |
There was a problem hiding this comment.
These should all use const& - don't they in the base class?
There was a problem hiding this comment.
They're also just string in the base class, where they're moved to the Expression
There was a problem hiding this comment.
Ah sorry, I didn't see the move.
Added CVC4 as an option for the SMT backend.
Z3 is still the default solver. CVC4 is only used when Z3 is not available.
The next step is writing the double solver that uses both and solves everything.