@@ -43,20 +43,53 @@ bool has_symbol(
4343static bool find_symbols (
4444 symbol_kindt,
4545 const typet &,
46- std::function<bool (const symbol_exprt &)>);
46+ std::function<bool (const symbol_exprt &)>,
47+ std::unordered_set<irep_idt> &bindings);
4748
4849static bool find_symbols (
4950 symbol_kindt kind,
5051 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)
5254{
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+
5386 forall_operands (it, src)
5487 {
55- if (!find_symbols (kind, *it, op))
88+ if (!find_symbols (kind, *it, op, bindings ))
5689 return false ;
5790 }
5891
59- if (!find_symbols (kind, src.type (), op))
92+ if (!find_symbols (kind, src.type (), op, bindings ))
6093 return false ;
6194
6295 if (
@@ -83,7 +116,8 @@ static bool find_symbols(
83116
84117 if (
85118 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))
87121 {
88122 return false ;
89123 }
@@ -92,7 +126,7 @@ static bool find_symbols(
92126
93127 if (
94128 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 ))
96130 {
97131 return false ;
98132 }
@@ -103,20 +137,21 @@ static bool find_symbols(
103137static bool find_symbols (
104138 symbol_kindt kind,
105139 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)
107142{
108143 if (kind != symbol_kindt::F_TYPE_NON_PTR || src.id () != ID_pointer)
109144 {
110145 if (
111146 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 ))
113148 {
114149 return false ;
115150 }
116151
117152 for (const typet &subtype : to_type_with_subtypes (src).subtypes ())
118153 {
119- if (!find_symbols (kind, subtype, op))
154+ if (!find_symbols (kind, subtype, op, bindings ))
120155 return false ;
121156 }
122157
@@ -137,26 +172,26 @@ static bool find_symbols(
137172
138173 for (const auto &c : struct_union_type.components ())
139174 {
140- if (!find_symbols (kind, c, op))
175+ if (!find_symbols (kind, c, op, bindings ))
141176 return false ;
142177 }
143178 }
144179 else if (src.id ()==ID_code)
145180 {
146181 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 ))
148183 return false ;
149184
150185 for (const auto &p : code_type.parameters ())
151186 {
152- if (!find_symbols (kind, p, op))
187+ if (!find_symbols (kind, p, op, bindings ))
153188 return false ;
154189 }
155190 }
156191 else if (src.id ()==ID_array)
157192 {
158193 // 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 ))
160195 return false ;
161196 }
162197 else if (
@@ -183,6 +218,24 @@ static bool find_symbols(
183218 return true ;
184219}
185220
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+
186239void find_symbols (const exprt &src, std::set<symbol_exprt> &dest)
187240{
188241 find_symbols (
0 commit comments