Skip to content

Commit 6dcb40c

Browse files
authored
Merge pull request #1210 from diffblue/bmc-R-W-loop
BMC: replace recursion for R and W by loop
2 parents 9732d42 + f9dab56 commit 6dcb40c

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

src/trans-word-level/property.cpp

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -406,31 +406,50 @@ static obligationst property_obligations_rec(
406406
}
407407
else if(property_expr.id() == ID_sva_until || property_expr.id() == ID_weak_U)
408408
{
409-
// we expand: p W q ≡ q ∨ ( p ∧ X(p W q) )
410-
auto &p = to_binary_expr(property_expr).lhs();
411-
auto &q = to_binary_expr(property_expr).rhs();
409+
auto &binary_expr = to_binary_expr(property_expr);
410+
auto &p = binary_expr.lhs();
411+
auto &q = binary_expr.rhs();
412412

413-
// Once we reach the end of the unwinding, replace X(p W q) by 'true'.
414-
auto tmp = or_exprt{
415-
q,
416-
(current + 1) < no_timeframes ? and_exprt{p, X_exprt{property_expr}} : p};
413+
// p has to to be true until (not including) q is true
414+
exprt::operandst q_disjuncts;
415+
obligationst obligations;
417416

418-
return property_obligations_rec(tmp, current, no_timeframes);
417+
for(mp_integer j = current; j < no_timeframes; ++j)
418+
{
419+
auto q_rec = property_obligations_rec(q, j, no_timeframes);
420+
q_disjuncts.push_back(q_rec.conjunction().second);
421+
422+
auto p_rec = property_obligations_rec(p, j, no_timeframes);
423+
auto cond =
424+
or_exprt{p_rec.conjunction().second, disjunction(q_disjuncts)};
425+
426+
obligations.add(current, cond);
427+
}
428+
429+
return obligations;
419430
}
420431
else if(property_expr.id() == ID_R)
421432
{
422-
// we expand: p R q <=> q ∧ (p ∨ X(p R q))
423433
auto &R_expr = to_R_expr(property_expr);
424434
auto &p = R_expr.lhs();
425435
auto &q = R_expr.rhs();
426436

427-
// Once we reach the end of the unwinding, we replace X(p R q) by
428-
// true, and hence the expansion becomes "q" only.
429-
exprt expansion = (current + 1) < no_timeframes
430-
? and_exprt{q, or_exprt{p, X_exprt{property_expr}}}
431-
: q;
437+
// q has to be true until (including) p is true
438+
exprt::operandst p_disjuncts;
439+
obligationst obligations;
432440

433-
return property_obligations_rec(expansion, current, no_timeframes);
441+
for(mp_integer j = current; j < no_timeframes; ++j)
442+
{
443+
auto q_rec = property_obligations_rec(q, j, no_timeframes);
444+
auto cond =
445+
or_exprt{q_rec.conjunction().second, disjunction(p_disjuncts)};
446+
obligations.add(current, cond);
447+
448+
auto p_rec = property_obligations_rec(p, j, no_timeframes);
449+
p_disjuncts.push_back(p_rec.conjunction().second);
450+
}
451+
452+
return obligations;
434453
}
435454
else if(property_expr.id() == ID_strong_R)
436455
{

0 commit comments

Comments
 (0)