Skip to content

Commit 3e51bdb

Browse files
committed
BMC: instantiate_word_level now side-effect free
This removes the side effect of the methods in instantiate_word_levelt, by introducing an explicit parameter.
1 parent e684b79 commit 3e51bdb

File tree

1 file changed

+49
-83
lines changed

1 file changed

+49
-83
lines changed

src/trans-word-level/instantiate_word_level.cpp

Lines changed: 49 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -69,40 +69,23 @@ symbol_exprt timeframe_symbol(std::size_t timeframe, symbol_exprt src)
6969
class wl_instantiatet
7070
{
7171
public:
72-
wl_instantiatet(
73-
std::size_t _current,
74-
std::size_t _no_timeframes,
75-
const namespacet &_ns)
76-
: current(_current), no_timeframes(_no_timeframes), ns(_ns)
72+
wl_instantiatet(std::size_t _no_timeframes, const namespacet &_ns)
73+
: no_timeframes(_no_timeframes), ns(_ns)
7774
{
7875
}
7976

80-
[[nodiscard]] exprt operator()(exprt expr)
77+
/// Instantiate the given expression for timeframe t
78+
[[nodiscard]] exprt operator()(exprt expr, std::size_t t) const
8179
{
82-
return instantiate_rec(std::move(expr));
80+
return instantiate_rec(std::move(expr), t);
8381
}
8482

8583
protected:
86-
std::size_t current, no_timeframes;
84+
std::size_t no_timeframes;
8785
const namespacet &ns;
8886

89-
[[nodiscard]] exprt instantiate_rec(exprt);
90-
[[nodiscard]] typet instantiate_rec(typet);
91-
92-
class save_currentt
93-
{
94-
public:
95-
inline explicit save_currentt(std::size_t &_c) : c(_c), saved(c)
96-
{
97-
}
98-
99-
inline ~save_currentt()
100-
{
101-
c=saved; // restore
102-
}
103-
104-
std::size_t &c, saved;
105-
};
87+
[[nodiscard]] exprt instantiate_rec(exprt, std::size_t t) const;
88+
[[nodiscard]] typet instantiate_rec(typet, std::size_t t) const;
10689
};
10790

10891
/*******************************************************************\
@@ -117,26 +100,26 @@ Function: wl_instantiatet::instantiate_rec
117100
118101
\*******************************************************************/
119102

