Skip to content

Commit e7fc79a

Browse files
author
Daniel Kroening
authored
Merge pull request #5158 from diffblue/smt2_function_scoping_test
SMT-LIB2 parameter/let/quantifier scopes
2 parents 835af93 + 6eabb66 commit e7fc79a

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);
@@ -258,12 +262,16 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
258262
if(next_token() != smt2_tokenizert::CLOSE)
259263
throw error("expected ')' at end of bindings");
260264

261-
// go forwards, add to id_map
262-
for(const auto &b : bindings)
265+
// save the renaming map
266+
renaming_mapt old_renaming_map = renaming_map;
267+
268+
// go forwards, add to id_map, renaming if need be
269+
for(auto &b : bindings)
263270
{
264271
const irep_idt id =
265272
add_fresh_id(b.get_identifier(), exprt(ID_nil, b.type()));
266-
CHECK_RETURN(id == b.get_identifier());
273+
274+
b.set_identifier(id);
267275
}
268276

269277
exprt expr=expression();
@@ -277,6 +285,9 @@ exprt smt2_parsert::quantifier_expression(irep_idt id)
277285
for(const auto &b : bindings)
278286
id_map.erase(b.get_identifier());
279287

288+
// restore renaming map
289+
renaming_map = old_renaming_map;
290+
280291
// go backwards, build quantified expression
281292
for(auto r_it=bindings.rbegin(); r_it!=bindings.rend(); r_it++)
282293
{
@@ -1241,8 +1252,7 @@ void smt2_parsert::setup_commands()
12411252
irep_idt id = smt2_tokenizer.get_buffer();
12421253
auto type = sort();
12431254

1244-
if(add_fresh_id(id, exprt(ID_nil, type)) != id)
1245-
throw error() << "identifier '" << id << "' defined twice";
1255+
add_unique_id(id, exprt(ID_nil, type));
12461256
};
12471257

12481258
// declare-var appears to be a synonym for declare-const that is
@@ -1256,8 +1266,7 @@ void smt2_parsert::setup_commands()
12561266
irep_idt id = smt2_tokenizer.get_buffer();
12571267
auto type = function_signature_declaration();
12581268

1259-
if(add_fresh_id(id, exprt(ID_nil, type)) != id)
1260-
throw error() << "identifier '" << id << "' defined twice";
1269+
add_unique_id(id, exprt(ID_nil, type));
12611270
};
12621271

12631272
commands["define-const"] = [this]() {
@@ -1278,8 +1287,7 @@ void smt2_parsert::setup_commands()
12781287
}
12791288

12801289
// create the entry
1281-
if(add_fresh_id(id, value) != id)
1282-
throw error() << "identifier '" << id << "' defined twice";
1290+
add_unique_id(id, value);
12831291
};
12841292

12851293
commands["define-fun"] = [this]() {
@@ -1316,8 +1324,7 @@ void smt2_parsert::setup_commands()
13161324
}
13171325

13181326
// create the entry
1319-
if(add_fresh_id(id, body) != id)
1320-
throw error() << "identifier '" << id << "' defined twice";
1327+
add_unique_id(id, body);
13211328

13221329
id_map.at(id).type = signature.type;
13231330
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)