Skip to content

Commit 4a82eca

Browse files
authored
Merge pull request #690 from diffblue/obligationst
introduce `obligationst`
2 parents b0cd3b2 + 233fefc commit 4a82eca

File tree

2 files changed

+85
-18
lines changed

2 files changed

+85
-18
lines changed

src/trans-word-level/obligations.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*******************************************************************\
2+
3+
Module: Unwinding the Properties
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_TRANS_WORD_LEVEL_OBLIGATIONS_H
10+
#define CPROVER_TRANS_WORD_LEVEL_OBLIGATIONS_H
11+
12+
#include <util/expr.h>
13+
#include <util/mp_arith.h>
14+
15+
#include <map>
16+
17+
class obligationst
18+
{
19+
public:
20+
obligationst() = default;
21+
22+
explicit obligationst(const std::pair<mp_integer, exprt> &pair)
23+
{
24+
add(pair.first, pair.second);
25+
}
26+
27+
// The value are conditions that must be met for the property to hold.
28+
// The key is the length of the counterexample if the condition is violated.
29+
std::map<mp_integer, exprt::operandst> map;
30+
31+
// add a condition
32+
void add(const mp_integer &t, exprt expr)
33+
{
34+
map[t].push_back(std::move(expr));
35+
}
36+
37+
void add(const std::pair<mp_integer, exprt::operandst> &pair)
38+
{
39+
auto &entry = map[pair.first];
40+
for(auto &expr : pair.second)
41+
entry.push_back(expr);
42+
}
43+
44+
// add a set of conditions
45+
void add(const obligationst &obligations)
46+
{
47+
for(auto &obligation : obligations.map)
48+
add(obligation);
49+
}
50+
};
51+
52+
#endif

src/trans-word-level/property.cpp

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Author: Daniel Kroening, [email protected]
2121
#include <verilog/sva_expr.h>
2222

2323
#include "instantiate_word_level.h"
24+
#include "obligations.h"
2425

2526
#include <cstdlib>
2627

@@ -209,13 +210,12 @@ Function: property_obligations_rec
209210
210211
\*******************************************************************/
211212

212-
static void property_obligations_rec(
213+
static obligationst property_obligations_rec(
213214
const exprt &property_expr,
214215
decision_proceduret &solver,
215216
const mp_integer &current,
216217
const mp_integer &no_timeframes,
217-
const namespacet &ns,
218-
std::map<mp_integer, exprt::operandst> &obligations)
218+
const namespacet &ns)
219219
{
220220
PRECONDITION(current >= 0 && current < no_timeframes);
221221

@@ -235,17 +235,24 @@ static void property_obligations_rec(
235235
PRECONDITION(false);
236236
}(property_expr);
237237

238+
obligationst obligations;
239+
238240
for(mp_integer c = current; c < no_timeframes; ++c)
239241
{
240-
property_obligations_rec(phi, solver, c, no_timeframes, ns, obligations);
242+
obligations.add(
243+
property_obligations_rec(phi, solver, c, no_timeframes, ns));
241244
}
245+
246+
return obligations;
242247
}
243248
else if(
244249
property_expr.id() == ID_AF || property_expr.id() == ID_F ||
245250
property_expr.id() == ID_sva_s_eventually)
246251
{
247252
const auto &phi = to_unary_expr(property_expr).op();
248253

254+
obligationst obligations;
255+
249256
// Counterexamples to Fφ must have a loop.
250257
// We consider l-k loops with l<k.
251258
for(mp_integer k = current + 1; k < no_timeframes; ++k)
@@ -267,9 +274,11 @@ static void property_obligations_rec(
267274
disjuncts.push_back(std::move(tmp));
268275
}
269276

270-
obligations[k].push_back(disjunction(disjuncts));
277+
obligations.add(k, disjunction(disjuncts));
271278
}
272279
}
280+
281+
return obligations;
273282
}
274283
else if(
275284
property_expr.id() == ID_sva_ranged_always ||
@@ -305,22 +314,33 @@ static void property_obligations_rec(
305314
to = std::min(*to_opt, no_timeframes - 1);
306315
}
307316

317+
obligationst obligations;
318+
308319
for(mp_integer c = from; c <= to; ++c)
309320
{
310-
property_obligations_rec(phi, solver, c, no_timeframes, ns, obligations);
321+
obligations.add(
322+
property_obligations_rec(phi, solver, c, no_timeframes, ns));
311323
}
324+
325+
return obligations;
312326
}
313327
else if(property_expr.id() == ID_and)
314328
{
315329
// generate seperate obligations for each conjunct
330+
obligationst obligations;
331+
316332
for(auto &op : to_and_expr(property_expr).operands())
317-
property_obligations_rec(
318-
op, solver, current, no_timeframes, ns, obligations);
333+
{
334+
obligations.add(
335+
property_obligations_rec(op, solver, current, no_timeframes, ns));
336+
}
337+
338+
return obligations;
319339
}
320340
else
321341
{
322-
auto tmp = instantiate_property(property_expr, current, no_timeframes, ns);
323-
obligations[tmp.first].push_back(tmp.second);
342+
return obligationst{
343+
instantiate_property(property_expr, current, no_timeframes, ns)};
324344
}
325345
}
326346

@@ -336,18 +356,13 @@ Function: property_obligations
336356
337357
\*******************************************************************/
338358

339-
static std::map<mp_integer, exprt::operandst> property_obligations(
359+
obligationst property_obligations(
340360
const exprt &property_expr,
341361
decision_proceduret &solver,
342362
const mp_integer &no_timeframes,
343363
const namespacet &ns)
344364
{
345-
std::map<mp_integer, exprt::operandst> obligations;
346-
347-
property_obligations_rec(
348-
property_expr, solver, 0, no_timeframes, ns, obligations);
349-
350-
return obligations;
365+
return property_obligations_rec(property_expr, solver, 0, no_timeframes, ns);
351366
}
352367

353368
/*******************************************************************\
@@ -378,7 +393,7 @@ void property(
378393

379394
// Map obligations onto timeframes.
380395
prop_handles.resize(no_timeframes, true_exprt());
381-
for(auto &obligation_it : obligations)
396+
for(auto &obligation_it : obligations.map)
382397
{
383398
auto t = obligation_it.first;
384399
DATA_INVARIANT(

0 commit comments

Comments
 (0)