mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add option to choose solver
This commit is contained in:
@@ -40,7 +40,8 @@ SMTPortfolio::SMTPortfolio(
|
||||
):
|
||||
SolverInterface(_queryTimeout)
|
||||
{
|
||||
m_solvers.emplace_back(make_unique<SMTLib2Interface>(move(_smtlib2Responses), move(_smtCallback), m_queryTimeout));
|
||||
if (_enabledSolvers.smtlib2)
|
||||
m_solvers.emplace_back(make_unique<SMTLib2Interface>(move(_smtlib2Responses), move(_smtCallback), m_queryTimeout));
|
||||
#ifdef HAVE_Z3
|
||||
if (_enabledSolvers.z3 && Z3Interface::available())
|
||||
m_solvers.emplace_back(make_unique<Z3Interface>(m_queryTimeout));
|
||||
@@ -143,10 +144,11 @@ pair<CheckResult, vector<string>> SMTPortfolio::check(vector<Expression> const&
|
||||
vector<string> SMTPortfolio::unhandledQueries()
|
||||
{
|
||||
// This code assumes that the constructor guarantees that
|
||||
// SmtLib2Interface is in position 0.
|
||||
smtAssert(!m_solvers.empty(), "");
|
||||
smtAssert(dynamic_cast<SMTLib2Interface*>(m_solvers.front().get()), "");
|
||||
return m_solvers.front()->unhandledQueries();
|
||||
// SmtLib2Interface is in position 0, if enabled.
|
||||
if (!m_solvers.empty())
|
||||
if (auto smtlib2 = dynamic_cast<SMTLib2Interface*>(m_solvers.front().get()))
|
||||
return smtlib2->unhandledQueries();
|
||||
return {};
|
||||
}
|
||||
|
||||
bool SMTPortfolio::solverAnswered(CheckResult result)
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
|
||||
#include <libsolutil/Common.h>
|
||||
|
||||
#include <range/v3/view.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -36,16 +39,71 @@ namespace solidity::smtutil
|
||||
struct SMTSolverChoice
|
||||
{
|
||||
bool cvc4 = false;
|
||||
bool smtlib2 = false;
|
||||
bool z3 = false;
|
||||
|
||||
static constexpr SMTSolverChoice All() { return {true, true}; }
|
||||
static constexpr SMTSolverChoice CVC4() { return {true, false}; }
|
||||
static constexpr SMTSolverChoice Z3() { return {false, true}; }
|
||||
static constexpr SMTSolverChoice None() { return {false, false}; }
|
||||
static constexpr SMTSolverChoice All() { return {true, true, true}; }
|
||||
static constexpr SMTSolverChoice CVC4() { return {true, false, false}; }
|
||||
static constexpr SMTSolverChoice SMTLIB2() { return {false, true, false}; }
|
||||
static constexpr SMTSolverChoice Z3() { return {false, false, true}; }
|
||||
static constexpr SMTSolverChoice None() { return {false, false, false}; }
|
||||
|
||||
static std::optional<SMTSolverChoice> fromString(std::string const& _solvers)
|
||||
{
|
||||
SMTSolverChoice solvers;
|
||||
if (_solvers == "all")
|
||||
{
|
||||
smtAssert(solvers.setSolver("cvc4"), "");
|
||||
smtAssert(solvers.setSolver("smtlib2"), "");
|
||||
smtAssert(solvers.setSolver("z3"), "");
|
||||
}
|
||||
else
|
||||
for (auto&& s: _solvers | ranges::views::split(',') | ranges::to<std::vector<std::string>>())
|
||||
if (!solvers.setSolver(s))
|
||||
return {};
|
||||
|
||||
return solvers;
|
||||
}
|
||||
|
||||
SMTSolverChoice& operator&(SMTSolverChoice const& _other)
|
||||
{
|
||||
cvc4 &= _other.cvc4;
|
||||
smtlib2 &= _other.smtlib2;
|
||||
z3 &= _other.z3;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SMTSolverChoice& operator&=(SMTSolverChoice const& _other)
|
||||
{
|
||||
return *this & _other;
|
||||
}
|
||||
|
||||
bool operator!=(SMTSolverChoice const& _other) const noexcept { return !(*this == _other); }
|
||||
|
||||
bool operator==(SMTSolverChoice const& _other) const noexcept
|
||||
{
|
||||
return cvc4 == _other.cvc4 &&
|
||||
smtlib2 == _other.smtlib2 &&
|
||||
z3 == _other.z3;
|
||||
}
|
||||
|
||||
bool setSolver(std::string const& _solver)
|
||||
{
|
||||
static std::set<std::string> const solvers{"cvc4", "smtlib2", "z3"};
|
||||
if (!solvers.count(_solver))
|
||||
return false;
|
||||
if (_solver == "cvc4")
|
||||
cvc4 = true;
|
||||
else if (_solver == "smtlib2")
|
||||
smtlib2 = true;
|
||||
else if (_solver == "z3")
|
||||
z3 = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool none() { return !some(); }
|
||||
bool some() { return cvc4 || z3; }
|
||||
bool all() { return cvc4 && z3; }
|
||||
bool some() { return cvc4 || smtlib2 || z3; }
|
||||
bool all() { return cvc4 && smtlib2 && z3; }
|
||||
};
|
||||
|
||||
enum class CheckResult
|
||||
|
||||
Reference in New Issue
Block a user