@@ -43,20 +43,53 @@ bool has_symbol(
43
43
static bool find_symbols (
44
44
symbol_kindt,
45
45
const typet &,
46
- std::function<bool (const symbol_exprt &)>);
46
+ std::function<bool (const symbol_exprt &)>,
47
+ std::unordered_set<irep_idt> &bindings);
47
48
48
49
static bool find_symbols (
49
50
symbol_kindt kind,
50
51
const exprt &src,
51
- std::function<bool (const symbol_exprt &)> op)
52
+ std::function<bool (const symbol_exprt &)> op,
53
+ std::unordered_set<irep_idt> &bindings)
52
54
{
55
+ if (kind == symbol_kindt::F_EXPR_NOT_BOUND)
56
+ {
57
+ if (src.id () == ID_forall || src.id () == ID_exists || src.id () == ID_lambda)
58
+ {
59
+ const auto &binding_expr = to_binding_expr (src);
60
+ std::unordered_set<irep_idt> new_bindings{bindings};
61
+ for (const auto &v : binding_expr.variables ())
62
+ new_bindings.insert (v.get_identifier ());
63
+
64
+ if (!find_symbols (kind, binding_expr.where (), op, new_bindings))
65
+ return false ;
66
+
67
+ return find_symbols (kind, binding_expr.type (), op, bindings);
68
+ }
69
+ else if (src.id () == ID_let)
70
+ {
71
+ const auto &let_expr = to_let_expr (src);
72
+ std::unordered_set<irep_idt> new_bindings{bindings};
73
+ for (const auto &v : let_expr.variables ())
74
+ new_bindings.insert (v.get_identifier ());
75
+
76
+ if (!find_symbols (kind, let_expr.where (), op, new_bindings))
77
+ return false ;
78
+
79
+ if (!find_symbols (kind, let_expr.op1 (), op, new_bindings))
80
+ return false ;
81
+
82
+ return find_symbols (kind, let_expr.type (), op, bindings);
83
+ }
84
+ }
85
+
53
86
forall_operands (it, src)
54
87
{
55
- if (!find_symbols (kind, *it, op))
88
+ if (!find_symbols (kind, *it, op, bindings ))
56
89
return false ;
57
90
}
58
91
59
- if (!find_symbols (kind, src.type (), op))
92
+ if (!find_symbols (kind, src.type (), op, bindings ))
60
93
return false ;
61
94
62
95
if (
@@ -83,7 +116,8 @@ static bool find_symbols(
83
116
84
117
if (
85
118
c_sizeof_type.is_not_nil () &&
86
- !find_symbols (kind, static_cast <const typet &>(c_sizeof_type), op))
119
+ !find_symbols (
120
+ kind, static_cast <const typet &>(c_sizeof_type), op, bindings))
87
121
{
88
122
return false ;
89
123
}
@@ -92,7 +126,7 @@ static bool find_symbols(
92
126
93
127
if (
94
128
va_arg_type.is_not_nil () &&
95
- !find_symbols (kind, static_cast <const typet &>(va_arg_type), op))
129
+ !find_symbols (kind, static_cast <const typet &>(va_arg_type), op, bindings ))
96
130
{
97
131
return false ;
98
132
}
@@ -103,20 +137,21 @@ static bool find_symbols(
103
137
static bool find_symbols (
104
138
symbol_kindt kind,
105
139
const typet &src,
106
- std::function<bool (const symbol_exprt &)> op)
140
+ std::function<bool (const symbol_exprt &)> op,
141
+ std::unordered_set<irep_idt> &bindings)
107
142
{
108
143
if (kind != symbol_kindt::F_TYPE_NON_PTR || src.id () != ID_pointer)
109
144
{
110
145
if (
111
146
src.has_subtype () &&
112
- !find_symbols (kind, to_type_with_subtype (src).subtype (), op))
147
+ !find_symbols (kind, to_type_with_subtype (src).subtype (), op, bindings ))
113
148
{
114
149
return false ;
115
150
}
116
151
117
152
for (const typet &subtype : to_type_with_subtypes (src).subtypes ())
118
153
{
119
- if (!find_symbols (kind, subtype, op))
154
+ if (!find_symbols (kind, subtype, op, bindings ))
120
155
return false ;
121
156
}
122
157
@@ -137,26 +172,26 @@ static bool find_symbols(
137
172
138
173
for (const auto &c : struct_union_type.components ())
139
174
{
140
- if (!find_symbols (kind, c, op))
175
+ if (!find_symbols (kind, c, op, bindings ))
141
176
return false ;
142
177
}
143
178
}
144
179
else if (src.id ()==ID_code)
145
180
{
146
181
const code_typet &code_type=to_code_type (src);
147
- if (!find_symbols (kind, code_type.return_type (), op))
182
+ if (!find_symbols (kind, code_type.return_type (), op, bindings ))
148
183
return false ;
149
184
150
185
for (const auto &p : code_type.parameters ())
151
186
{
152
- if (!find_symbols (kind, p, op))
187
+ if (!find_symbols (kind, p, op, bindings ))
153
188
return false ;
154
189
}
155
190
}
156
191
else if (src.id ()==ID_array)
157
192
{
158
193
// do the size -- the subtype is already done
159
- if (!find_symbols (kind, to_array_type (src).size (), op))
194
+ if (!find_symbols (kind, to_array_type (src).size (), op, bindings ))
160
195
return false ;
161
196
}
162
197
else if (
@@ -183,6 +218,24 @@ static bool find_symbols(
183
218
return true ;
184
219
}
185
220
221
+ static bool find_symbols (
222
+ symbol_kindt kind,
223
+ const typet &type,
224
+ std::function<bool (const symbol_exprt &)> op)
225
+ {
226
+ std::unordered_set<irep_idt> bindings;
227
+ return find_symbols (kind, type, op, bindings);
228
+ }
229
+
230
+ static bool find_symbols (
231
+ symbol_kindt kind,
232
+ const exprt &src,
233
+ std::function<bool (const symbol_exprt &)> op)
234
+ {
235
+ std::unordered_set<irep_idt> bindings;
236
+ return find_symbols (kind, src, op, bindings);
237
+ }
238
+
186
239
void find_symbols (const exprt &src, std::set<symbol_exprt> &dest)
187
240
{
188
241
find_symbols (
0 commit comments