[SMTChecker]: Update CVC4 to cvc5

This commit is contained in:
Martin Blicha 2023-05-29 18:05:11 +02:00
parent facc38097d
commit 43f7a0f1cb
20 changed files with 210 additions and 240 deletions

View File

@ -122,15 +122,15 @@ elseif (${Z3_FOUND})
message("Z3 SMT solver found. This enables optional SMT checking with Z3.") message("Z3 SMT solver found. This enables optional SMT checking with Z3.")
endif() endif()
find_package(CVC4 QUIET) find_package(CVC5 QUIET)
if (${CVC4_FOUND}) if (${CVC5_FOUND})
add_definitions(-DHAVE_CVC4) add_definitions(-DHAVE_CVC5)
message("CVC4 SMT solver found. This enables optional SMT checking with CVC4.") message("cvc5 SMT solver found. This enables optional SMT checking with cvc5.")
endif() endif()
if (NOT (${Z3_FOUND} OR ${CVC4_FOUND})) if (NOT (${Z3_FOUND} OR ${CVC5_FOUND}))
message("No SMT solver found (or it has been forcefully disabled). Optional SMT checking will not be available.\ message("No SMT solver found (or it has been forcefully disabled). Optional SMT checking will not be available.\
\nPlease install Z3 or CVC4 or remove the option disabling them (USE_Z3, USE_CVC4).") \nPlease install Z3 or cvc5 or remove the option disabling them (USE_Z3, USE_CVC5).")
endif() endif()
add_subdirectory(libsolutil) add_subdirectory(libsolutil)

View File

@ -266,7 +266,7 @@ option(USE_Z3 "Allow compiling with Z3 SMT solver integration" ON)
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
option(USE_Z3_DLOPEN "Dynamically load the Z3 SMT solver instead of linking against it." OFF) option(USE_Z3_DLOPEN "Dynamically load the Z3 SMT solver instead of linking against it." OFF)
endif() endif()
option(USE_CVC4 "Allow compiling with CVC4 SMT solver integration" ON) option(USE_CVC5 "Allow compiling with CVC5 SMT solver integration" ON)
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
option(USE_LD_GOLD "Use GNU gold linker" ON) option(USE_LD_GOLD "Use GNU gold linker" ON)

View File

@ -1,33 +0,0 @@
if (USE_CVC4)
find_path(CVC4_INCLUDE_DIR cvc4/cvc4.h)
find_library(CVC4_LIBRARY NAMES cvc4)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CVC4 DEFAULT_MSG CVC4_LIBRARY CVC4_INCLUDE_DIR)
if(CVC4_FOUND)
# CVC4 may depend on either CLN or GMP.
# We can assume that the one it requires is present on the system,
# so we quietly try to find both and link against them, if they are
# present.
find_package(CLN QUIET)
find_package(GMP QUIET)
set(CVC4_LIBRARIES ${CVC4_LIBRARY})
if (CLN_FOUND)
set(CVC4_LIBRARIES ${CVC4_LIBRARIES} CLN::CLN)
endif ()
if (GMP_FOUND)
set(CVC4_LIBRARIES ${CVC4_LIBRARIES} GMP::GMP)
endif ()
if (NOT TARGET CVC4::CVC4)
add_library(CVC4::CVC4 UNKNOWN IMPORTED)
set_property(TARGET CVC4::CVC4 PROPERTY IMPORTED_LOCATION ${CVC4_LIBRARY})
set_property(TARGET CVC4::CVC4 PROPERTY INTERFACE_LINK_LIBRARIES ${CVC4_LIBRARIES})
set_property(TARGET CVC4::CVC4 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CVC4_INCLUDE_DIR})
endif()
endif()
else()
set(CVC4_FOUND FALSE)
endif()

33
cmake/FindCVC5.cmake Normal file
View File

@ -0,0 +1,33 @@
if (USE_CVC5)
find_path(CVC5_INCLUDE_DIR cvc5/cvc5.h)
find_library(CVC5_LIBRARY NAMES cvc5)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CVC5 DEFAULT_MSG CVC5_LIBRARY CVC5_INCLUDE_DIR)
if(CVC5_FOUND)
# CVC5 may depend on either CLN or GMP.
# We can assume that the one it requires is present on the system,
# so we quietly try to find both and link against them, if they are
# present.
find_package(CLN QUIET)
find_package(GMP QUIET)
set(CVC5_LIBRARIES ${CVC5_LIBRARY})
if (CLN_FOUND)
set(CVC5_LIBRARIES ${CVC5_LIBRARIES} CLN::CLN)
endif ()
if (GMP_FOUND)
set(CVC5_LIBRARIES ${CVC5_LIBRARIES} GMP::GMP)
endif ()
if (NOT TARGET CVC5::CVC5)
add_library(CVC5::CVC5 UNKNOWN IMPORTED)
set_property(TARGET CVC5::CVC5 PROPERTY IMPORTED_LOCATION ${CVC5_LIBRARY})
set_property(TARGET CVC5::CVC5 PROPERTY INTERFACE_LINK_LIBRARIES ${CVC5_LIBRARIES})
set_property(TARGET CVC5::CVC5 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CVC5_INCLUDE_DIR})
endif()
endif()
else()
set(CVC5_FOUND FALSE)
endif()

View File

