Skip to content

Commit cace2ce

Browse files
committed
smt2: convert mathematical_function types and function_application
This change enables the SMT-LIB2 backend to convert 1) function symbols with type mathematical function and 2) applications of such functions given as function_application expression. This enables a number of use cases, e.g., encodings of programs into constrained Horn clause systems.
1 parent dbc5d5d commit cace2ce

File tree

3 files changed

+99
-11
lines changed

3 files changed

+99
-11
lines changed

regression/cbmc/uninterpreted_function/uf1.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
uf1.c
33

44
^EXIT=10$

regression/cbmc/uninterpreted_function/uf2.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
uf2.c
33

44
^EXIT=0$

src/solvers/smt2/smt2_conv.cpp

+97-9
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,26 @@ void smt2_convt::convert_expr(const exprt &expr)
21382138
{
21392139
convert_expr(simplify_expr(to_bitreverse_expr(expr).lower(), ns));
21402140
}
2141+
else if(expr.id() == ID_function_application)
2142+
{
2143+
const auto &function_application_expr = to_function_application_expr(expr);
2144+
// do not use parentheses if there function is a constant
2145+
if(function_application_expr.arguments().empty())
2146+
{
2147+
convert_expr(function_application_expr.function());
2148+
}
2149+
else
2150+
{
2151+
out << '(';
2152+
convert_expr(function_application_expr.function());
2153+
for(auto &op : function_application_expr.arguments())
2154+
{
2155+
out << ' ';
2156+
convert_expr(op);
2157+
}
2158+
out << ')';
2159+
}
2160+
}
21412161
else
21422162
INVARIANT_WITH_DIAGNOSTICS(
21432163
false,
@@ -4468,13 +4488,49 @@ void smt2_convt::set_to(const exprt &expr, bool value)
44684488
smt2_identifiers.insert(smt2_identifier);
44694489

44704490
out << "; set_to true (equal)\n";
4471-
out << "(define-fun |" << smt2_identifier << "| () ";
4491+
out << "(define-fun |" << smt2_identifier << '|';
44724492

4473-
convert_type(equal_expr.lhs().type());
4474-
out << " ";
4475-
convert_expr(prepared_rhs);
4493+
if(equal_expr.lhs().type().id() == ID_mathematical_function)
4494+
{
4495+
auto &mathematical_function_type =
4496+
to_mathematical_function_type(equal_expr.lhs().type());
4497+
out << " (";
4498+
bool first = true;
4499+
4500+
for(std::size_t p_nr = 0;
4501+
p_nr < mathematical_function_type.domain().size();
4502+
p_nr++)
4503+
{
4504+
if(first)
4505+
first = false;
4506+
else
4507+
out << ' ';
4508+
4509+
out << '(' << 'p' << (p_nr + 1) << ' ';
4510+
convert_type(mathematical_function_type.domain()[p_nr]);
4511+
out << ')';
4512+
}
44764513

4477-
out << ")" << "\n";
4514+
out << ") ";
4515+
convert_type(mathematical_function_type.codomain());
4516+
4517+
out << ' ' << '(';
4518+
convert_expr(prepared_rhs);
4519+
for(std::size_t p_nr = 0;
4520+
p_nr < mathematical_function_type.domain().size();
4521+
p_nr++)
4522+
out << ' ' << 'p' << (p_nr + 1);
4523+
out << ')';
4524+
}
4525+
else
4526+
{
4527+
out << " () ";
4528+
convert_type(equal_expr.lhs().type());
4529+
out << ' ';
4530+
convert_expr(prepared_rhs);
4531+
}
4532+
4533+
out << ')' << '\n';
44784534
return; // done
44794535
}
44804536
}
@@ -4616,10 +4672,33 @@ void smt2_convt::find_symbols(const exprt &expr)
46164672
smt2_identifiers.insert(smt2_identifier);
46174673

46184674
out << "; find_symbols\n";
4619-
out << "(declare-fun |"
4620-
<< smt2_identifier
4621-
<< "| () ";
4622-
convert_type(expr.type());
4675+
out << "(declare-fun |" << smt2_identifier << '|';
4676+
4677+
if(expr.type().id() == ID_mathematical_function)
4678+
{
4679+
auto &mathematical_function_type =
4680+
to_mathematical_function_type(expr.type());
4681+
out << " (";
4682+
bool first = true;
4683+
4684+
for(auto &type : mathematical_function_type.domain())
4685+
{
4686+
if(first)
4687+
first = false;
4688+
else
4689+
out << ' ';
4690+
convert_type(type);
4691+
}
4692+
4693+
out << ") ";
4694+
convert_type(mathematical_function_type.codomain());
4695+
}
4696+
else
4697+
{
4698+
out << " () ";
4699+
convert_type(expr.type());
4700+
}
4701+
46234702
out << ")" << "\n";
46244703
}
46254704
}
@@ -5218,6 +5297,15 @@ void smt2_convt::find_symbols_rec(
52185297
find_symbols_rec(ns.follow_tag(union_tag), recstack);
52195298
}
52205299
}
5300+
else if(type.id() == ID_mathematical_function)
5301+
{
5302+
const auto &mathematical_function_type =
5303+
to_mathematical_function_type(type);
5304+
for(auto &d_type : mathematical_function_type.domain())
5305+
find_symbols_rec(d_type, recstack);
5306+
5307+
find_symbols_rec(mathematical_function_type.codomain(), recstack);
5308+
}
52215309
}
52225310

52235311
std::size_t smt2_convt::get_number_of_solver_calls() const

0 commit comments

Comments
 (0)