@@ -46,33 +46,77 @@ bool has_symbol(const exprt &src, const find_symbols_sett &symbols)
4646static bool find_symbols (
4747 symbol_kindt,
4848 const typet &,
49- std::function<bool (const symbol_exprt &)>);
49+ std::function<bool (const symbol_exprt &)>,
50+ std::unordered_set<irep_idt> &bindings);
5051
5152static bool find_symbols (
5253 symbol_kindt kind,
5354 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)
5557{
58+ if (kind == symbol_kindt::F_EXPR_NOT_BOUND)
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+
5689 forall_operands (it, src)
5790 {
58- if (!find_symbols (kind, *it, op))
91+ if (!find_symbols (kind, *it, op, bindings ))
5992 return false ;
6093 }
6194
62- if (!find_symbols (kind, src.type (), op))
95+ if (!find_symbols (kind, src.type (), op, bindings ))
6396 return false ;
6497
65- if (kind == symbol_kindt::F_ALL || kind == symbol_kindt::F_EXPR )
98+ if (src. id () == ID_symbol )
6699 {
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_NOT_BOUND)
108+ {
109+ if (bindings.find (s.get_identifier ()) == bindings.end () && !op (s))
110+ return false ;
111+ }
69112 }
70113
71114 const irept &c_sizeof_type=src.find (ID_C_c_sizeof_type);
72115
73116 if (
74117 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))
76120 {
77121 return false ;
78122 }
@@ -81,7 +125,7 @@ static bool find_symbols(
81125
82126 if (
83127 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 ))
85129 {
86130 return false ;
87131 }
@@ -92,20 +136,21 @@ static bool find_symbols(
92136static bool find_symbols (
93137 symbol_kindt kind,
94138 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)
96141{
97142 if (kind != symbol_kindt::F_TYPE_NON_PTR || src.id () != ID_pointer)
98143 {
99144 if (
100145 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 ))
102147 {
103148 return false ;
104149 }
105150
106151 for (const typet &subtype : to_type_with_subtypes (src).subtypes ())
107152 {
108- if (!find_symbols (kind, subtype, op))
153+ if (!find_symbols (kind, subtype, op, bindings ))
109154 return false ;
110155 }
111156
@@ -126,26 +171,26 @@ static bool find_symbols(
126171
127172 for (const auto &c : struct_union_type.components ())
128173 {
129- if (!find_symbols (kind, c, op))
174+ if (!find_symbols (kind, c, op, bindings ))
130175 return false ;
131176 }
132177 }
133178 else if (src.id ()==ID_code)
134179 {
135180 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 ))
137182 return false ;
138183
139184 for (const auto &p : code_type.parameters ())
140185 {
141- if (!find_symbols (kind, p, op))
186+ if (!find_symbols (kind, p, op, bindings ))
142187 return false ;
143188 }
144189 }
145190 else if (src.id ()==ID_array)
146191 {
147192 // 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 ))
149194 return false ;
150195 }
151196 else if (
@@ -172,6 +217,24 @@ static bool find_symbols(
172217 return true ;
173218}
174219
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+
175238void find_symbols (const exprt &src, std::set<symbol_exprt> &dest)
176239{
177240 find_symbols (symbol_kindt::F_EXPR, src, [&dest](const symbol_exprt &e) {
@@ -180,11 +243,18 @@ void find_symbols(const exprt &src, std::set<symbol_exprt> &dest)
180243 });
181244}
182245
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)
184250{
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
253+ : symbol_kindt::F_EXPR_NOT_BOUND,
254+ src,
255+ [&identifier](const symbol_exprt &e) {
256+ return e.get_identifier () != identifier;
257+ });
188258}
189259
190260void find_type_symbols (const exprt &src, find_symbols_sett &dest)
0 commit comments