Skip to content

Commit b6c4ca8

Browse files
committed
trace length for disjunctive properties
Given a property a ∨ b with obligations at timeframe l and m, generate the obligation for the disjunction at timeframe max{l, m}.
1 parent e8d87af commit b6c4ca8

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE broken-smt-backend
2+
disjunction1.smv
3+
--bound 20 --numbered-trace
4+
^\[spec1\] G \(X FALSE \| X X FALSE\): REFUTED$
5+
^Counterexample with 3 states:$
6+
^i@0 = 0$
7+
^i@1 = 1$
8+
^i@2 = 2$
9+
^EXIT=10$
10+
^SIGNAL=0$
11+
--
12+
^warning: ignoring
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
MODULE main
2+
3+
VAR i: 0..20;
4+
5+
ASSIGN init(i) := 0;
6+
next(i) := case
7+
i >= 10 : 10;
8+
TRUE : i + 1;
9+
esac;
10+
11+
-- we need to see a trace with three states
12+
LTLSPEC G ((X FALSE) | (X X FALSE))

src/trans-word-level/property.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,54 @@ bool bmc_supports_property(const exprt &expr)
7878

7979
/*******************************************************************\
8080
81+
Function: max_property_obligation
82+
83+
Inputs:
84+
85+
Outputs:
86+
87+
Purpose:
88+
89+
\*******************************************************************/
90+
91+
static void property_obligations_rec(
92+
const exprt &property_expr,
93+
decision_proceduret &,
94+
const mp_integer &current,
95+
const mp_integer &no_timeframes,
96+
const namespacet &,
97+
std::map<mp_integer, exprt::operandst> &obligations);
98+
99+
static std::pair<mp_integer, exprt> max_property_obligation(
100+
const exprt &property_expr,
101+
decision_proceduret &solver,
102+
const mp_integer &current,
103+
const mp_integer &no_timeframes,
104+
const namespacet &ns)
105+
{
106+
// Generate one obligation, equivalent to the conjunction
107+
// for the maximum timeframe.
108+
109+
std::map<mp_integer, exprt::operandst> obligations;
110+
111+
property_obligations_rec(
112+
property_expr, solver, current, no_timeframes, ns, obligations);
113+
114+
exprt::operandst conjuncts;
115+
mp_integer max_timeframe = 0;
116+
117+
for(auto &[timeframe, exprs] : obligations)
118+
{
119+
max_timeframe = std::max(max_timeframe, timeframe);
120+
for(auto &conjunct : exprs)
121+
conjuncts.push_back(conjunct);
122+
}
123+
124+
return std::pair<mp_integer, exprt>{max_timeframe, conjunction(conjuncts)};
125+
}
126+
127+
/*******************************************************************\
128+
81129
Function: property_obligations_rec
82130
83131
Inputs:
@@ -198,10 +246,28 @@ static void property_obligations_rec(
198246
}
199247
else if(property_expr.id() == ID_and)
200248
{
249+
// generate seperate obligations for each conjunct
201250
for(auto &op : to_and_expr(property_expr).operands())
202251
property_obligations_rec(
203252
op, solver, current, no_timeframes, ns, obligations);
204253
}
254+
else if(property_expr.id() == ID_or)
255+
{
256+
// generate one obligation, equivalent to the disjunction,
257+
// for the maximum timeframe
258+
mp_integer max_timeframe = 0;
259+
exprt::operandst disjuncts;
260+
261+
for(auto &op : to_or_expr(property_expr).operands())
262+
{
263+
auto obligation =
264+
max_property_obligation(op, solver, current, no_timeframes, ns);
265+
max_timeframe = std::max(max_timeframe, obligation.first);
266+
disjuncts.push_back(obligation.second);
267+
}
268+
269+
obligations[max_timeframe].push_back(disjunction(disjuncts));
270+
}
205271
else
206272
{
207273
// current state property

0 commit comments

Comments
 (0)