Skip to content

Commit dda4d36

Browse files
authored
Merge pull request #402 from diffblue/instantiate_wl_functional
BMC: world-level property instantiation refactorings
2 parents bdb6e7b + 38b47b5 commit dda4d36

File tree

4 files changed

+72
-104
lines changed

4 files changed

+72
-104
lines changed

src/trans-word-level/instantiate_word_level.cpp

Lines changed: 55 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ Function: timeframe_identifier
2929
\*******************************************************************/
3030

3131
std::string
32-
timeframe_identifier(std::size_t timeframe, const irep_idt &identifier)
32+
timeframe_identifier(const mp_integer &timeframe, const irep_idt &identifier)
3333
{
34-
return id2string(identifier)+"@"+std::to_string(timeframe);
34+
return id2string(identifier) + "@" + integer2string(timeframe);
3535
}
3636

3737
/*******************************************************************\
@@ -46,7 +46,7 @@ Function: timeframe_symbol
4646
4747
\*******************************************************************/
4848

49-
symbol_exprt timeframe_symbol(std::size_t timeframe, symbol_exprt src)
49+
symbol_exprt timeframe_symbol(const mp_integer &timeframe, symbol_exprt src)
5050
{
5151
auto result = std::move(src);
5252
result.set_identifier(
@@ -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(const mp_integer &_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, const mp_integer &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+
const mp_integer &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, const mp_integer &t) const;
88+
[[nodiscard]] typet instantiate_rec(typet, const mp_integer &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 mp_integer &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;
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;
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

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

296-
for(std::size_t j = k; j <= i; j++)
268+
for(mp_integer 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, const mp_integer &) 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,
395-
std::size_t no_timeframes,
360+
const mp_integer &t,
361+
const mp_integer &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
}

src/trans-word-level/instantiate_word_level.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@ Author: Daniel Kroening, [email protected]
99
#ifndef CPROVER_BMC_INSTANTIATE_WORD_LEVEL_H
1010
#define CPROVER_BMC_INSTANTIATE_WORD_LEVEL_H
1111

12-
#include <solvers/prop/prop_conv.h>
13-
12+
#include <util/mp_arith.h>
1413
#include <util/namespace.h>
1514

15+
#include <solvers/prop/prop_conv.h>
16+
1617
exprt instantiate(
1718
const exprt &expr,
18-
std::size_t current,
19-
std::size_t no_timeframes,
19+
const mp_integer &current,
20+
const mp_integer &no_timeframes,
2021
const namespacet &);
2122

2223
std::string
23-
timeframe_identifier(std::size_t timeframe, const irep_idt &identifier);
24+
timeframe_identifier(const mp_integer &timeframe, const irep_idt &identifier);
2425

25-
symbol_exprt timeframe_symbol(std::size_t timeframe, symbol_exprt);
26+
symbol_exprt timeframe_symbol(const mp_integer &timeframe, symbol_exprt);
2627

2728
#endif

src/trans-word-level/property.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ Function: states_equal
109109
\*******************************************************************/
110110

111111
exprt states_equal(
112-
std::size_t k,
113-
std::size_t i,
112+
const mp_integer &k,
113+
const mp_integer &i,
114114
const std::vector<symbol_exprt> &variables_to_compare)
115115
{
116116
// We require k<i to avoid the symmetric constraints.
@@ -141,13 +141,13 @@ Function: lasso_symbol
141141
142142
\*******************************************************************/
143143

144-
symbol_exprt lasso_symbol(std::size_t k, std::size_t i)
144+
symbol_exprt lasso_symbol(const mp_integer &k, const mp_integer &i)
145145
{
146146
// True when states i and k are equal.
147147
// We require k<i to avoid the symmetric constraints.
148148
PRECONDITION(k < i);
149149
irep_idt lasso_identifier =
150-
"lasso::" + std::to_string(i) + "-back-to-" + std::to_string(k);
150+
"lasso::" + integer2string(i) + "-back-to-" + integer2string(k);
151151
return symbol_exprt(lasso_identifier, bool_typet());
152152
}
153153

@@ -165,7 +165,7 @@ Function: lasso_constraints
165165

166166
void lasso_constraints(
167167
decision_proceduret &solver,
168-
std::size_t no_timeframes,
168+
const mp_integer &no_timeframes,
169169
const namespacet &ns,
170170
const irep_idt &module_identifier)
171171
{
@@ -204,9 +204,9 @@ void lasso_constraints(
204204
}
205205
}
206206

207-
for(std::size_t i = 1; i < no_timeframes; i++)
207+
for(mp_integer i = 1; i < no_timeframes; ++i)
208208
{
209-
for(std::size_t k = 0; k < i; k++)
209+
for(mp_integer k = 0; k < i; ++k)
210210
{
211211
// Is there a loop back from time frame i back to time frame k?
212212
auto lasso_symbol = ::lasso_symbol(k, i);

0 commit comments

Comments
 (0)