@@ -380,32 +380,26 @@ static obligationst property_obligations_rec(
380380 property_expr.id () == ID_sva_until ||
381381 property_expr.id () == ID_sva_s_until || property_expr.id () == ID_U)
382382 {
383- // non-overlapping until
384- // we need a lasso to refute these
385-
386- // we expand: p U q <=> q ∨ (p ∧ X(p U q))
387- exprt tmp_q = to_binary_expr (property_expr).op1 ();
388- tmp_q = property_obligations_rec (tmp_q, solver, current, no_timeframes, ns)
389- .conjunction ()
390- .second ;
391-
392- exprt expansion = to_binary_expr (property_expr).op0 ();
393- expansion =
394- property_obligations_rec (expansion, solver, current, no_timeframes, ns)
395- .conjunction ()
396- .second ;
383+ auto &p = to_binary_expr (property_expr).lhs ();
384+ auto &q = to_binary_expr (property_expr).rhs ();
397385
398- const auto next = current + 1 ;
386+ // p U q ≡ Fq ∧ (p W q)
387+ exprt tmp = and_exprt{F_exprt{q}, weak_U_exprt{p, q}};
399388
400- if (next < no_timeframes)
401- {
402- auto obligations_rec = property_obligations_rec (
403- property_expr, solver, next, no_timeframes, ns);
404- expansion = and_exprt{expansion, obligations_rec.conjunction ().second };
405- }
389+ return property_obligations_rec (tmp, solver, current, no_timeframes, ns);
390+ }
391+ else if (property_expr.id () == ID_weak_U)
392+ {
393+ // we expand: p W q ≡ q ∨ ( p ∧ X(p W q) )
394+ auto &p = to_weak_U_expr (property_expr).lhs ();
395+ auto &q = to_weak_U_expr (property_expr).rhs ();
406396
407- DATA_INVARIANT (no_timeframes != 0 , " must have timeframe" );
408- return obligationst{no_timeframes - 1 , or_exprt{tmp_q, expansion}};
397+ // Once we reach the end of the unwinding, replace X(p W q) by 'true'.
398+ auto tmp = or_exprt{
399+ q,
400+ (current + 1 ) < no_timeframes ? and_exprt{p, X_exprt{property_expr}} : p};
401+
402+ return property_obligations_rec (tmp, solver, current, no_timeframes, ns);
409403 }
410404 else if (property_expr.id () == ID_R)
411405 {
0 commit comments