Skip to content

Commit 795ccf7

Browse files
authored
Merge pull request #721 from diffblue/sva_until_with
SVA until_with
2 parents 98d69e5 + 068274c commit 795ccf7

File tree

5 files changed

+106
-36
lines changed

5 files changed

+106
-36
lines changed

regression/ebmc/SVA-LTL/simple_passing_LTL_properties.desc

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ simple_passing_LTL_properties.sv
44
^Adding lasso constraints$
55
^EXIT=0$
66
^SIGNAL=0$
7-
^\[top\.p0\] .* PROVED up to bound 10$
8-
^\[top\.p1\] .* PROVED up to bound 10$
9-
^\[top\.p2\] .* PROVED up to bound 10$
10-
^\[top\.p3\] .* PROVED up to bound 10$
11-
^\[top\.p4\] .* PROVED up to bound 10$
12-
^\[top\.p5\] .* PROVED up to bound 10$
13-
^\[top\.p6\] .* PROVED up to bound 10$
14-
^\[top\.p7\] .* PROVED up to bound 10$
15-
^\[top\.p8\] .* PROVED up to bound 10$
7+
^\[top\.p00\] .* PROVED up to bound 10$
8+
^\[top\.p01\] .* PROVED up to bound 10$
9+
^\[top\.p02\] .* PROVED up to bound 10$
10+
^\[top\.p03\] .* PROVED up to bound 10$
11+
^\[top\.p04\] .* PROVED up to bound 10$
12+
^\[top\.p05\] .* PROVED up to bound 10$
13+
^\[top\.p06\] .* PROVED up to bound 10$
14+
^\[top\.p07\] .* PROVED up to bound 10$
15+
^\[top\.p08\] .* PROVED up to bound 10$
16+
^\[top\.p09\] .* PROVED up to bound 10$
17+
^\[top\.p10\] .* PROVED up to bound 10$
1618
--

regression/ebmc/SVA-LTL/simple_passing_LTL_properties.sv

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@ module top(input clock, input i1);
1111
counter=counter+1;
1212
end
1313

14-
p0: assert property (my_bit);
15-
p1: assert property (always my_bit);
16-
p2: assert property (counter==3 |-> nexttime counter==4);
17-
p3: assert property (counter==3 |=> counter==4);
18-
p4: assert property (counter==3 |=> nexttime counter==5);
19-
p5: assert property (s_eventually counter==8);
20-
p6: assert property (counter==0 |-> s_eventually counter==8);
21-
p7: assert property (counter==0 |-> counter<=5 until counter==6);
22-
p8: assert property (counter==0 |-> counter<=5 until_with counter==5);
14+
p00: assert property (my_bit);
15+
p01: assert property (always my_bit);
16+
p02: assert property (counter==3 |-> nexttime counter==4);
17+
p03: assert property (counter==3 |=> counter==4);
18+
p04: assert property (counter==3 |=> nexttime counter==5);
19+
p05: assert property (s_eventually counter==8);
20+
p06: assert property (counter==0 |-> s_eventually counter==8);
21+
p07: assert property (counter==0 |-> counter<=5 until counter==6);
22+
p08: assert property (counter==0 |-> counter<=5 s_until counter==6);
23+
p09: assert property (counter==0 |-> counter<=5 until_with counter==5);
24+
p10: assert property (counter==0 |-> counter<=5 s_until_with counter==5);
2325

2426
endmodule
2527

src/hw_cbmc_irep_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ IREP_ID_ONE(ER)
1111
IREP_ID_ONE(U)
1212
IREP_ID_ONE(weak_U)
1313
IREP_ID_ONE(R)
14+
IREP_ID_ONE(strong_R)
1415
IREP_ID_ONE(A)
1516
IREP_ID_ONE(F)
1617
IREP_ID_ONE(E)

src/temporal-logic/temporal_expr.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,29 @@ static inline R_exprt &to_R_expr(exprt &expr)
262262
return static_cast<R_exprt &>(expr);
263263
}
264264

