Skip to content

Commit cee5acf

Browse files
authored
Merge pull request #5973 from padhi-aws-forks/smt2_array_comprehension
Fix SMT encoding of `array_comprehension_exprt`
2 parents e42cc6c + c499ff7 commit cee5acf

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
CORE broken-smt-backend
1+
CORE broken-cprover-smt-backend
22
main.c
33

44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$
77
--
88
^warning: ignoring
9+
--
10+
This test currently does not pass with CPROVER SMT2 backend
11+
because the solver does not fully support quantified expressions.

src/solvers/smt2/smt2_conv.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ smt2_convt::smt2_convt(
5757
use_as_const(false),
5858
use_datatypes(false),
5959
use_array_of_bool(false),
60+
use_lambda_for_array(false),
6061
emit_set_logic(true),
6162
ns(_ns),
6263
out(_out),
@@ -101,6 +102,7 @@ smt2_convt::smt2_convt(
101102
case solvert::Z3:
102103
use_as_const = true;
103104
use_array_of_bool = true;
105+
use_lambda_for_array = true;
104106
emit_set_logic = false;
105107
use_datatypes = true;
106108
break;
@@ -1304,6 +1306,31 @@ void smt2_convt::convert_expr(const exprt &expr)
13041306
out << it->second;
13051307
}
13061308
}
1309+
else if(expr.id() == ID_array_comprehension)
1310+
{
1311+
const auto &array_comprehension = to_array_comprehension_expr(expr);
1312+
1313+
DATA_INVARIANT(
1314+
array_comprehension.type().id() == ID_array,
1315+
"array_comprehension expression shall have array type");
1316+
1317+
if(use_lambda_for_array)
1318+
{
1319+
out << "(lambda ((";
1320+
convert_expr(array_comprehension.arg());
1321+
out << " ";
1322+
convert_type(array_comprehension.type().size().type());
1323+
out << ")) ";
1324+
convert_expr(array_comprehension.body());
1325+
out << ")";
1326+
}
1327+
else
1328+
{
1329+
const auto &it = defined_expressions.find(array_comprehension);
1330+
CHECK_RETURN(it != defined_expressions.end());
1331+
out << it->second;
1332+
}
1333+
}
13071334
else if(expr.id()==ID_index)
13081335
{
13091336
convert_index(to_index_expr(expr));
@@ -4408,6 +4435,44 @@ void smt2_convt::find_symbols(const exprt &expr)
44084435
}
44094436
}
44104437
}
4438+
else if(expr.id() == ID_array_comprehension)
4439+
{
4440+
if(!use_lambda_for_array)
4441+
{
4442+
if(defined_expressions.find(expr) == defined_expressions.end())
4443+
{
4444+
const auto &array_comprehension = to_array_comprehension_expr(expr);
4445+
const auto &array_size = array_comprehension.type().size();
4446+
4447+
const irep_idt id =
4448+
"array_comprehension." + std::to_string(defined_expressions.size());
4449+
out << "(declare-fun " << id << " () ";
4450+
convert_type(array_comprehension.type());
4451+
out << ")\n";
4452+
4453+
out << "; the following is a substitute for lambda i . x(i)\n";
4454+
out << "; universally quantified initialization of the array\n";
4455+
out << "(assert (forall ((";
4456+
convert_expr(array_comprehension.arg());
4457+
out << " ";
4458+
convert_type(array_size.type());
4459+
out << ")) (=> (and (bvule (_ bv0 " << boolbv_width(array_size.type())
4460+
<< ") ";
4461+
convert_expr(array_comprehension.arg());
4462+
out << ") (bvult ";
4463+
convert_expr(array_comprehension.arg());
4464+
out << " ";
4465+
convert_expr(array_size);
4466+
out << ")) (= (select " << id << " ";
4467+
convert_expr(array_comprehension.arg());
4468+
out << ") ";
4469+
convert_expr(array_comprehension.body());
4470+
out << "))))\n";
4471+
4472+
defined_expressions[expr] = id;
4473+
}
4474+
}
4475+
}
44114476
else if(expr.id()==ID_array)
44124477
{
44134478
if(defined_expressions.find(expr)==defined_expressions.end())

src/solvers/smt2/smt2_conv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class smt2_convt : public stack_decision_proceduret
6262
bool use_as_const;
6363
bool use_datatypes;
6464
bool use_array_of_bool;
65+
bool use_lambda_for_array;
6566
bool emit_set_logic;
6667

6768
exprt handle(const exprt &expr) override;

0 commit comments

Comments
 (0)