@ -328,10 +328,10 @@ The following are dependencies for all builds of Solidity:
+-----------------------------------+-------------------------------------------------------+ +-----------------------------------+-------------------------------------------------------+
| `z3`_ (version 4.8.16+, Optional) | For use with SMT checker. | | `z3`_ (version 4.8.16+, Optional) | For use with SMT checker. |
+-----------------------------------+-------------------------------------------------------+ +-----------------------------------+-------------------------------------------------------+
| `cvc4`_ (Optional) | For use with SMT checker. | | `cvc5`_ (Optional) | For use with SMT checker. |
+-----------------------------------+-------------------------------------------------------+ +-----------------------------------+-------------------------------------------------------+
.. _cvc4: https://cvc4.cs.stanford.edu/web/ .. _cvc5: https://cvc5.github.io/downloads.html
.. _Git: https://git-scm.com/download .. _Git: https://git-scm.com/download
.. _Boost: https://www.boost.org .. _Boost: https://www.boost.org
.. _CMake: https://cmake.org/download/ .. _CMake: https://cmake.org/download/

View File

@ -821,10 +821,10 @@ which is primarily an SMT solver and makes `Spacer
<https://github.com/uuverifiers/eldarica>`_ which does both. <https://github.com/uuverifiers/eldarica>`_ which does both.
The user can choose which solvers should be used, if available, via the CLI The user can choose which solvers should be used, if available, via the CLI
option ``--model-checker-solvers {all,cvc4,eld,smtlib2,z3}`` or the JSON option option ``--model-checker-solvers {all,cvc5,eld,smtlib2,z3}`` or the JSON option
``settings.modelChecker.solvers=[smtlib2,z3]``, where: ``settings.modelChecker.solvers=[smtlib2,z3]``, where:
- ``cvc4`` is only available if the ``solc`` binary is compiled with it. Only BMC uses ``cvc4``. - ``cvc5`` is only available if the ``solc`` binary is compiled with it. Only BMC uses ``cvc5``.
- ``eld`` is used via its binary which must be installed in the system. Only CHC uses ``eld``, and only if ``z3`` is not enabled. - ``eld`` is used via its binary which must be installed in the system. Only CHC uses ``eld``, and only if ``z3`` is not enabled.
- ``smtlib2`` outputs SMT/Horn queries in the `smtlib2 <http://smtlib.cs.uiowa.edu/>`_ format. - ``smtlib2`` outputs SMT/Horn queries in the `smtlib2 <http://smtlib.cs.uiowa.edu/>`_ format.
These can be used together with the compiler's `callback mechanism <https://github.com/ethereum/solc-js>`_ so that These can be used together with the compiler's `callback mechanism <https://github.com/ethereum/solc-js>`_ so that
@ -848,7 +848,7 @@ concerned about this option. More advanced users might apply this option to try
alternative solvers on more complex problems. alternative solvers on more complex problems.
Please note that certain combinations of chosen engine and solver will lead to Please note that certain combinations of chosen engine and solver will lead to
the SMTChecker doing nothing, for example choosing CHC and ``cvc4``. the SMTChecker doing nothing, for example choosing CHC and ``cvc5``.
******************************* *******************************
Abstraction and False Positives Abstraction and False Positives

View File

@ -457,7 +457,7 @@ Input Description
"showUnsupported": true, "showUnsupported": true,
// Choose which solvers should be used, if available. // Choose which solvers should be used, if available.
// See the Formal Verification section for the solvers description. // See the Formal Verification section for the solvers description.
"solvers": ["cvc4", "smtlib2", "z3"], "solvers": ["cvc5", "smtlib2", "z3"],
// Choose which targets should be checked: constantCondition, // Choose which targets should be checked: constantCondition,
// underflow, overflow, divByZero, balance, assert, popEmptyArray, outOfBounds. // underflow, overflow, divByZero, balance, assert, popEmptyArray, outOfBounds.
// If the option is not given all targets are checked by default, // If the option is not given all targets are checked by default,

View File

@ -18,10 +18,10 @@ else()
set(z3_SRCS) set(z3_SRCS)
endif() endif()
if (${CVC4_FOUND}) if (${CVC5_FOUND})
set(cvc4_SRCS CVC4Interface.cpp CVC4Interface.h) set(cvc5_SRCS CVC4Interface.cpp CVC4Interface.h)
else() else()
set(cvc4_SRCS) set(cvc5_SRCS)
endif() endif()
if (${USE_Z3_DLOPEN}) if (${USE_Z3_DLOPEN})
@ -36,7 +36,7 @@ if (${USE_Z3_DLOPEN})
set(z3_SRCS ${z3_SRCS} ${Z3_WRAPPER} Z3Loader.cpp Z3Loader.h) set(z3_SRCS ${z3_SRCS} ${Z3_WRAPPER} Z3Loader.cpp Z3Loader.h)
endif() endif()
add_library(smtutil ${sources} ${z3_SRCS} ${cvc4_SRCS}) add_library(smtutil ${sources} ${z3_SRCS} ${cvc5_SRCS})
target_link_libraries(smtutil PUBLIC solutil Boost::boost) target_link_libraries(smtutil PUBLIC solutil Boost::boost)
if (${USE_Z3_DLOPEN}) if (${USE_Z3_DLOPEN})
@ -46,6 +46,6 @@ elseif (${Z3_FOUND})
target_link_libraries(smtutil PUBLIC z3::libz3) target_link_libraries(smtutil PUBLIC z3::libz3)
endif() endif()
if (${CVC4_FOUND}) if (${CVC5_FOUND})
target_link_libraries(smtutil PUBLIC CVC4::CVC4) target_link_libraries(smtutil PUBLIC CVC5::CVC5)
endif() endif()

View File

