mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix CHCSmtLib2Interface
This commit is contained in:
@@ -53,8 +53,7 @@ void CHCSmtLib2Interface::reset()
|
||||
m_accumulatedOutput.clear();
|
||||
m_variables.clear();
|
||||
m_unhandledQueries.clear();
|
||||
if (m_queryTimeout)
|
||||
write("(set-option :timeout " + to_string(*m_queryTimeout) + ")");
|
||||
m_sortNames.clear();
|
||||
}
|
||||
|
||||
void CHCSmtLib2Interface::registerRelation(Expression const& _expr)
|
||||
@@ -64,27 +63,25 @@ void CHCSmtLib2Interface::registerRelation(Expression const& _expr)
|
||||
if (!m_variables.count(_expr.name))
|
||||
{
|
||||
auto fSort = dynamic_pointer_cast<FunctionSort>(_expr.sort);
|
||||
string domain = m_smtlib2->toSmtLibSort(fSort->domain);
|
||||
string domain = toSmtLibSort(fSort->domain);
|
||||
// Relations are predicates which have implicit codomain Bool.
|
||||
m_variables.insert(_expr.name);
|
||||
write(
|
||||
"(declare-rel |" +
|
||||
"(declare-fun |" +
|
||||
_expr.name +
|
||||
"| " +
|
||||
domain +
|
||||
")"
|
||||
" Bool)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& _name)
|
||||
void CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& /*_name*/)
|
||||
{
|
||||
write(
|
||||
"(rule (! " +
|
||||
"(assert\n(forall " + forall() + "\n" +
|
||||
m_smtlib2->toSExpr(_expr) +
|
||||
" :named " +
|
||||
_name +
|
||||
"))"
|
||||
"))\n\n"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,22 +89,29 @@ pair<CheckResult, CHCSolverInterface::CexGraph> CHCSmtLib2Interface::query(Expre
|
||||
{
|
||||
string accumulated{};
|
||||
swap(m_accumulatedOutput, accumulated);
|
||||
for (auto const& var: m_smtlib2->variables())
|
||||
declareVariable(var.first, var.second);
|
||||
solAssert(m_smtlib2, "");
|
||||
writeHeader();
|
||||
for (auto const& [type, decl]: m_smtlib2->userSorts())
|
||||
write(decl);
|
||||
m_accumulatedOutput += accumulated;
|
||||
|
||||
string queryRule = "(assert\n(forall " + forall() + "\n" +
|
||||
"(=> " + _block.name + " false)"
|
||||
"))";
|
||||
string response = querySolver(
|
||||
m_accumulatedOutput +
|
||||
"\n(query " + _block.name + " :print-certificate true)"
|
||||
queryRule +
|
||||
"\n(check-sat)"
|
||||
);
|
||||
swap(m_accumulatedOutput, accumulated);
|
||||
|
||||
CheckResult result;
|
||||
// TODO proper parsing
|
||||
if (boost::starts_with(response, "sat\n"))
|
||||
result = CheckResult::SATISFIABLE;
|
||||
else if (boost::starts_with(response, "unsat\n"))
|
||||
if (boost::starts_with(response, "sat"))
|
||||
result = CheckResult::UNSATISFIABLE;
|
||||
else if (boost::starts_with(response, "unknown\n"))
|
||||
else if (boost::starts_with(response, "unsat"))
|
||||
result = CheckResult::SATISFIABLE;
|
||||
else if (boost::starts_with(response, "unknown"))
|
||||
result = CheckResult::UNKNOWN;
|
||||
else
|
||||
result = CheckResult::ERROR;
|
||||
@@ -124,10 +128,46 @@ void CHCSmtLib2Interface::declareVariable(string const& _name, SortPointer const
|
||||
else if (!m_variables.count(_name))
|
||||
{
|
||||
m_variables.insert(_name);
|
||||
write("(declare-var |" + _name + "| " + m_smtlib2->toSmtLibSort(*_sort) + ')');
|
||||
write("(declare-var |" + _name + "| " + toSmtLibSort(*_sort) + ')');
|
||||
}
|
||||
}
|
||||
|
||||
string CHCSmtLib2Interface::toSmtLibSort(Sort const& _sort)
|
||||
{
|
||||
if (!m_sortNames.count(&_sort))
|
||||
m_sortNames[&_sort] = m_smtlib2->toSmtLibSort(_sort);
|
||||
return m_sortNames.at(&_sort);
|
||||
}
|
||||
|
||||
string CHCSmtLib2Interface::toSmtLibSort(vector<SortPointer> const& _sorts)
|
||||
{
|
||||
string ssort("(");
|
||||
for (auto const& sort: _sorts)
|
||||
ssort += toSmtLibSort(*sort) + " ";
|
||||
ssort += ")";
|
||||
return ssort;
|
||||
}
|
||||
|
||||
void CHCSmtLib2Interface::writeHeader()
|
||||
{
|
||||
if (m_queryTimeout)
|
||||
write("(set-option :timeout " + to_string(*m_queryTimeout) + ")");
|
||||
write("(set-logic HORN)\n");
|
||||
}
|
||||
|
||||
string CHCSmtLib2Interface::forall()
|
||||
{
|
||||
string vars("(");
|
||||
for (auto const& [name, sort]: m_smtlib2->variables())
|
||||
{
|
||||
solAssert(sort, "");
|
||||
if (sort->kind != Kind::Function)
|
||||
vars += " (" + name + " " + toSmtLibSort(*sort) + ")";
|
||||
}
|
||||
vars += ")";
|
||||
return vars;
|
||||
}
|
||||
|
||||
void CHCSmtLib2Interface::declareFunction(string const& _name, SortPointer const& _sort)
|
||||
{
|
||||
smtAssert(_sort, "");
|
||||
@@ -137,8 +177,8 @@ void CHCSmtLib2Interface::declareFunction(string const& _name, SortPointer const
|
||||
{
|
||||
auto fSort = dynamic_pointer_cast<FunctionSort>(_sort);
|
||||
smtAssert(fSort->codomain, "");
|
||||
string domain = m_smtlib2->toSmtLibSort(fSort->domain);
|
||||
string codomain = m_smtlib2->toSmtLibSort(*fSort->codomain);
|
||||
string domain = toSmtLibSort(fSort->domain);
|
||||
string codomain = toSmtLibSort(*fSort->codomain);
|
||||
m_variables.insert(_name);
|
||||
write(
|
||||
"(declare-fun |" +
|
||||
|
||||
Reference in New Issue
Block a user