Skip to content

Commit 3f6ecba

Browse files
committed
find_symbols: support restriction to non-bound symbols
Adds a new symbol kind to distinguish bound from unbound ones.
1 parent d4ec86a commit 3f6ecba

File tree

2 files changed

+68
-13
lines changed

2 files changed

+68
-13
lines changed

src/util/find_symbols.cpp

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,53 @@ bool has_symbol(
4343
static 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

4849
static 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(
103137
static 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+
186239
void find_symbols(const exprt &src, std::set<symbol_exprt> &dest)
187240
{
188241
find_symbols(

src/util/find_symbols.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ enum class symbol_kindt
3737
F_EXPR_NEXT,
3838
/// Current or next-state symbol expressions.
3939
F_EXPR_BOTH,
40+
/// Symbol expressions, but excluding bindings.
41+
F_EXPR_NOT_BOUND,
4042
/// All of the above.
4143
F_ALL
4244
};

0 commit comments

Comments
 (0)