Skip to content

Commit 6eabb66

Browse files
author
Daniel Kroening
committed
fix for SMT-LIB2 scopes for function definitions and let
SMT-LIB2 function definitions have scopes for the identifiers of the parameters. The same holds for let expressions. This was raised in #5143. The need to make the scoped identifiers unique will be removed once the IR bindings have scopes.
1 parent db4c76b commit 6eabb66

File tree

8 files changed

+88
-21
lines changed

8 files changed

+88
-21
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
function-scoping1.smt2
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^unsat$
7+
--
8+
^\(error
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(set-logic QF_BV)
2+
3+
; the function parameters are in a separate scope
4+
5+
(define-fun min ((a (_ BitVec 8)) (b (_ BitVec 8))) (_ BitVec 8)
6+
(ite (bvule a b) a b))
7+
8+
(declare-const a (_ BitVec 32))
9+
10+
(assert (not (= a a)))
11+
12+
(check-sat)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
let-scoping1.smt2
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^unsat$
7+
--
8+
^\(error
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(set-logic QF_BV)
2+
3+
; the let parameters are in a separate scope
4+
(define-fun let1 () Bool (let ((a true)) a))
5+
(declare-const a (_ BitVec 32))
6+
(assert (not (= a a)))
7+
8+
; declare-const first
9+
(declare-const b (_ BitVec 32))
10+
(define-fun let2 () Bool (let ((b true)) b))
11+
12+
(check-sat)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
quantifier-scoping.smt2
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^unsat$
7+
--
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(set-logic QF_BV)
2+
3+
; the quantified identifiers are in a separate scope
4+
(define-fun q1 () Bool (exists ((a Bool)) a))
5+
(declare-const a (_ BitVec 32))
6+
(assert (not (= a a)))
7+
8+
; declare-const first
9+
(declare-const b (_ BitVec 32))
10+
(define-fun q2 () Bool (exists ((b Bool)) b))
11+
12+
(check-sat)

src/solvers/smt2/smt2_parser.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,6 @@ exprt::operandst smt2_parsert::operands()
130130

131131
irep_idt smt2_parsert::add_fresh_id(const irep_idt &id, const exprt &expr)
132132
{
133-
if(id_map
134-
.emplace(
135-
std::piecewise_construct,
136-
std::forward_as_tuple(id),
137-
std::forward_as_tuple(expr))
138-
.second)
139-
{
140-
return id; // id not yet used
141-
}
142-
143133
auto &count=renaming_counters[id];
144134
irep_idt new_id;
145135
do
@@ -159,6 +149,20 @@ irep_idt smt2_parsert::add_fresh_id(const irep_idt &id, const exprt &expr)
159149
return new_id;
160150
}
161151

152+
void smt2_parsert::add_unique_id(const irep_idt &id, const exprt &expr)
153+
{
154+
if(!id_map
155+
.emplace(
156+
std::piecewise_construct,
157+
std::forward_as_tuple(id),
158+
std::forward_as_tuple(expr))
159+
.second)
160+
{
161+
// id already used
162+
throw error() << "identifier '" << id << "' defined twice";
163+
}
164+
}
165+
162166
irep_idt smt2_parsert::rename_id(const irep_idt &id) const
163167
{
164168
auto it=renaming_map.find(id);
@@ -261,12 +265,16 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
261265
if(next_token() != smt2_tokenizert::CLOSE)
262266
throw error("expected ')' at end of bindings");
263267

264-
// go forwards, add to id_map
265-
for(const auto &b : bindings)
268+
// save the renaming map
269+
renaming_mapt old_renaming_map = renaming_map;
270+
271+
// go forwards, add to id_map, renaming if need be
272+
for(auto &b : bindings)
266273
{
267274
const irep_idt id =
268275
add_fresh_id(b.get_identifier(), exprt(ID_nil, b.type()));
269-
CHECK_RETURN(id == b.get_identifier());
276+
277+
b.set_identifier(id);
270278
}
271279

272280
exprt expr=expression();
@@ -280,6 +288,9 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
280288
for(const auto &b : bindings)
281289
id_map.erase(b.get_identifier());
282290

291+
// restore renaming map
292+
renaming_map = old_renaming_map;
293+
283294
// go backwards, build quantified expression
284295
for(auto r_it=bindings.rbegin(); r_it!=bindings.rend(); r_it++)
285296
{
@@ -1244,8 +1255,7 @@ void smt2_parsert::setup_commands()
12441255
irep_idt id = smt2_tokenizer.get_buffer();
12451256
auto type = sort();
12461257

1247-
if(add_fresh_id(id, exprt(ID_nil, type)) != id)
1248-
throw error() << "identifier '" << id << "' defined twice";
1258+
add_unique_id(id, exprt(ID_nil, type));
12491259
};
12501260

12511261
// declare-var appears to be a synonym for declare-const that is
@@ -1259,8 +1269,7 @@ void smt2_parsert::setup_commands()
12591269
irep_idt id = smt2_tokenizer.get_buffer();
12601270
auto type = function_signature_declaration();
12611271

1262-
if(add_fresh_id(id, exprt(ID_nil, type)) != id)
1263-
throw error() << "identifier '" << id << "' defined twice";
1272+
add_unique_id(id, exprt(ID_nil, type));
12641273
};
12651274

12661275
commands["define-const"] = [this]() {
@@ -1281,8 +1290,7 @@ void smt2_parsert::setup_commands()
12811290
}
12821291

12831292
// create the entry
1284-
if(add_fresh_id(id, value) != id)
1285-
throw error() << "identifier '" << id << "' defined twice";
1293+
add_unique_id(id, value);
12861294
};
12871295

12881296
commands["define-fun"] = [this]() {
@@ -1319,8 +1327,7 @@ void smt2_parsert::setup_commands()
13191327
}
13201328

13211329
// create the entry
1322-
if(add_fresh_id(id, body) != id)
1323-
throw error() << "identifier '" << id << "' defined twice";
1330+
add_unique_id(id, body);
13241331

13251332
id_map.at(id).type = signature.type;
13261333
id_map.at(id).parameters = signature.parameters;

src/solvers/smt2/smt2_parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class smt2_parsert
9090
using renaming_counterst=std::map<irep_idt, unsigned>;
9191
renaming_counterst renaming_counters;
9292
irep_idt add_fresh_id(const irep_idt &, const exprt &);
93+
void add_unique_id(const irep_idt &, const exprt &);
9394
irep_idt rename_id(const irep_idt &) const;
9495

9596
struct signature_with_parameter_idst

0 commit comments

Comments
 (0)