Skip to content

Commit fa1f769

Browse files
committed
Fixed SMT encoding of array_of_exprt
Instead of using quantifers to encode array_of expressions -- which, as indicated in the comments, doesn't seem to work on existing solvers -- we can use the `as const` construct for CVC4 and Z3.
1 parent f899754 commit fa1f769

File tree

2 files changed

+44
-25
lines changed

2 files changed

+44
-25
lines changed

src/solvers/smt2/smt2_conv.cpp

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ smt2_convt::smt2_convt(
5353
const std::string &_logic,
5454
solvert _solver,
5555
std::ostream &_out)
56-
: use_FPA_theory(false),
56+
: use_as_const(false),
57+
use_FPA_theory(false),
5758
use_datatypes(false),
5859
use_array_of_bool(false),
5960
emit_set_logic(true),
@@ -87,6 +88,7 @@ smt2_convt::smt2_convt(
8788
break;
8889

8990
case solvert::CVC4:
91+
use_as_const = true;
9092
break;
9193

9294
case solvert::MATHSAT:
@@ -96,6 +98,7 @@ smt2_convt::smt2_convt(
9698
break;
9799

98100
case solvert::Z3:
101+
use_as_const = true;
99102
use_array_of_bool = true;
100103
emit_set_logic = false;
101104
use_datatypes = true;
@@ -1276,18 +1279,29 @@ void smt2_convt::convert_expr(const exprt &expr)
12761279
convert_address_of_rec(
12771280
address_of_expr.object(), to_pointer_type(address_of_expr.type()));
12781281
}
1279-
else if(expr.id()==ID_array_of)
1282+
else if(expr.id() == ID_array_of)
12801283
{
1281-
const array_of_exprt &array_of_expr = to_array_of_expr(expr);
1284+
const auto &array_of_expr = to_array_of_expr(expr);
12821285

12831286
DATA_INVARIANT(
12841287
array_of_expr.type().id() == ID_array,
12851288
"array of expression shall have array type");
12861289

1287-
defined_expressionst::const_iterator it =
1288-
defined_expressions.find(array_of_expr);
1289-
CHECK_RETURN(it != defined_expressions.end());
1290-
out << it->second;
1290+
if(use_as_const)
1291+
{
1292+
out << "((as const ";
1293+
convert_type(array_of_expr.type());
1294+
out << ") ";
1295+
convert_expr(array_of_expr.what());
1296+
out << ")";
1297+
}
1298+
else
1299+
{
1300+
defined_expressionst::const_iterator it =
1301+
defined_expressions.find(array_of_expr);
1302+
CHECK_RETURN(it != defined_expressions.end());
1303+
out << it->second;
1304+
}
12911305
}
12921306
else if(expr.id()==ID_index)
12931307
{
@@ -4367,27 +4381,31 @@ void smt2_convt::find_symbols(const exprt &expr)
43674381
out << ")" << "\n";
43684382
}
43694383
}
4370-
else if(expr.id()==ID_array_of)
4384+
else if(expr.id() == ID_array_of)
43714385
{
4372-
if(defined_expressions.find(expr)==defined_expressions.end())
4386+
if(!use_as_const)
43734387
{
4374-
const irep_idt id =
4375-
"array_of." + std::to_string(defined_expressions.size());
4376-
out << "; the following is a substitute for lambda i. x" << "\n";
4377-
out << "(declare-fun " << id << " () ";
4378-
convert_type(expr.type());
4379-
out << ")" << "\n";
4380-
4381-
// use a quantifier instead of the lambda
4382-
#if 0 // not really working in any solver yet!
4383-
out << "(assert (forall ((i ";
4384-
convert_type(array_index_type());
4385-
out << ")) (= (select " << id << " i) ";
4386-
convert_expr(expr.op0());
4387-
out << ")))" << "\n";
4388-
#endif
4388+
if(defined_expressions.find(expr) == defined_expressions.end())
4389+
{
4390+
const auto &array_of = to_array_of_expr(expr);
43894391

4390-
defined_expressions[expr]=id;
4392+
const irep_idt id =
4393+
"array_of." + std::to_string(defined_expressions.size());
4394+
out << "; the following is a substitute for lambda i. x\n";
4395+
out << "(declare-fun " << id << " () ";
4396+
convert_type(array_of.type());
4397+
out << ")\n";
4398+
4399+
// use a quantifier instead of the lambda
4400+
// may not work with existing solver, but is a sound translation
4401+
out << "(assert (forall ((i ";
4402+
convert_type(array_of.type().size().type());
4403+
out << ")) (= (select " << id << " i) ";
4404+
convert_expr(array_of.what());
4405+
out << ")))\n";
4406+
4407+
defined_expressions[expr] = id;
4408+
}
43914409
}
43924410
}
43934411
else if(expr.id()==ID_array)

src/solvers/smt2/smt2_conv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class smt2_convt : public stack_decision_proceduret
5858

5959
~smt2_convt() override = default;
6060

61+
bool use_as_const;
6162
bool use_FPA_theory;
6263
bool use_datatypes;
6364
bool use_array_of_bool;

0 commit comments

Comments
 (0)