[SMTChecker] Report malformed expressions more precisely

This commit is contained in:
Leonardo Alt 2019-06-05 11:51:43 +02:00
parent fc35c139ca
commit 1221eeebf1
2 changed files with 147 additions and 119 deletions

View File

@ -60,17 +60,21 @@ void CVC4Interface::addAssertion(Expression const& _expr)
{ {
m_solver.assertFormula(toCVC4Expr(_expr)); m_solver.assertFormula(toCVC4Expr(_expr));
} }
catch (CVC4::TypeCheckingException const&) catch (CVC4::TypeCheckingException const& _e)
{ {
solAssert(false, ""); solAssert(false, _e.what());
} }
catch (CVC4::LogicException const&) catch (CVC4::LogicException const& _e)
{ {
solAssert(false, ""); solAssert(false, _e.what());
} }
catch (CVC4::UnsafeInterruptException const&) catch (CVC4::UnsafeInterruptException const& _e)
{ {
solAssert(false, ""); solAssert(false, _e.what());
}
catch (CVC4::Exception const& _e)
{
solAssert(false, _e.what());
} }
} }
@ -120,66 +124,82 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
for (auto const& arg: _expr.arguments) for (auto const& arg: _expr.arguments)
arguments.push_back(toCVC4Expr(arg)); arguments.push_back(toCVC4Expr(arg));
string const& n = _expr.name; try
// Function application
if (!arguments.empty() && m_variables.count(_expr.name))
return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments);
// Literal
else if (arguments.empty())
{ {
if (n == "true") string const& n = _expr.name;
return m_context.mkConst(true); // Function application
else if (n == "false") if (!arguments.empty() && m_variables.count(_expr.name))
return m_context.mkConst(false); return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments);
else // Literal
try else if (arguments.empty())
{ {
return m_context.mkConst(CVC4::Rational(n)); if (n == "true")
} return m_context.mkConst(true);
catch (...) else if (n == "false")
{ return m_context.mkConst(false);
solAssert(false, ""); else
} try
{
return m_context.mkConst(CVC4::Rational(n));
}
catch (CVC4::TypeCheckingException const& _e)
{
solAssert(false, _e.what());
}
catch (CVC4::Exception const& _e)
{
solAssert(false, _e.what());
}
}
solAssert(_expr.hasCorrectArity(), "");
if (n == "ite")
return arguments[0].iteExpr(arguments[1], arguments[2]);
else if (n == "not")
return arguments[0].notExpr();
else if (n == "and")
return arguments[0].andExpr(arguments[1]);
else if (n == "or")
return arguments[0].orExpr(arguments[1]);
else if (n == "implies")
return m_context.mkExpr(CVC4::kind::IMPLIES, arguments[0], arguments[1]);
else if (n == "=")
return m_context.mkExpr(CVC4::kind::EQUAL, arguments[0], arguments[1]);
else if (n == "<")
return m_context.mkExpr(CVC4::kind::LT, arguments[0], arguments[1]);
else if (n == "<=")
return m_context.mkExpr(CVC4::kind::LEQ, arguments[0], arguments[1]);
else if (n == ">")
return m_context.mkExpr(CVC4::kind::GT, arguments[0], arguments[1]);
else if (n == ">=")
return m_context.mkExpr(CVC4::kind::GEQ, arguments[0], arguments[1]);
else if (n == "+")
return m_context.mkExpr(CVC4::kind::PLUS, arguments[0], arguments[1]);
else if (n == "-")
return m_context.mkExpr(CVC4::kind::MINUS, arguments[0], arguments[1]);
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]);
else if (n == "mod")
return m_context.mkExpr(CVC4::kind::INTS_MODULUS, arguments[0], arguments[1]);
else if (n == "select")
return m_context.mkExpr(CVC4::kind::SELECT, arguments[0], arguments[1]);
else if (n == "store")
return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]);
solAssert(false, "");
}
catch (CVC4::TypeCheckingException const& _e)
{
solAssert(false, _e.what());
}
catch (CVC4::Exception const& _e)
{
solAssert(false, _e.what());
} }
solAssert(_expr.hasCorrectArity(), "");
if (n == "ite")
return arguments[0].iteExpr(arguments[1], arguments[2]);
else if (n == "not")
return arguments[0].notExpr();
else if (n == "and")
return arguments[0].andExpr(arguments[1]);
else if (n == "or")
return arguments[0].orExpr(arguments[1]);
else if (n == "implies")
return m_context.mkExpr(CVC4::kind::IMPLIES, arguments[0], arguments[1]);
else if (n == "=")
return m_context.mkExpr(CVC4::kind::EQUAL, arguments[0], arguments[1]);
else if (n == "<")
return m_context.mkExpr(CVC4::kind::LT, arguments[0], arguments[1]);
else if (n == "<=")
return m_context.mkExpr(CVC4::kind::LEQ, arguments[0], arguments[1]);
else if (n == ">")
return m_context.mkExpr(CVC4::kind::GT, arguments[0], arguments[1]);
else if (n == ">=")
return m_context.mkExpr(CVC4::kind::GEQ, arguments[0], arguments[1]);
else if (n == "+")
return m_context.mkExpr(CVC4::kind::PLUS, arguments[0], arguments[1]);
else if (n == "-")
return m_context.mkExpr(CVC4::kind::MINUS, arguments[0], arguments[1]);
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]);
else if (n == "mod")
return m_context.mkExpr(CVC4::kind::INTS_MODULUS, arguments[0], arguments[1]);
else if (n == "select")
return m_context.mkExpr(CVC4::kind::SELECT, arguments[0], arguments[1]);
else if (n == "store")
return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]);
// Cannot reach here.
solAssert(false, ""); solAssert(false, "");
return arguments[0];
} }
CVC4::Type CVC4Interface::cvc4Sort(Sort const& _sort) CVC4::Type CVC4Interface::cvc4Sort(Sort const& _sort)