265+
class strong_R_exprt : public binary_predicate_exprt
266+
{
267+
public:
268+
explicit strong_R_exprt(exprt op0, exprt op1)
269+
: binary_predicate_exprt(std::move(op0), ID_strong_R, std::move(op1))
270+
{
271+
}
272+
};
273+
274+
static inline const strong_R_exprt &to_strong_R_expr(const exprt &expr)
275+
{
276+
PRECONDITION(expr.id() == ID_strong_R);
277+
strong_R_exprt::check(expr);
278+
return static_cast<const strong_R_exprt &>(expr);
279+
}
280+
281+
static inline strong_R_exprt &to_strong_R_expr(exprt &expr)
282+
{
283+
PRECONDITION(expr.id() == ID_strong_R);
284+
strong_R_exprt::check(expr);
285+
return static_cast<strong_R_exprt &>(expr);
286+
}
287+
265288
class ER_exprt : public binary_predicate_exprt
266289
{
267290
public:

src/trans-word-level/property.cpp

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,7 @@ static obligationst property_obligations_rec(
371371
return obligationst{no_timeframes - 1, true_exprt()}; // works on NNF only
372372
}
373373
}
374-
else if(
375-
property_expr.id() == ID_sva_until ||
376-
property_expr.id() == ID_sva_s_until || property_expr.id() == ID_U)
374+
else if(property_expr.id() == ID_sva_s_until || property_expr.id() == ID_U)
377375
{
378376
auto &p = to_binary_expr(property_expr).lhs();
379377
auto &q = to_binary_expr(property_expr).rhs();
@@ -383,11 +381,11 @@ static obligationst property_obligations_rec(
383381

384382
return property_obligations_rec(tmp, current, no_timeframes, ns);
385383
}
386-
else if(property_expr.id() == ID_weak_U)
384+
else if(property_expr.id() == ID_sva_until || property_expr.id() == ID_weak_U)
387385
{
388386
// we expand: p W q ≡ q ∨ ( p ∧ X(p W q) )
389-
auto &p = to_weak_U_expr(property_expr).lhs();
390-
auto &q = to_weak_U_expr(property_expr).rhs();
387+
auto &p = to_binary_expr(property_expr).lhs();
388+
auto &q = to_binary_expr(property_expr).rhs();
391389

392390
// Once we reach the end of the unwinding, replace X(p W q) by 'true'.
393391
auto tmp = or_exprt{
@@ -411,23 +409,33 @@ static obligationst property_obligations_rec(
411409

412410
return property_obligations_rec(expansion, current, no_timeframes, ns);
413411
}
414-
else if(
415-
property_expr.id() == ID_sva_until_with ||
416-
property_expr.id() == ID_sva_s_until_with)
412+
else if(property_expr.id() == ID_strong_R)
417413
{
418-
// overlapping until
419-
420-
// we rewrite using 'next'
421-
binary_exprt tmp = to_binary_expr(property_expr);
422-
if(property_expr.id() == ID_sva_until_with)
423-
tmp.id(ID_sva_until);
424-
else
425-
tmp.id(ID_sva_s_until);
414+
auto &p = to_strong_R_expr(property_expr).lhs();
415+
auto &q = to_strong_R_expr(property_expr).rhs();
426416

427-
tmp.op1() = X_exprt{tmp.op1()};
417+
// p strongR q ≡ Fp ∧ (p R q)
418+
exprt tmp = and_exprt{F_exprt{q}, weak_U_exprt{p, q}};
428419

429420
return property_obligations_rec(tmp, current, no_timeframes, ns);
430421
}
422+
else if(property_expr.id() == ID_sva_until_with)
423+
{
424+
// Rewrite to LTL (weak) R.
425+
// Note that lhs and rhs are flipped.
426+
auto &until_with = to_sva_until_with_expr(property_expr);
427+
auto R = R_exprt{until_with.rhs(), until_with.lhs()};
428+
return property_obligations_rec(R, solver, current, no_timeframes, ns);
429+
}
430+
else if(property_expr.id() == ID_sva_s_until_with)
431+
{
432+
// Rewrite to LTL (strong) R.
433+
// Note that lhs and rhs are flipped.
434+
auto &s_until_with = to_sva_s_until_with_expr(property_expr);
435+
auto strong_R = strong_R_exprt{s_until_with.rhs(), s_until_with.lhs()};
436+
return property_obligations_rec(
437+
strong_R, solver, current, no_timeframes, ns);
438+
}
431439
else if(property_expr.id() == ID_and)
432440
{
433441
// Generate seperate sets of obligations for each conjunct,
@@ -571,6 +579,40 @@ static obligationst property_obligations_rec(
571579
return property_obligations_rec(
572580
to_not_expr(op).op(), current, no_timeframes, ns);
573581
}
582+
else if(op.id() == ID_sva_until)
583+
{
584+
// ¬(φ W ψ) ≡ (¬φ strongR ¬ψ)
585+
auto &W = to_sva_until_expr(op);
586+
auto strong_R = strong_R_exprt{not_exprt{W.lhs()}, not_exprt{W.rhs()}};
587+
return property_obligations_rec(
588+
strong_R, solver, current, no_timeframes, ns);
589+
}
590+
else if(op.id() == ID_sva_s_until)
591+
{
592+
// ¬(φ U ψ) ≡ (¬φ R ¬ψ)
593+
auto &U = to_sva_s_until_expr(op);
594+
auto R = R_exprt{not_exprt{U.lhs()}, not_exprt{U.rhs()}};
595+
return property_obligations_rec(R, solver, current, no_timeframes, ns);
596+
}
597+
else if(op.id() == ID_sva_until_with)
598+
{
599+
// ¬(φ R ψ) ≡ (¬φ U ¬ψ)
600+
// Note LHS and RHS are swapped.
601+
auto &until_with = to_sva_until_with_expr(op);
602+
auto R = R_exprt{until_with.rhs(), until_with.lhs()};
603+
auto U = sva_until_exprt{not_exprt{R.lhs()}, not_exprt{R.rhs()}};
604+
return property_obligations_rec(U, solver, current, no_timeframes, ns);
605+
}
606+
else if(op.id() == ID_sva_s_until_with)
607+
{
608+
// ¬(φ strongR ψ) ≡ (¬φ W ¬ψ)
609+
// Note LHS and RHS are swapped.
610+
auto &s_until_with = to_sva_s_until_with_expr(op);
611+
auto strong_R = strong_R_exprt{s_until_with.rhs(), s_until_with.lhs()};
612+
auto W =
613+
weak_U_exprt{not_exprt{strong_R.lhs()}, not_exprt{strong_R.rhs()}};
614+
return property_obligations_rec(W, solver, current, no_timeframes, ns);
615+
}
574616
else
575617
return obligationst{
576618
instantiate_property(property_expr, current, no_timeframes)};

0 commit comments

Comments
 (0)