@ -18,102 +18,82 @@
#include <libsmtutil/CVC4Interface.h> #include <libsmtutil/CVC4Interface.h>
#include <libsolutil/CommonData.h>
#include <libsolutil/CommonIO.h> #include <libsolutil/CommonIO.h>
#include <libsolutil/Exceptions.h> #include <libsolutil/Exceptions.h>
#include <cvc4/util/bitvector.h>
using namespace std; using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::util; using namespace solidity::util;
using namespace solidity::smtutil; using namespace solidity::smtutil;
CVC4Interface::CVC4Interface(optional<unsigned> _queryTimeout): CVC5Interface::CVC5Interface(optional<unsigned> _queryTimeout):
SolverInterface(_queryTimeout), SolverInterface(_queryTimeout)
m_solver(&m_context)
{ {
reset(); reset();
} }
void CVC4Interface::reset() void CVC5Interface::reset()
{ {
m_variables.clear(); m_variables.clear();
m_solver.reset(); m_solver.resetAssertions();
m_solver.setOption("produce-models", true); m_solver.setOption("produce-models", "true");
if (m_queryTimeout) if (m_queryTimeout)
m_solver.setTimeLimit(*m_queryTimeout); m_solver.setOption("tlimit-per", std::to_string(*m_queryTimeout));
else else
m_solver.setResourceLimit(resourceLimit); m_solver.setOption("rlimit", std::to_string(resourceLimit));
} }
void CVC4Interface::push() void CVC5Interface::push()
{ {
m_solver.push(); m_solver.push();
} }
void CVC4Interface::pop() void CVC5Interface::pop()
{ {
m_solver.pop(); m_solver.pop();
} }
void CVC4Interface::declareVariable(string const& _name, SortPointer const& _sort) void CVC5Interface::declareVariable(string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort, ""); smtAssert(_sort, "");
m_variables[_name] = m_context.mkVar(_name.c_str(), cvc4Sort(*_sort)); m_variables[_name] = m_solver.mkConst(CVC5Sort(*_sort), _name);
} }
void CVC4Interface::addAssertion(Expression const& _expr) void CVC5Interface::addAssertion(Expression const& _expr)
{ {
try try
{ {
m_solver.assertFormula(toCVC4Expr(_expr)); m_solver.assertFormula(toCVC5Expr(_expr));
} }
catch (CVC4::TypeCheckingException const& _e) catch (cvc5::CVC5ApiException const& _e)
{
smtAssert(false, _e.what());
}
catch (CVC4::LogicException const& _e)
{
smtAssert(false, _e.what());
}
catch (CVC4::UnsafeInterruptException const& _e)
{
smtAssert(false, _e.what());
}
catch (CVC4::Exception const& _e)
{ {
smtAssert(false, _e.what()); smtAssert(false, _e.what());
} }
} }
pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const& _expressionsToEvaluate) pair<CheckResult, vector<string>> CVC5Interface::check(vector<Expression> const& _expressionsToEvaluate)
{ {
CheckResult result; CheckResult result;
vector<string> values; vector<string> values;
try try
{ {
switch (m_solver.checkSat().isSat()) cvc5::Result res = m_solver.checkSat();
{ if (res.isSat())
case CVC4::Result::SAT:
result = CheckResult::SATISFIABLE; result = CheckResult::SATISFIABLE;
break; else if (res.isUnsat())
case CVC4::Result::UNSAT:
result = CheckResult::UNSATISFIABLE; result = CheckResult::UNSATISFIABLE;
break; else if (res.isUnknown())
case CVC4::Result::SAT_UNKNOWN:
result = CheckResult::UNKNOWN; result = CheckResult::UNKNOWN;
break; else
default:
smtAssert(false, ""); smtAssert(false, "");
}
if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty()) if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty())
{ {
for (Expression const& e: _expressionsToEvaluate) for (Expression const& e: _expressionsToEvaluate)
values.push_back(toString(m_solver.getValue(toCVC4Expr(e)))); values.push_back(toString(m_solver.getValue(toCVC5Expr(e))));
} }
} }
catch (CVC4::Exception const&) catch (cvc5::CVC5ApiException const&)
{ {
result = CheckResult::ERROR; result = CheckResult::ERROR;
values.clear(); values.clear();
@ -122,41 +102,41 @@ pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const&
return make_pair(result, values); return make_pair(result, values);
} }
CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr) cvc5::Term CVC5Interface::toCVC5Expr(Expression const& _expr)
{ {
// Variable // Variable
if (_expr.arguments.empty() && m_variables.count(_expr.name)) if (_expr.arguments.empty() && m_variables.count(_expr.name))
return m_variables.at(_expr.name); return m_variables.at(_expr.name);
vector<CVC4::Expr> arguments; vector<cvc5::Term> arguments;
for (auto const& arg: _expr.arguments) for (auto const& arg: _expr.arguments)
arguments.push_back(toCVC4Expr(arg)); arguments.push_back(toCVC5Expr(arg));
try try
{ {
string const& n = _expr.name; string const& n = _expr.name;
// Function application // Function application
if (!arguments.empty() && m_variables.count(_expr.name)) if (!arguments.empty() && m_variables.count(_expr.name))
return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments); return m_solver.mkTerm(cvc5::Kind::APPLY_UF, vector<cvc5::Term>{m_variables.at(n)} + arguments);
// Literal // Literal
else if (arguments.empty()) else if (arguments.empty())
{ {
if (n == "true") if (n == "true")
return m_context.mkConst(true); return m_solver.mkTrue();
else if (n == "false") else if (n == "false")
return m_context.mkConst(false); return m_solver.mkFalse();
else if (auto sortSort = dynamic_pointer_cast<SortSort>(_expr.sort)) else if (auto sortSort = dynamic_pointer_cast<SortSort>(_expr.sort))
return m_context.mkVar(n, cvc4Sort(*sortSort->inner)); return m_solver.mkVar(CVC5Sort(*sortSort->inner), n);
else else
try try
{ {
return m_context.mkConst(CVC4::Rational(n)); return m_solver.mkInteger(n);
} }
catch (CVC4::TypeCheckingException const& _e) catch (cvc5::CVC5ApiRecoverableException const& _e)
{ {
smtAssert(false, _e.what()); smtAssert(false, _e.what());
} }
catch (CVC4::Exception const& _e) catch (cvc5::CVC5ApiException const& _e)
{ {
smtAssert(false, _e.what()); smtAssert(false, _e.what());
} }
@ -164,127 +144,127 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
smtAssert(_expr.hasCorrectArity(), ""); smtAssert(_expr.hasCorrectArity(), "");
if (n == "ite") if (n == "ite")
return arguments[0].iteExpr(arguments[1], arguments[2]); return arguments[0].iteTerm(arguments[1], arguments[2]);
else if (n == "not") else if (n == "not")
return arguments[0].notExpr(); return arguments[0].notTerm();
else if (n == "and") else if (n == "and")
return arguments[0].andExpr(arguments[1]); return arguments[0].andTerm(arguments[1]);
else if (n == "or") else if (n == "or")
return arguments[0].orExpr(arguments[1]); return arguments[0].orTerm(arguments[1]);
else if (n == "=>") else if (n == "=>")
return m_context.mkExpr(CVC4::kind::IMPLIES, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::IMPLIES, {arguments[0], arguments[1]});
else if (n == "=") else if (n == "=")
return m_context.mkExpr(CVC4::kind::EQUAL, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::EQUAL, {arguments[0], arguments[1]});
else if (n == "<") else if (n == "<")
return m_context.mkExpr(CVC4::kind::LT, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::LT, {arguments[0], arguments[1]});
else if (n == "<=") else if (n == "<=")
return m_context.mkExpr(CVC4::kind::LEQ, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::LEQ, {arguments[0], arguments[1]});
else if (n == ">") else if (n == ">")
return m_context.mkExpr(CVC4::kind::GT, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::GT, {arguments[0], arguments[1]});
else if (n == ">=") else if (n == ">=")
return m_context.mkExpr(CVC4::kind::GEQ, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::GEQ, {arguments[0], arguments[1]});
else if (n == "+") else if (n == "+")
return m_context.mkExpr(CVC4::kind::PLUS, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::ADD, {arguments[0], arguments[1]});
else if (n == "-") else if (n == "-")
return m_context.mkExpr(CVC4::kind::MINUS, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::SUB, {arguments[0], arguments[1]});
else if (n == "*") else if (n == "*")
return m_context.mkExpr(CVC4::kind::MULT, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::MULT, {arguments[0], arguments[1]});
else if (n == "div") else if (n == "div")
return m_context.mkExpr(CVC4::kind::INTS_DIVISION_TOTAL, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::INTS_DIVISION, {arguments[0], arguments[1]});
else if (n == "mod") else if (n == "mod")
return m_context.mkExpr(CVC4::kind::INTS_MODULUS, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::INTS_MODULUS, {arguments[0], arguments[1]});
else if (n == "bvnot") else if (n == "bvnot")
return m_context.mkExpr(CVC4::kind::BITVECTOR_NOT, arguments[0]); return m_solver.mkTerm(cvc5::Kind::BITVECTOR_NOT, {arguments[0]});
else if (n == "bvand") else if (n == "bvand")
return m_context.mkExpr(CVC4::kind::BITVECTOR_AND, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::BITVECTOR_AND, {arguments[0], arguments[1]});
else if (n == "bvor") else if (n == "bvor")
return m_context.mkExpr(CVC4::kind::BITVECTOR_OR, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::BITVECTOR_OR, {arguments[0], arguments[1]});
else if (n == "bvxor") else if (n == "bvxor")
return m_context.mkExpr(CVC4::kind::BITVECTOR_XOR, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::BITVECTOR_XOR, {arguments[0], arguments[1]});
else if (n == "bvshl") else if (n == "bvshl")
return m_context.mkExpr(CVC4::kind::BITVECTOR_SHL, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::BITVECTOR_SHL, {arguments[0], arguments[1]});
else if (n == "bvlshr") else if (n == "bvlshr")
return m_context.mkExpr(CVC4::kind::BITVECTOR_LSHR, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::BITVECTOR_LSHR, {arguments[0], arguments[1]});
else if (n == "bvashr") else if (n == "bvashr")
return m_context.mkExpr(CVC4::kind::BITVECTOR_ASHR, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::BITVECTOR_ASHR, {arguments[0], arguments[1]});
else if (n == "int2bv") else if (n == "int2bv")
{ {
size_t size = std::stoul(_expr.arguments[1].name); size_t size = std::stoul(_expr.arguments[1].name);
auto i2bvOp = m_context.mkConst(CVC4::IntToBitVector(static_cast<unsigned>(size))); auto i2bvOp = m_solver.mkOp(cvc5::Kind::INT_TO_BITVECTOR, {static_cast<unsigned>(size)});
// CVC4 treats all BVs as unsigned, so we need to manually apply 2's complement if needed. // CVC5 treats all BVs as unsigned, so we need to manually apply 2's complement if needed.
return m_context.mkExpr( return m_solver.mkTerm(
CVC4::kind::ITE, cvc5::Kind::ITE,
m_context.mkExpr(CVC4::kind::GEQ, arguments[0], m_context.mkConst(CVC4::Rational(0))), {
m_context.mkExpr(CVC4::kind::INT_TO_BITVECTOR, i2bvOp, arguments[0]), m_solver.mkTerm(cvc5::Kind::GEQ, {arguments[0], m_solver.mkInteger(0)}),
m_context.mkExpr( m_solver.mkTerm(i2bvOp, {arguments[0]}),
CVC4::kind::BITVECTOR_NEG, m_solver.mkTerm(
m_context.mkExpr(CVC4::kind::INT_TO_BITVECTOR, i2bvOp, m_context.mkExpr(CVC4::kind::UMINUS, arguments[0])) cvc5::Kind::BITVECTOR_NEG,
) {m_solver.mkTerm(i2bvOp, {m_solver.mkTerm(cvc5::Kind::NEG, {arguments[0]})})}
)
}
); );
} }
else if (n == "bv2int") else if (n == "bv2int")
{ {
auto intSort = dynamic_pointer_cast<IntSort>(_expr.sort); auto intSort = dynamic_pointer_cast<IntSort>(_expr.sort);
smtAssert(intSort, ""); smtAssert(intSort, "");
auto nat = m_context.mkExpr(CVC4::kind::BITVECTOR_TO_NAT, arguments[0]); auto nat = m_solver.mkTerm(cvc5::Kind::BITVECTOR_TO_NAT, {arguments[0]});
if (!intSort->isSigned) if (!intSort->isSigned)
return nat; return nat;
auto type = arguments[0].getType(); auto type = arguments[0].getSort();
smtAssert(type.isBitVector(), ""); smtAssert(type.isBitVector(), "");
auto size = CVC4::BitVectorType(type).getSize(); auto size = type.getBitVectorSize();
// CVC4 treats all BVs as unsigned, so we need to manually apply 2's complement if needed. // CVC5 treats all BVs as unsigned, so we need to manually apply 2's complement if needed.
auto extractOp = m_context.mkConst(CVC4::BitVectorExtract(size - 1, size - 1)); auto extractOp = m_solver.mkOp(cvc5::Kind::BITVECTOR_EXTRACT, {size - 1, size - 1});
return m_context.mkExpr(CVC4::kind::ITE, return m_solver.mkTerm(
m_context.mkExpr( cvc5::Kind::ITE,
CVC4::kind::EQUAL, {
m_context.mkExpr(CVC4::kind::BITVECTOR_EXTRACT, extractOp, arguments[0]), m_solver.mkTerm(
m_context.mkConst(CVC4::BitVector(1, uint64_t{0})) cvc5::Kind::EQUAL,
), {m_solver.mkTerm(extractOp, {arguments[0]}), m_solver.mkBitVector(1, uint64_t{0})}
nat, ),
m_context.mkExpr( nat,
CVC4::kind::UMINUS, m_solver.mkTerm(
m_context.mkExpr(CVC4::kind::BITVECTOR_TO_NAT, m_context.mkExpr(CVC4::kind::BITVECTOR_NEG, arguments[0])) cvc5::Kind::NEG,
) {m_solver.mkTerm(cvc5::Kind::BITVECTOR_TO_NAT, {m_solver.mkTerm(cvc5::Kind::BITVECTOR_NEG, {arguments[0]})})}
)
}
); );
} }
else if (n == "select") else if (n == "select")
return m_context.mkExpr(CVC4::kind::SELECT, arguments[0], arguments[1]); return m_solver.mkTerm(cvc5::Kind::SELECT, {arguments[0], arguments[1]});
else if (n == "store") else if (n == "store")
return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]); return m_solver.mkTerm(cvc5::Kind::STORE, {arguments[0], arguments[1], arguments[2]});
else if (n == "const_array") else if (n == "const_array")
{ {
shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort); shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort);
smtAssert(sortSort, ""); smtAssert(sortSort, "");
return m_context.mkConst(CVC4::ArrayStoreAll(cvc4Sort(*sortSort->inner), arguments[1])); return m_solver.mkConstArray(CVC5Sort(*sortSort->inner), arguments[1]);
} }
else if (n == "tuple_get") else if (n == "tuple_get")
{ {
shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments[0].sort); shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments[0].sort);
smtAssert(tupleSort, ""); smtAssert(tupleSort, "");
CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components)); auto tt = m_solver.mkTupleSort(CVC5Sort(tupleSort->components));
CVC4::Datatype const& dt = tt.getDatatype(); cvc5::Datatype const& dt = tt.getDatatype();
size_t index = std::stoul(_expr.arguments[1].name); size_t index = std::stoul(_expr.arguments[1].name);
CVC4::Expr s = dt[0][index].getSelector(); cvc5::DatatypeSelector s = dt[0][index];
return m_context.mkExpr(CVC4::kind::APPLY_SELECTOR, s, arguments[0]); return m_solver.mkTerm(cvc5::Kind::APPLY_SELECTOR, {s.getTerm(), arguments[0]});
} }
else if (n == "tuple_constructor") else if (n == "tuple_constructor")
{ {
shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort); shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort);
smtAssert(tupleSort, ""); smtAssert(tupleSort, "");
CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components)); auto tt = m_solver.mkTupleSort(CVC5Sort(tupleSort->components));
CVC4::Datatype const& dt = tt.getDatatype(); cvc5::Datatype const& dt = tt.getDatatype();
CVC4::Expr c = dt[0].getConstructor(); cvc5::DatatypeConstructor c = dt[0];
return m_context.mkExpr(CVC4::kind::APPLY_CONSTRUCTOR, c, arguments); return m_solver.mkTerm(cvc5::Kind::APPLY_CONSTRUCTOR, vector<cvc5::Term>{c.getTerm()} + arguments);
} }
smtAssert(false); smtAssert(false);
} }
catch (CVC4::TypeCheckingException const& _e) catch (cvc5::CVC5ApiException const& _e)
{
smtAssert(false, _e.what());
}
catch (CVC4::Exception const& _e)
{ {
smtAssert(false, _e.what()); smtAssert(false, _e.what());
} }
@ -295,43 +275,45 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
util::unreachable(); util::unreachable();
} }
CVC4::Type CVC4Interface::cvc4Sort(Sort const& _sort) cvc5::Sort CVC5Interface::CVC5Sort(Sort const& _sort)
{ {
switch (_sort.kind) switch (_sort.kind)
{ {
case Kind::Bool: case Kind::Bool:
return m_context.booleanType(); return m_solver.getBooleanSort();
case Kind::Int: case Kind::Int:
return m_context.integerType(); return m_solver.getIntegerSort();
case Kind::BitVector: case Kind::BitVector:
return m_context.mkBitVectorType(dynamic_cast<BitVectorSort const&>(_sort).size); return m_solver.mkBitVectorSort(dynamic_cast<BitVectorSort const&>(_sort).size);
case Kind::Function: case Kind::Function:
{ {
FunctionSort const& fSort = dynamic_cast<FunctionSort const&>(_sort); FunctionSort const& fSort = dynamic_cast<FunctionSort const&>(_sort);
return m_context.mkFunctionType(cvc4Sort(fSort.domain), cvc4Sort(*fSort.codomain)); if (fSort.domain.empty()) // function sort in cvc5 must have nonempty domain
return CVC5Sort(*fSort.codomain);
return m_solver.mkFunctionSort(CVC5Sort(fSort.domain), CVC5Sort(*fSort.codomain));
} }
case Kind::Array: case Kind::Array:
{ {
auto const& arraySort = dynamic_cast<ArraySort const&>(_sort); auto const& arraySort = dynamic_cast<ArraySort const&>(_sort);
return m_context.mkArrayType(cvc4Sort(*arraySort.domain), cvc4Sort(*arraySort.range)); return m_solver.mkArraySort(CVC5Sort(*arraySort.domain), CVC5Sort(*arraySort.range));
} }
case Kind::Tuple: case Kind::Tuple:
{ {
auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort); auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort);
return m_context.mkTupleType(cvc4Sort(tupleSort.components)); return m_solver.mkTupleSort(CVC5Sort(tupleSort.components));
} }
default: default:
break; break;
} }
smtAssert(false, ""); smtAssert(false, "");
// Cannot be reached. // Cannot be reached.
return m_context.integerType(); return m_solver.getIntegerSort();
} }
vector<CVC4::Type> CVC4Interface::cvc4Sort(vector<SortPointer> const& _sorts) vector<cvc5::Sort> CVC5Interface::CVC5Sort(vector<SortPointer> const& _sorts)
{ {
vector<CVC4::Type> cvc4Sorts; vector<cvc5::Sort> CVC5Sorts;
for (auto const& _sort: _sorts) for (auto const& _sort: _sorts)
cvc4Sorts.push_back(cvc4Sort(*_sort)); CVC5Sorts.push_back(CVC5Sort(*_sort));
return cvc4Sorts; return CVC5Sorts;
} }

