diff options
author | Leonardo Alt <leo@ethereum.org> | 2018-11-21 22:13:50 +0800 |
---|---|---|
committer | Leonardo Alt <leo@ethereum.org> | 2018-11-21 22:46:47 +0800 |
commit | 01ce43e51ba8ced7f2e53f5e9f9e0ea6b718df64 (patch) | |
tree | b84619e480c5f88cc1f3c57b8b738845e32093d8 /libsolidity/formal/SolverInterface.h | |
parent | d3f66ca0fab130e801b012bd192e1e8e97fb3761 (diff) | |
download | dexon-solidity-01ce43e51ba8ced7f2e53f5e9f9e0ea6b718df64.tar.gz dexon-solidity-01ce43e51ba8ced7f2e53f5e9f9e0ea6b718df64.tar.zst dexon-solidity-01ce43e51ba8ced7f2e53f5e9f9e0ea6b718df64.zip |
[SMTChecker] Refactor smt::Sort and its usage
Diffstat (limited to 'libsolidity/formal/SolverInterface.h')
-rw-r--r-- | libsolidity/formal/SolverInterface.h | 108 |
1 files changed, 48 insertions, 60 deletions
diff --git a/libsolidity/formal/SolverInterface.h b/libsolidity/formal/SolverInterface.h index a6618fb5..55c0a563 100644 --- a/libsolidity/formal/SolverInterface.h +++ b/libsolidity/formal/SolverInterface.h @@ -42,21 +42,32 @@ enum class CheckResult SATISFIABLE, UNSATISFIABLE, UNKNOWN, CONFLICTING, ERROR }; -enum class Sort +enum class Kind { Int, Bool }; +struct Sort +{ + Sort(Kind _kind): + kind(_kind) {} + virtual ~Sort() = default; + Kind const kind; + bool operator==(Sort const& _other) const { return kind == _other.kind; } +}; +using SortPointer = std::shared_ptr<Sort>; + + /// C++ representation of an SMTLIB2 expression. class Expression { friend class SolverInterface; public: - explicit Expression(bool _v): name(_v ? "true" : "false"), sort(Sort::Bool) {} - Expression(size_t _number): name(std::to_string(_number)), sort(Sort::Int) {} - Expression(u256 const& _number): name(_number.str()), sort(Sort::Int) {} - Expression(bigint const& _number): name(_number.str()), sort(Sort::Int) {} + explicit Expression(bool _v): Expression(_v ? "true" : "false", Kind::Bool) {} + Expression(size_t _number): Expression(std::to_string(_number), Kind::Int) {} + Expression(u256 const& _number): Expression(_number.str(), Kind::Int) {} + Expression(bigint const& _number): Expression(_number.str(), Kind::Int) {} Expression(Expression const&) = default; Expression(Expression&&) = default; @@ -85,7 +96,7 @@ public: static Expression ite(Expression _condition, Expression _trueValue, Expression _falseValue) { - solAssert(_trueValue.sort == _falseValue.sort, ""); + solAssert(*_trueValue.sort == *_falseValue.sort, ""); return Expression("ite", std::vector<Expression>{ std::move(_condition), std::move(_trueValue), std::move(_falseValue) }, _trueValue.sort); @@ -98,19 +109,19 @@ public: friend Expression operator!(Expression _a) { - return Expression("not", std::move(_a), Sort::Bool); + return Expression("not", std::move(_a), Kind::Bool); } friend Expression operator&&(Expression _a, Expression _b) { - return Expression("and", std::move(_a), std::move(_b), Sort::Bool); + return Expression("and", std::move(_a), std::move(_b), Kind::Bool); } friend Expression operator||(Expression _a, Expression _b) { - return Expression("or", std::move(_a), std::move(_b), Sort::Bool); + return Expression("or", std::move(_a), std::move(_b), Kind::Bool); } friend Expression operator==(Expression _a, Expression _b) { - return Expression("=", std::move(_a), std::move(_b), Sort::Bool); + return Expression("=", std::move(_a), std::move(_b), Kind::Bool); } friend Expression operator!=(Expression _a, Expression _b) { @@ -118,35 +129,35 @@ public: } friend Expression operator<(Expression _a, Expression _b) { - return Expression("<", std::move(_a), std::move(_b), Sort::Bool); + return Expression("<", std::move(_a), std::move(_b), Kind::Bool); } friend Expression operator<=(Expression _a, Expression _b) { - return Expression("<=", std::move(_a), std::move(_b), Sort::Bool); + return Expression("<=", std::move(_a), std::move(_b), Kind::Bool); } friend Expression operator>(Expression _a, Expression _b) { - return Expression(">", std::move(_a), std::move(_b), Sort::Bool); + return Expression(">", std::move(_a), std::move(_b), Kind::Bool); } friend Expression operator>=(Expression _a, Expression _b) { - return Expression(">=", std::move(_a), std::move(_b), Sort::Bool); + return Expression(">=", std::move(_a), std::move(_b), Kind::Bool); } friend Expression operator+(Expression _a, Expression _b) { - return Expression("+", std::move(_a), std::move(_b), Sort::Int); + return Expression("+", std::move(_a), std::move(_b), Kind::Int); } friend Expression operator-(Expression _a, Expression _b) { - return Expression("-", std::move(_a), std::move(_b), Sort::Int); + return Expression("-", std::move(_a), std::move(_b), Kind::Int); } friend Expression operator*(Expression _a, Expression _b) { - return Expression("*", std::move(_a), std::move(_b), Sort::Int); + return Expression("*", std::move(_a), std::move(_b), Kind::Int); } friend Expression operator/(Expression _a, Expression _b) { - return Expression("/", std::move(_a), std::move(_b), Sort::Int); + return Expression("/", std::move(_a), std::move(_b), Kind::Int); } Expression operator()(std::vector<Expression> _arguments) const { @@ -154,36 +165,26 @@ public: arguments.empty(), "Attempted function application to non-function." ); - switch (sort) - { - case Sort::Int: - return Expression(name, std::move(_arguments), Sort::Int); - case Sort::Bool: - return Expression(name, std::move(_arguments), Sort::Bool); - default: - solAssert( - false, - "Attempted function application to invalid type." - ); - break; - } + return Expression(name, std::move(_arguments), sort); } std::string name; std::vector<Expression> arguments; - Sort sort; + SortPointer sort; private: - /// Manual constructor, should only be used by SolverInterface and this class itself. - Expression(std::string _name, std::vector<Expression> _arguments, Sort _sort): - name(std::move(_name)), arguments(std::move(_arguments)), sort(_sort) {} - - explicit Expression(std::string _name, Sort _sort): - Expression(std::move(_name), std::vector<Expression>{}, _sort) {} - Expression(std::string _name, Expression _arg, Sort _sort): - Expression(std::move(_name), std::vector<Expression>{std::move(_arg)}, _sort) {} - Expression(std::string _name, Expression _arg1, Expression _arg2, Sort _sort): - Expression(std::move(_name), std::vector<Expression>{std::move(_arg1), std::move(_arg2)}, _sort) {} + /// Manual constructors, should only be used by SolverInterface and this class itself. + Expression(std::string _name, std::vector<Expression> _arguments, SortPointer _sort): + name(std::move(_name)), arguments(std::move(_arguments)), sort(std::move(_sort)) {} + Expression(std::string _name, std::vector<Expression> _arguments, Kind _kind): + Expression(std::move(_name), std::move(_arguments), std::make_shared<Sort>(_kind)) {} + + explicit Expression(std::string _name, Kind _kind): + Expression(std::move(_name), std::vector<Expression>{}, _kind) {} + Expression(std::string _name, Expression _arg, Kind _kind): + Expression(std::move(_name), std::vector<Expression>{std::move(_arg)}, _kind) {} + Expression(std::string _name, Expression _arg1, Expression _arg2, Kind _kind): + Expression(std::move(_name), std::vector<Expression>{std::move(_arg1), std::move(_arg2)}, _kind) {} }; DEV_SIMPLE_EXCEPTION(SolverError); @@ -197,39 +198,26 @@ public: virtual void push() = 0; virtual void pop() = 0; - virtual void declareFunction(std::string _name, std::vector<Sort> const& _domain, Sort _codomain) = 0; - void declareFunction(std::string _name, Sort _domain, Sort _codomain) - { - declareFunction(std::move(_name), std::vector<Sort>{std::move(_domain)}, std::move(_codomain)); - } - Expression newFunction(std::string _name, std::vector<Sort> const& _domain, Sort _codomain) + virtual void declareFunction(std::string _name, std::vector<SortPointer> const& _domain, Sort const& _codomain) = 0; + Expression newFunction(std::string _name, std::vector<SortPointer> const& _domain, Sort const& _codomain) { declareFunction(_name, _domain, _codomain); // Subclasses should do something here - switch (_codomain) - { - case Sort::Int: - return Expression(std::move(_name), {}, Sort::Int); - case Sort::Bool: - return Expression(std::move(_name), {}, Sort::Bool); - default: - solAssert(false, "Function sort not supported."); - break; - } + return Expression(std::move(_name), {}, _codomain.kind); } virtual void declareInteger(std::string _name) = 0; Expression newInteger(std::string _name) { // Subclasses should do something here declareInteger(_name); - return Expression(std::move(_name), {}, Sort::Int); + return Expression(std::move(_name), {}, Kind::Int); } virtual void declareBool(std::string _name) = 0; Expression newBool(std::string _name) { // Subclasses should do something here declareBool(_name); - return Expression(std::move(_name), {}, Sort::Bool); + return Expression(std::move(_name), {}, Kind::Bool); } virtual void addAssertion(Expression const& _expr) = 0; |