View File

@ -116,69 +116,77 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
for (auto const& arg: _expr.arguments) for (auto const& arg: _expr.arguments)
arguments.push_back(toZ3Expr(arg)); arguments.push_back(toZ3Expr(arg));
string const& n = _expr.name; try
if (m_functions.count(n))
return m_functions.at(n)(arguments);
else if (m_constants.count(n))
{ {
solAssert(arguments.empty(), ""); string const& n = _expr.name;
return m_constants.at(n); if (m_functions.count(n))
return m_functions.at(n)(arguments);
else if (m_constants.count(n))
{
solAssert(arguments.empty(), "");
return m_constants.at(n);
}
else if (arguments.empty())
{
if (n == "true")
return m_context.bool_val(true);
else if (n == "false")
return m_context.bool_val(false);
else
try
{
return m_context.int_val(n.c_str());
}
catch (z3::exception const& _e)
{
solAssert(false, _e.msg());
}
}
solAssert(_expr.hasCorrectArity(), "");
if (n == "ite")
return z3::ite(arguments[0], arguments[1], arguments[2]);
else if (n == "not")
return !arguments[0];
else if (n == "and")
return arguments[0] && arguments[1];
else if (n == "or")
return arguments[0] || arguments[1];
else if (n == "implies")
return z3::implies(arguments[0], arguments[1]);
else if (n == "=")
return arguments[0] == arguments[1];
else if (n == "<")
return arguments[0] < arguments[1];
else if (n == "<=")
return arguments[0] <= arguments[1];
else if (n == ">")
return arguments[0] > arguments[1];
else if (n == ">=")
return arguments[0] >= arguments[1];
else if (n == "+")
return arguments[0] + arguments[1];
else if (n == "-")
return arguments[0] - arguments[1];
else if (n == "*")
return arguments[0] * arguments[1];
else if (n == "/")
return arguments[0] / arguments[1];
else if (n == "mod")
return z3::mod(arguments[0], arguments[1]);
else if (n == "select")
return z3::select(arguments[0], arguments[1]);
else if (n == "store")
return z3::store(arguments[0], arguments[1], arguments[2]);
solAssert(false, "");
} }
else if (arguments.empty()) catch (z3::exception const& _e)
{ {
if (n == "true") solAssert(false, _e.msg());
return m_context.bool_val(true);
else if (n == "false")
return m_context.bool_val(false);
else
try
{
return m_context.int_val(n.c_str());
}
catch (...)
{
solAssert(false, "");
}
} }
solAssert(_expr.hasCorrectArity(), "");
if (n == "ite")
return z3::ite(arguments[0], arguments[1], arguments[2]);
else if (n == "not")
return !arguments[0];
else if (n == "and")
return arguments[0] && arguments[1];
else if (n == "or")
return arguments[0] || arguments[1];
else if (n == "implies")
return z3::implies(arguments[0], arguments[1]);
else if (n == "=")
return arguments[0] == arguments[1];
else if (n == "<")
return arguments[0] < arguments[1];
else if (n == "<=")
return arguments[0] <= arguments[1];
else if (n == ">")
return arguments[0] > arguments[1];
else if (n == ">=")
return arguments[0] >= arguments[1];
else if (n == "+")
return arguments[0] + arguments[1];
else if (n == "-")
return arguments[0] - arguments[1];
else if (n == "*")
return arguments[0] * arguments[1];
else if (n == "/")
return arguments[0] / arguments[1];
else if (n == "mod")
return z3::mod(arguments[0], arguments[1]);
else if (n == "select")
return z3::select(arguments[0], arguments[1]);
else if (n == "store")
return z3::store(arguments[0], arguments[1], arguments[2]);
// Cannot reach here.
solAssert(false, ""); solAssert(false, "");
return arguments[0];
} }
z3::sort Z3Interface::z3Sort(Sort const& _sort) z3::sort Z3Interface::z3Sort(Sort const& _sort)