@@ -23,8 +23,8 @@ enum class symbol_kindt
23
23
F_TYPE_NON_PTR,
24
24
// / Symbol expressions.
25
25
F_EXPR,
26
- // / Symbol expressions, but excluding bindings .
27
- F_EXPR_NOT_BOUND ,
26
+ // / Symbol expressions, but excluding bound variables .
27
+ F_EXPR_FREE ,
28
28
// / All of the above.
29
29
F_ALL
30
30
};
@@ -46,33 +46,77 @@ bool has_symbol(const exprt &src, const find_symbols_sett &symbols)
46
46
static bool find_symbols (
47
47
symbol_kindt,
48
48
const typet &,
49
- std::function<bool (const symbol_exprt &)>);
49
+ std::function<bool (const symbol_exprt &)>,
50
+ std::unordered_set<irep_idt> &bindings);
50
51
51
52
static bool find_symbols (
52
53
symbol_kindt kind,
53
54
const exprt &src,
54
- std::function<bool (const symbol_exprt &)> op)
55
+ std::function<bool (const symbol_exprt &)> op,
56
+ std::unordered_set<irep_idt> &bindings)
55
57
{
58
+ if (kind == symbol_kindt::F_EXPR_FREE)
59
+ {
60
+ if (src.id () == ID_forall || src.id () == ID_exists || src.id () == ID_lambda)
61
+ {
62
+ const auto &binding_expr = to_binding_expr (src);
63
+ std::unordered_set<irep_idt> new_bindings{bindings};
64
+ for (const auto &v : binding_expr.variables ())
65
+ new_bindings.insert (v.get_identifier ());
66
+
67
+ if (!find_symbols (kind, binding_expr.where (), op, new_bindings))
68
+ return false ;
69
+
70
+ return find_symbols (kind, binding_expr.type (), op, bindings);
71
+ }
72
+ else if (src.id () == ID_let)
73
+ {
74
+ const auto &let_expr = to_let_expr (src);
75
+ std::unordered_set<irep_idt> new_bindings{bindings};
76
+ for (const auto &v : let_expr.variables ())
77
+ new_bindings.insert (v.get_identifier ());
78
+
79
+ if (!find_symbols (kind, let_expr.where (), op, new_bindings))
80
+ return false ;
81
+
82
+ if (!find_symbols (kind, let_expr.op1 (), op, new_bindings))
83
+ return false ;
84
+
85
+ return find_symbols (kind, let_expr.type (), op, bindings);
86
+ }
87
+ }
88
+
56
89
forall_operands (it, src)
57
90
{
58
- if (!find_symbols (kind, *it, op))
91
+ if (!find_symbols (kind, *it, op, bindings ))
59
92
return false ;
60
93
}
61
94
62
- if (!find_symbols (kind, src.type (), op))
95
+ if (!find_symbols (kind, src.type (), op, bindings ))
63
96
return false ;
64
97
65
- if (kind == symbol_kindt::F_ALL || kind == symbol_kindt::F_EXPR )
98
+ if (src. id () == ID_symbol )
66
99
{
67
- if (src.id () == ID_symbol && !op (to_symbol_expr (src)))
68
- return false ;
100
+ const symbol_exprt &s = to_symbol_expr (src);
101
+
102
+ if (kind == symbol_kindt::F_ALL || kind == symbol_kindt::F_EXPR)
103
+ {
104
+ if (!op (s))
105
+ return false ;
106
+ }
107
+ else if (kind == symbol_kindt::F_EXPR_FREE)
108
+ {
109
+ if (bindings.find (s.get_identifier ()) == bindings.end () && !op (s))
110
+ return false ;
111
+ }
69
112
}
70
113
71
114
const irept &c_sizeof_type=src.find (ID_C_c_sizeof_type);
72
115
73
116
if (
74
117
c_sizeof_type.is_not_nil () &&
75
- !find_symbols (kind, static_cast <const typet &>(c_sizeof_type), op))
118
+ !find_symbols (
119
+ kind, static_cast <const typet &>(c_sizeof_type), op, bindings))
76
120
{
77
121
return false ;
78
122
}
@@ -81,7 +125,7 @@ static bool find_symbols(
81
125
82
126
if (
83
127
va_arg_type.is_not_nil () &&
84
- !find_symbols (kind, static_cast <const typet &>(va_arg_type), op))
128
+ !find_symbols (kind, static_cast <const typet &>(va_arg_type), op, bindings ))
85
129
{
86
130
return false ;
87
131
}
@@ -92,20 +136,21 @@ static bool find_symbols(
92
136
static bool find_symbols (
93
137
symbol_kindt kind,
94
138
const typet &src,
95
- std::function<bool (const symbol_exprt &)> op)
139
+ std::function<bool (const symbol_exprt &)> op,
140
+ std::unordered_set<irep_idt> &bindings)
96
141
{
97
142
if (kind != symbol_kindt::F_TYPE_NON_PTR || src.id () != ID_pointer)
98
143
{
99
144
if (
100
145
src.has_subtype () &&
101
- !find_symbols (kind, to_type_with_subtype (src).subtype (), op))
146
+ !find_symbols (kind, to_type_with_subtype (src).subtype (), op, bindings ))
102
147
{
103
148
return false ;
104
149
}
105
150
106
151
for (const typet &subtype : to_type_with_subtypes (src).subtypes ())
107
152
{
108
- if (!find_symbols (kind, subtype, op))
153
+ if (!find_symbols (kind, subtype, op, bindings ))
109
154
return false ;
110
155
}
111
156
@@ -126,26 +171,26 @@ static bool find_symbols(
126
171
127
172
for (const auto &c : struct_union_type.components ())
128
173
{
129
- if (!find_symbols (kind, c, op))
174
+ if (!find_symbols (kind, c, op, bindings ))
130
175
return false ;
131
176
}
132
177
}
133
178
else if (src.id ()==ID_code)
134
179
{
135
180
const code_typet &code_type=to_code_type (src);
136
- if (!find_symbols (kind, code_type.return_type (), op))
181
+ if (!find_symbols (kind, code_type.return_type (), op, bindings ))
137
182
return false ;
138
183
139
184
for (const auto &p : code_type.parameters ())
140
185
{
141
- if (!find_symbols (kind, p, op))
186
+ if (!find_symbols (kind, p, op, bindings ))
142
187
return false ;
143
188
}
144
189
}
145
190
else if (src.id ()==ID_array)
146
191
{
147
192
// do the size -- the subtype is already done
148
- if (!find_symbols (kind, to_array_type (src).size (), op))
193
+ if (!find_symbols (kind, to_array_type (src).size (), op, bindings ))
149
194
return false ;
150
195
}
151
196
else if (
@@ -172,6 +217,24 @@ static bool find_symbols(
172
217
return true ;
173
218
}
174
219
220
+ static bool find_symbols (
221
+ symbol_kindt kind,
222
+ const typet &type,
223
+ std::function<bool (const symbol_exprt &)> op)
224
+ {
225
+ std::unordered_set<irep_idt> bindings;
226
+ return find_symbols (kind, type, op, bindings);
227
+ }
228
+
229
+ static bool find_symbols (
230
+ symbol_kindt kind,
231
+ const exprt &src,
232
+ std::function<bool (const symbol_exprt &)> op)
233
+ {
234
+ std::unordered_set<irep_idt> bindings;
235
+ return find_symbols (kind, src, op, bindings);
236
+ }
237
+
175
238
void find_symbols (const exprt &src, std::set<symbol_exprt> &dest)
176
239
{
177
240
find_symbols (symbol_kindt::F_EXPR, src, [&dest](const symbol_exprt &e) {
@@ -180,11 +243,17 @@ void find_symbols(const exprt &src, std::set<symbol_exprt> &dest)
180
243
});
181
244
}
182
245
183
- bool has_symbol_expr (const exprt &src, const irep_idt &identifier)
246
+ bool has_symbol_expr (
247
+ const exprt &src,
248
+ const irep_idt &identifier,
249
+ bool include_bound_symbols)
184
250
{
185
- return !find_symbols (symbol_kindt::F_EXPR, src, [&identifier](const symbol_exprt &e) {
186
- return e.get_identifier () != identifier;
187
- });
251
+ return !find_symbols (
252
+ include_bound_symbols ? symbol_kindt::F_EXPR : symbol_kindt::F_EXPR_FREE,
253
+ src,
254
+ [&identifier](const symbol_exprt &e) {
255
+ return e.get_identifier () != identifier;
256
+ });
188
257
}
189
258
190
259
void find_type_symbols (const exprt &src, find_symbols_sett &dest)
0 commit comments