Skip to content

Commit 48a1390

Browse files
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 48a1390

File tree

6 files changed

+59
-18
lines changed

6 files changed

+59
-18
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)

src/solvers/smt2/smt2_parser.cpp

Lines changed: 18 additions & 18 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);
@@ -1244,8 +1248,7 @@ void smt2_parsert::setup_commands()
12441248
irep_idt id = smt2_tokenizer.get_buffer();
12451249
auto type = sort();
12461250

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

12511254
// declare-var appears to be a synonym for declare-const that is
@@ -1259,8 +1262,7 @@ void smt2_parsert::setup_commands()
12591262
irep_idt id = smt2_tokenizer.get_buffer();
12601263
auto type = function_signature_declaration();
12611264

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

12661268
commands["define-const"] = [this]() {
@@ -1281,8 +1283,7 @@ void smt2_parsert::setup_commands()
12811283
}
12821284

12831285
// create the entry
1284-
if(add_fresh_id(id, value) != id)
1285-
throw error() << "identifier '" << id << "' defined twice";
1286+
add_unique_id(id, value);
12861287
};
12871288

12881289
commands["define-fun"] = [this]() {
@@ -1319,8 +1320,7 @@ void smt2_parsert::setup_commands()
13191320
}
13201321

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

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