120-
exprt wl_instantiatet::instantiate_rec(exprt expr)
103+
exprt wl_instantiatet::instantiate_rec(exprt expr, const std::size_t t) const
121104
{
122-
expr.type() = instantiate_rec(expr.type());
105+
expr.type() = instantiate_rec(expr.type(), t);
123106

124107
if(expr.id() == ID_next_symbol)
125108
{
126109
expr.id(ID_symbol);
127-
return timeframe_symbol(current + 1, to_symbol_expr(std::move(expr)));
110+
return timeframe_symbol(t + 1, to_symbol_expr(std::move(expr)));
128111
}
129112
else if(expr.id() == ID_symbol)
130113
{
131-
return timeframe_symbol(current, to_symbol_expr(std::move(expr)));
114+
return timeframe_symbol(t, to_symbol_expr(std::move(expr)));
132115
}
133116
else if(expr.id()==ID_sva_overlapped_implication)
134117
{
135118
// same as regular implication
136119
expr.id(ID_implies);
137120

138121
for(auto &op : expr.operands())
139-
op = instantiate_rec(op);
122+
op = instantiate_rec(op, t);
140123

141124
return expr;
142125
}
@@ -147,18 +130,16 @@ exprt wl_instantiatet::instantiate_rec(exprt expr)
147130
{
148131
expr.id(ID_implies);
149132
auto &implies_expr = to_implies_expr(expr);
150-
implies_expr.op0() = instantiate_rec(implies_expr.op0());
133+
implies_expr.op0() = instantiate_rec(implies_expr.op0(), t);
134+
135+
const auto next = t + 1;
151136

152-
save_currentt save_current(current);
153-
154-
current++;
155-
156137
// Do we exceed the bound? Make it 'true',
157138
// works on NNF only
158-
if(current>=no_timeframes)
139+
if(next >= no_timeframes)
159140
implies_expr.op1() = true_exprt();
160141
else
161-
implies_expr.op1() = instantiate_rec(implies_expr.op1());
142+
implies_expr.op1() = instantiate_rec(implies_expr.op1(), next);
162143

163144
return std::move(implies_expr);
164145
}
@@ -171,22 +152,19 @@ exprt wl_instantiatet::instantiate_rec(exprt expr)
171152
{
172153
auto &ternary_expr = to_ternary_expr(expr);
173154

174-
// save the current time frame, we'll change it
175-
save_currentt save_current(current);
176-
177155
if(ternary_expr.op1().is_nil())
178156
{
179157
mp_integer offset;
180158
if(to_integer_non_constant(ternary_expr.op0(), offset))
181159
throw "failed to convert sva_cycle_delay offset";
182160

183-
current = save_current.saved + offset.to_ulong();
161+
const auto u = t + offset.to_ulong();
184162

185163
// Do we exceed the bound? Make it 'true'
186-
if(current>=no_timeframes)
164+
if(u >= no_timeframes)
187165
return true_exprt();
188166
else
189-
return instantiate_rec(ternary_expr.op2());
167+
return instantiate_rec(ternary_expr.op2(), u);
190168
}
191169
else
192170
{
@@ -208,14 +186,14 @@ exprt wl_instantiatet::instantiate_rec(exprt expr)
208186

209187
for(mp_integer offset=from; offset<to; ++offset)
210188
{
211-
current = save_current.saved + offset.to_ulong();
189+
auto u = t + offset.to_ulong();
212190

213-
if(current>=no_timeframes)
191+
if(u >= no_timeframes)
214192
{
215193
}
216194
else
217195
{
218-
disjuncts.push_back(instantiate_rec(ternary_expr.op2()));
196+
disjuncts.push_back(instantiate_rec(ternary_expr.op2(), u));
219197
}
220198
}
221199

@@ -231,22 +209,19 @@ exprt wl_instantiatet::instantiate_rec(exprt expr)
231209
expr.id(ID_and);
232210

233211
for(auto &op : expr.operands())
234-
op = instantiate_rec(op);
212+
op = instantiate_rec(op, t);
235213

236214
return expr;
237215
}
238216
else if(expr.id()==ID_sva_always)
239217
{
240218
auto &op = to_sva_always_expr(expr).op();
241219

242-
// save the current time frame, we'll change it
243-
save_currentt save_current(current);
244-
245220
exprt::operandst conjuncts;
246221

247-
for(; current<no_timeframes; current++)
222+
for(auto u = t; u < no_timeframes; u++)
248223
{
249-
conjuncts.push_back(instantiate_rec(op));
224+
conjuncts.push_back(instantiate_rec(op, u));
250225
}
251226

252227
return conjunction(conjuncts);
@@ -255,15 +230,12 @@ exprt wl_instantiatet::instantiate_rec(exprt expr)
255230
expr.id()==ID_sva_s_nexttime)
256231
{
257232
assert(expr.operands().size()==1);
258-
259-
// save the current time frame, we'll change it
260-
save_currentt save_current(current);
261-
262-
current++;
263-
264-
if(current<no_timeframes)
233+
234+
const auto next = t + 1;
235+
236+
if(next < no_timeframes)
265237
{
266-
return instantiate_rec(to_unary_expr(expr).op());
238+
return instantiate_rec(to_unary_expr(expr).op(), next);
267239
}
268240
else
269241
return true_exprt(); // works on NNF only
@@ -280,25 +252,22 @@ exprt wl_instantiatet::instantiate_rec(exprt expr)
280252
// some earlier state k < i.
281253
// (1) No state j with k<=k<=i on the lasso satisfies 'p'.
282254
//
283-
// We look backwards instead of forwards so that 'current'
255+
// We look backwards instead of forwards so that 't'
284256
// is the last state of the counterexample trace.
285257
//
286-
// Note that this is trivially true when current is zero,
258+
// Note that this is trivially true when t is zero,
287259
// as a single state cannot demonstrate the loop.
288260

289261
exprt::operandst conjuncts = {};
290-
const std::size_t i = current;
262+
const auto i = t;
291263

292264
for(std::size_t k = 0; k < i; k++)
293265
{
294266
exprt::operandst disjuncts = {not_exprt(lasso_symbol(k, i))};
295267

296268
for(std::size_t j = k; j <= i; j++)
297269
{
298-
// save the current time frame, we'll change it
299-
save_currentt save_current(current);
300-
current = j;
301-
disjuncts.push_back(instantiate_rec(p));
270+
disjuncts.push_back(instantiate_rec(p, j));
302271
}
303272

304273
conjuncts.push_back(disjunction(disjuncts));
@@ -314,22 +283,19 @@ exprt wl_instantiatet::instantiate_rec(exprt expr)
314283
assert(expr.operands().size()==2);
315284

316285
// we need a lasso to refute these
317-
318-
// save the current time frame, we'll change it
319-
save_currentt save_current(current);
320-
286+
321287
// we expand: p U q <=> q || (p && X(p U q))
322288
exprt tmp_q = to_binary_expr(expr).op1();
323-
tmp_q = instantiate_rec(tmp_q);
289+
tmp_q = instantiate_rec(tmp_q, t);
324290

325291
exprt expansion = to_binary_expr(expr).op0();
326-
expansion = instantiate_rec(expansion);
292+
expansion = instantiate_rec(expansion, t);
327293

328-
current++;
329-
330-
if(current<no_timeframes)
294+
const auto next = t + 1;
295+
296+
if(next < no_timeframes)
331297
{
332-
expansion = and_exprt(expansion, instantiate_rec(expr));
298+
expansion = and_exprt(expansion, instantiate_rec(expr, next));
333299
}
334300

335301
return or_exprt(tmp_q, expansion);
@@ -350,12 +316,12 @@ exprt wl_instantiatet::instantiate_rec(exprt expr)
350316

351317
tmp.op1() = sva_nexttime_exprt(tmp.op1());
352318

353-
return instantiate_rec(tmp);
319+
return instantiate_rec(tmp, t);
354320
}
355321
else
356322
{
357323
for(auto &op : expr.operands())
358-
op = instantiate_rec(op);
324+
op = instantiate_rec(op, t);
359325
return expr;
360326
}
361327
}
@@ -372,7 +338,7 @@ Function: wl_instantiatet::instantiate_rec
372338
373339
\*******************************************************************/
374340

375-
typet wl_instantiatet::instantiate_rec(typet type)
341+
typet wl_instantiatet::instantiate_rec(typet type, std::size_t) const
376342
{
377343
return type;
378344
}
@@ -391,10 +357,10 @@ Function: instantiate
391357

392358
exprt instantiate(
393359
const exprt &expr,
394-
std::size_t current,
360+
std::size_t t,
395361
std::size_t no_timeframes,
396362
const namespacet &ns)
397363
{
398-
wl_instantiatet wl_instantiate(current, no_timeframes, ns);
399-
return wl_instantiate(expr);
364+
wl_instantiatet wl_instantiate(no_timeframes, ns);
365+
return wl_instantiate(expr, t);
400366
}

0 commit comments

Comments
 (0)