View File

@ -20,30 +20,19 @@
#include <libsmtutil/SolverInterface.h> #include <libsmtutil/SolverInterface.h>
#if defined(__GLIBC__) #include <cvc5/cvc5.h>
// The CVC4 headers includes the deprecated system headers <ext/hash_map>
// and <ext/hash_set>. These headers cause a warning that will break the
// build, unless _GLIBCXX_PERMIT_BACKWARD_HASH is set.
#define _GLIBCXX_PERMIT_BACKWARD_HASH
#endif
#include <cvc4/cvc4.h>
#if defined(__GLIBC__)
#undef _GLIBCXX_PERMIT_BACKWARD_HASH
#endif
namespace solidity::smtutil namespace solidity::smtutil
{ {
class CVC4Interface: public SolverInterface class CVC5Interface: public SolverInterface
{ {
public: public:
/// Noncopyable. /// Noncopyable.
CVC4Interface(CVC4Interface const&) = delete; CVC5Interface(CVC5Interface const&) = delete;
CVC4Interface& operator=(CVC4Interface const&) = delete; CVC5Interface& operator=(CVC5Interface const&) = delete;
CVC4Interface(std::optional<unsigned> _queryTimeout = {}); CVC5Interface(std::optional<unsigned> _queryTimeout = {});
void reset() override; void reset() override;
@ -56,17 +45,16 @@ public:
std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override; std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
private: private:
CVC4::Expr toCVC4Expr(Expression const& _expr); cvc5::Term toCVC5Expr(Expression const& _expr);
CVC4::Type cvc4Sort(Sort const& _sort); cvc5::Sort CVC5Sort(Sort const& _sort);
std::vector<CVC4::Type> cvc4Sort(std::vector<SortPointer> const& _sorts); std::vector<cvc5::Sort> CVC5Sort(std::vector<SortPointer> const& _sorts);
CVC4::ExprManager m_context; cvc5::Solver m_solver;
CVC4::SmtEngine m_solver; std::map<std::string, cvc5::Term> m_variables;
std::map<std::string, CVC4::Expr> m_variables;
// CVC4 "basic resources" limit. // CVC5 "basic resources" limit.
// This is used to make the runs more deterministic and platform/machine independent. // This is used to make the runs more deterministic and platform/machine independent.
// The tests start failing for CVC4 with less than 6000, // The tests start failing for CVC5 with less than 6000,
// so using double that. // so using double that.
static int const resourceLimit = 12000; static int const resourceLimit = 12000;
}; };

View File

@ -21,7 +21,7 @@
#ifdef HAVE_Z3 #ifdef HAVE_Z3
#include <libsmtutil/Z3Interface.h> #include <libsmtutil/Z3Interface.h>
#endif #endif
#ifdef HAVE_CVC4 #ifdef HAVE_CVC5
#include <libsmtutil/CVC4Interface.h> #include <libsmtutil/CVC4Interface.h>
#endif #endif
#include <libsmtutil/SMTLib2Interface.h> #include <libsmtutil/SMTLib2Interface.h>
@ -46,9 +46,9 @@ SMTPortfolio::SMTPortfolio(
if (_enabledSolvers.z3 && Z3Interface::available()) if (_enabledSolvers.z3 && Z3Interface::available())
m_solvers.emplace_back(make_unique<Z3Interface>(m_queryTimeout)); m_solvers.emplace_back(make_unique<Z3Interface>(m_queryTimeout));
#endif #endif
#ifdef HAVE_CVC4 #ifdef HAVE_CVC5
if (_enabledSolvers.cvc4) if (_enabledSolvers.cvc5)
m_solvers.emplace_back(make_unique<CVC4Interface>(m_queryTimeout)); m_solvers.emplace_back(make_unique<CVC5Interface>(m_queryTimeout));
#endif #endif
} }

View File

@ -41,13 +41,13 @@ namespace solidity::smtutil
struct SMTSolverChoice struct SMTSolverChoice
{ {
bool cvc4 = false; bool cvc5 = false;
bool eld = false; bool eld = false;
bool smtlib2 = false; bool smtlib2 = false;
bool z3 = false; bool z3 = false;
static constexpr SMTSolverChoice All() noexcept { return {true, true, true, true}; } static constexpr SMTSolverChoice All() noexcept { return {true, true, true, true}; }
static constexpr SMTSolverChoice CVC4() noexcept { return {true, false, false, false}; } static constexpr SMTSolverChoice CVC5() noexcept { return {true, false, false, false}; }
static constexpr SMTSolverChoice ELD() noexcept { return {false, true, false, false}; } static constexpr SMTSolverChoice ELD() noexcept { return {false, true, false, false}; }
static constexpr SMTSolverChoice SMTLIB2() noexcept { return {false, false, true, false}; } static constexpr SMTSolverChoice SMTLIB2() noexcept { return {false, false, true, false}; }
static constexpr SMTSolverChoice Z3() noexcept { return {false, false, false, true}; } static constexpr SMTSolverChoice Z3() noexcept { return {false, false, false, true}; }
@ -65,7 +65,7 @@ struct SMTSolverChoice
SMTSolverChoice& operator&=(SMTSolverChoice const& _other) SMTSolverChoice& operator&=(SMTSolverChoice const& _other)
{ {
cvc4 &= _other.cvc4; cvc5 &= _other.cvc5;
eld &= _other.eld; eld &= _other.eld;
smtlib2 &= _other.smtlib2; smtlib2 &= _other.smtlib2;
z3 &= _other.z3; z3 &= _other.z3;
@ -82,7 +82,7 @@ struct SMTSolverChoice
bool operator==(SMTSolverChoice const& _other) const noexcept bool operator==(SMTSolverChoice const& _other) const noexcept
{ {
return cvc4 == _other.cvc4 && return cvc5 == _other.cvc5 &&
eld == _other.eld && eld == _other.eld &&
smtlib2 == _other.smtlib2 && smtlib2 == _other.smtlib2 &&
z3 == _other.z3; z3 == _other.z3;
@ -90,11 +90,11 @@ struct SMTSolverChoice
bool setSolver(std::string const& _solver) bool setSolver(std::string const& _solver)
{ {
static std::set<std::string> const solvers{"cvc4", "eld", "smtlib2", "z3"}; static std::set<std::string> const solvers{"cvc5", "eld", "smtlib2", "z3"};
if (!solvers.count(_solver)) if (!solvers.count(_solver))
return false; return false;
if (_solver == "cvc4") if (_solver == "cvc5")
cvc4 = true; cvc5 = true;
if (_solver == "eld") if (_solver == "eld")
eld = true; eld = true;
else if (_solver == "smtlib2") else if (_solver == "smtlib2")
@ -105,8 +105,8 @@ struct SMTSolverChoice
} }
bool none() const noexcept { return !some(); } bool none() const noexcept { return !some(); }
bool some() const noexcept { return cvc4 || eld || smtlib2 || z3; } bool some() const noexcept { return cvc5 || eld || smtlib2 || z3; }
bool all() const noexcept { return cvc4 && eld && smtlib2 && z3; } bool all() const noexcept { return cvc5 && eld && smtlib2 && z3; }
}; };
enum class CheckResult enum class CheckResult

View File

@ -49,15 +49,15 @@ BMC::BMC(
SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider), SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider),
m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _settings.solvers, _settings.timeout)) m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _settings.solvers, _settings.timeout))
{ {
#if defined (HAVE_Z3) || defined (HAVE_CVC4) #if defined (HAVE_Z3) || defined (HAVE_CVC5)
if (m_settings.solvers.cvc4 || m_settings.solvers.z3) if (m_settings.solvers.cvc5 || m_settings.solvers.z3)
if (!_smtlib2Responses.empty()) if (!_smtlib2Responses.empty())
m_errorReporter.warning( m_errorReporter.warning(
5622_error, 5622_error,
"SMT-LIB2 query responses were given in the auxiliary input, " "SMT-LIB2 query responses were given in the auxiliary input, "
"but this Solidity binary uses an SMT solver (Z3/CVC4) directly." "but this Solidity binary uses an SMT solver (Z3/cvc5) directly."
"These responses will be ignored." "These responses will be ignored."
"Consider disabling Z3/CVC4 at compilation time in order to use SMT-LIB2 responses." "Consider disabling Z3/cvc5 at compilation time in order to use SMT-LIB2 responses."
); );
#endif #endif
} }
@ -65,13 +65,13 @@ BMC::BMC(
void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<VerificationTargetType>, smt::EncodingContext::IdCompare> _solvedTargets) void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<VerificationTargetType>, smt::EncodingContext::IdCompare> _solvedTargets)
{ {
// At this point every enabled solver is available. // At this point every enabled solver is available.
if (!m_settings.solvers.cvc4 && !m_settings.solvers.smtlib2 && !m_settings.solvers.z3) if (!m_settings.solvers.cvc5 && !m_settings.solvers.smtlib2 && !m_settings.solvers.z3)
{ {
m_errorReporter.warning( m_errorReporter.warning(
7710_error, 7710_error,
SourceLocation(), SourceLocation(),
"BMC analysis was not possible since no SMT solver was found and enabled." "BMC analysis was not possible since no SMT solver was found and enabled."
" The accepted solvers for BMC are cvc4 and z3." " The accepted solvers for BMC are cvc5 and z3."
); );
return; return;
} }
@ -121,7 +121,7 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
); );
// If this check is true, Z3 and CVC4 are not available // If this check is true, Z3 and cvc5 are not available
// and the query answers were not provided, since SMTPortfolio // and the query answers were not provided, since SMTPortfolio
// guarantees that SmtLib2Interface is the first solver, if enabled. // guarantees that SmtLib2Interface is the first solver, if enabled.
if ( if (
@ -132,7 +132,7 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
m_errorReporter.warning( m_errorReporter.warning(
8084_error, 8084_error,
SourceLocation(), SourceLocation(),
"BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available." "BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available."
" None of the installed solvers was enabled." " None of the installed solvers was enabled."
#ifdef HAVE_Z3_DLOPEN #ifdef HAVE_Z3_DLOPEN
" Install libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " to enable Z3." " Install libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " to enable Z3."

View File

@ -170,8 +170,8 @@ SMTSolverChoice ModelChecker::availableSolvers()
#ifdef HAVE_Z3 #ifdef HAVE_Z3
available.z3 = solidity::smtutil::Z3Interface::available(); available.z3 = solidity::smtutil::Z3Interface::available();
#endif #endif
#ifdef HAVE_CVC4 #ifdef HAVE_CVC5
available.cvc4 = true; available.cvc5 = true;
#endif #endif
return available; return available;
} }
@ -180,13 +180,13 @@ SMTSolverChoice ModelChecker::checkRequestedSolvers(SMTSolverChoice _enabled, Er
{ {
SMTSolverChoice availableSolvers{ModelChecker::availableSolvers()}; SMTSolverChoice availableSolvers{ModelChecker::availableSolvers()};
if (_enabled.cvc4 && !availableSolvers.cvc4) if (_enabled.cvc5 && !availableSolvers.cvc5)
{ {
_enabled.cvc4 = false; _enabled.cvc5 = false;
_errorReporter.warning( _errorReporter.warning(
4902_error, 4902_error,
SourceLocation(), SourceLocation(),
"Solver CVC4 was selected for SMTChecker but it is not available." "Solver cvc5 was selected for SMTChecker but it is not available."
); );
} }

View File

@ -855,7 +855,7 @@ General Information)").c_str(),
) )
( (
g_strModelCheckerSolvers.c_str(), g_strModelCheckerSolvers.c_str(),
po::value<string>()->value_name("cvc4,eld,z3,smtlib2")->default_value("z3"), po::value<string>()->value_name("cvc5,eld,z3,smtlib2")->default_value("z3"),
"Select model checker solvers." "Select model checker solvers."
) )
( (

View File

@ -4,4 +4,4 @@ Warning: CHC analysis was not possible. No Horn solver was available. None of th
Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query. Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option "show unproved" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.
Warning: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.

View File

@ -14,10 +14,10 @@
{ {
"component": "general", "component": "general",
"errorCode": "7710", "errorCode": "7710",
"formattedMessage": "Warning: BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc4 and z3. "formattedMessage": "Warning: BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc5 and z3.
", ",
"message": "BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc4 and z3.", "message": "BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc5 and z3.",
"severity": "warning", "severity": "warning",
"type": "Warning" "type": "Warning"
} }

View File

@ -189,10 +189,10 @@
{ {
"component": "general", "component": "general",
"errorCode": "8084", "errorCode": "8084",
"formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. "formattedMessage": "Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.
", ",
"message": "BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled.", "message": "BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.",
"severity": "warning", "severity": "warning",
"type": "Warning" "type": "Warning"
} }

View File

@ -53,7 +53,7 @@ protected:
Set in m_modelCheckerSettings. Set in m_modelCheckerSettings.
SMTShowUnproved: `yes`, `no`, where the default is `yes`. SMTShowUnproved: `yes`, `no`, where the default is `yes`.
Set in m_modelCheckerSettings. Set in m_modelCheckerSettings.
SMTSolvers: `all`, `cvc4`, `z3`, `none`, where the default is `all`. SMTSolvers: `all`, `cvc5`, `z3`, `none`, where the default is `all`.
Set in m_modelCheckerSettings. Set in m_modelCheckerSettings.
BMCLoopIterations: number of loop iterations for BMC engine, the default is 1. BMCLoopIterations: number of loop iterations for BMC engine, the default is 1.
Set in m_modelCheckerSettings. Set in m_modelCheckerSettings.

View File

@ -19,8 +19,8 @@ contract C is B {
// Warning 6328: (b.sol:62-75): CHC: Assertion violation might happen here. // Warning 6328: (b.sol:62-75): CHC: Assertion violation might happen here.
// Warning 3996: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled. // Warning 3996: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.
// Warning 7812: (b.sol:62-75): BMC: Assertion violation might happen here. // Warning 7812: (b.sol:62-75): BMC: Assertion violation might happen here.
// Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. // Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.
// Warning 6328: (c.sol:68-81): CHC: Assertion violation might happen here. // Warning 6328: (c.sol:68-81): CHC: Assertion violation might happen here.
// Warning 3996: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled. // Warning 3996: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.
// Warning 7812: (c.sol:68-81): BMC: Assertion violation might happen here. // Warning 7812: (c.sol:68-81): BMC: Assertion violation might happen here.
// Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available. None of the installed solvers was enabled. // Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.