Skip to content

Commit e46d2f3

Browse files
committed
replace_symbolt now knows bindings
This makes replace_symbolt aware of bound symbols, which may hide the symbols that are being replaced.
1 parent f21971d commit e46d2f3

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

src/util/replace_symbol.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,41 @@ bool replace_symbolt::replace(exprt &dest) const
101101
if(!replace_symbol_expr(to_symbol_expr(dest)))
102102
return false;
103103
}
104+
else if(dest.id() == ID_let)
105+
{
106+
auto &let_expr = to_let_expr(dest);
107+
108+
// first replace the assigned value expressions
109+
for(auto &op : let_expr.values())
110+
if(replace(op))
111+
result = false;
112+
113+
// now set up the binding
114+
auto old_bindings = bindings;
115+
for(auto &variable : let_expr.variables())
116+
bindings.insert(variable.get_identifier());
117+
118+
// now replace in the 'where' expression
119+
if(!replace(let_expr.where()))
120+
result = false;
121+
122+
bindings = std::move(old_bindings);
123+
}
124+
else if(
125+
dest.id() == ID_array_comprehension || dest.id() == ID_exists ||
126+
dest.id() == ID_forall || dest.id() == ID_lambda)
127+
{
128+
auto &binding_expr = to_binding_expr(dest);
129+
130+
auto old_bindings = bindings;
131+
for(auto &binding : binding_expr.variables())
132+
bindings.insert(binding.get_identifier());
133+
134+
if(!replace(binding_expr.where()))
135+
result = false;
136+
137+
bindings = std::move(old_bindings);
138+
}
104139
else
105140
{
106141
Forall_operands(it, dest)
@@ -136,7 +171,10 @@ bool replace_symbolt::have_to_replace(const exprt &dest) const
136171
if(dest.id()==ID_symbol)
137172
{
138173
const irep_idt &identifier = to_symbol_expr(dest).get_identifier();
139-
return replaces_symbol(identifier);
174+
if(bindings.find(identifier) != bindings.end())
175+
return false;
176+
else
177+
return replaces_symbol(identifier);
140178
}
141179

142180
forall_operands(it, dest)

src/util/replace_symbol.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ Author: Daniel Kroening, [email protected]
1717

1818
#include "expr.h"
1919

20+
#include <set>
2021
#include <unordered_map>
2122

22-
/// Replace expression or type symbols by an expression or type, respectively.
23-
/// The resolved type of the symbol must match the type of the replacement.
23+
/// Replace a symbol expression by a given expression.
24+
/// The type of the symbol must match the type of the replacement.
25+
/// This class is aware of symbol hiding caused by bindings
26+
/// such as forall, exists, and the like.
2427
class replace_symbolt
2528
{
2629
public:
@@ -88,6 +91,7 @@ class replace_symbolt
8891

8992
protected:
9093
expr_mapt expr_map;
94+
mutable std::set<irep_idt> bindings;
9195

9296
virtual bool replace_symbol_expr(symbol_exprt &dest) const;
9397

0 commit comments

Comments
 (0)