Skip to content

Commit 1bac041

Browse files
authored
Merge pull request #770 from diffblue/negate_sva_until
SVA: remain within SVA when negating
2 parents e9e770d + 4e23bf6 commit 1bac041

File tree

4 files changed

+26
-16
lines changed

4 files changed

+26
-16
lines changed

regression/verilog/SVA/sva_iff2.sv

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ module main(input a, b);
44
p1: assert property ((eventually[0:1] a) iff (eventually[0:1] a));
55
p2: assert property ((s_eventually a) iff (s_eventually a));
66
p3: assert property ((a until b) iff (a until b));
7-
// p4: assert property ((a s_until b) iff (a s_until a));
7+
p4: assert property ((a s_until b) iff (a s_until b));
88
p5: assert property ((a until_with b) iff (a until_with b));
9-
p6: assert property ((a s_until_with b) iff (a s_until_with a));
9+
p6: assert property ((a s_until_with b) iff (a s_until_with b));
10+
p7: assert property ((a |-> b) iff (a |-> b));
11+
p8: assert property ((a #-# b) iff (a #-# b));
1012

1113
endmodule

regression/verilog/SVA/sva_implies2.sv

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ module main(input a, b);
55
p2: assert property ((eventually[0:1] a) implies (eventually[0:1] a));
66
p3: assert property ((s_eventually a) implies (s_eventually a));
77
p4: assert property ((a until b) implies (a until b));
8-
// p5: assert property ((a s_until b) implies (a s_until a));
8+
p5: assert property ((a s_until b) implies (a s_until b));
99
p6: assert property ((a until_with b) implies (a until_with b));
10-
p7: assert property ((a s_until_with b) implies (a s_until_with a));
10+
p7: assert property ((a s_until_with b) implies (a s_until_with b));
11+
p8: assert property ((a |-> b) implies (a |-> b));
12+
p9: assert property ((a #-# b) implies (a #-# b));
1113

1214
endmodule

src/temporal-logic/nnf.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,31 +94,35 @@ std::optional<exprt> negate_property_node(const exprt &expr)
9494
}
9595
else if(expr.id() == ID_sva_until)
9696
{
97-
// ¬(φ W ψ) ≡ (¬φ strongR ¬ψ)
98-
auto &W = to_sva_until_expr(expr);
99-
return strong_R_exprt{not_exprt{W.lhs()}, not_exprt{W.rhs()}};
97+
// ¬(φ weakU ψ) ≡ (¬φ strongR ¬ψ) ≡ (¬ψ strongU (¬ψ ∧ ¬φ)) ≡ (¬ψ s_until_with ¬φ)
98+
// Note that LHS and RHS are swapped.
99+
auto &until = to_sva_until_expr(expr);
100+
return sva_s_until_with_exprt{
101+
not_exprt{until.rhs()}, not_exprt{until.lhs()}};
100102
}
101103
else if(expr.id() == ID_sva_s_until)
102104
{
103-
// ¬(φ U ψ) ≡ (¬φ R ¬ψ)
104-
auto &U = to_sva_s_until_expr(expr);
105-
return R_exprt{not_exprt{U.lhs()}, not_exprt{U.rhs()}};
105+
// ¬(φ strongU ψ) ≡ (¬φ weakR ¬ψ) ≡ (¬ψ weakU (¬ψ ∧ ¬φ)) ≡ (¬ψ until_with ¬φ)
106+
// Note that LHS and RHS are swapped.
107+
auto &s_until = to_sva_s_until_expr(expr);
108+
return sva_until_with_exprt{
109+
not_exprt{s_until.rhs()}, not_exprt{s_until.lhs()}};
106110
}
107111
else if(expr.id() == ID_sva_until_with)
108112
{
109-
// ¬(φ R ψ) ≡ (¬φ U ¬ψ)
113+
// ¬(φ until_with ψ) ≡ ¬(φ until (φ ∧ ψ)) ≡ ¬(ψ weakR φ) ≡ (¬ψ strongU ¬φ)
110114
// Note LHS and RHS are swapped.
111115
auto &until_with = to_sva_until_with_expr(expr);
112-
auto R = R_exprt{until_with.rhs(), until_with.lhs()};
113-
return sva_until_exprt{not_exprt{R.lhs()}, not_exprt{R.rhs()}};
116+
return sva_s_until_exprt{
117+
not_exprt{until_with.rhs()}, not_exprt{until_with.lhs()}};
114118
}
115119
else if(expr.id() == ID_sva_s_until_with)
116120
{
117-
// ¬(φ strongR ψ) ≡ (¬φ W ¬ψ)
121+
// ¬(φ s_until_with ψ) ≡ ¬(φ s_until (φ ∧ ψ)) ≡ ¬(ψ strongR φ) ≡ (¬φ weakU ¬ψ)
118122
// Note LHS and RHS are swapped.
119123
auto &s_until_with = to_sva_s_until_with_expr(expr);
120-
auto strong_R = strong_R_exprt{s_until_with.rhs(), s_until_with.lhs()};
121-
return weak_U_exprt{not_exprt{strong_R.lhs()}, not_exprt{strong_R.rhs()}};
124+
return sva_until_exprt{
125+
not_exprt{s_until_with.rhs()}, not_exprt{s_until_with.lhs()}};
122126
}
123127
else if(expr.id() == ID_sva_overlapped_followed_by)
124128
{

src/verilog/sva_expr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ static inline sva_s_until_exprt &to_sva_s_until_expr(exprt &expr)
543543
return static_cast<sva_s_until_exprt &>(expr);
544544
}
545545

546+
/// SVA until_with operator -- like LTL (weak) R, but lhs/rhs swapped
546547
class sva_until_with_exprt : public binary_predicate_exprt
547548
{
548549
public:
@@ -567,6 +568,7 @@ static inline sva_until_with_exprt &to_sva_until_with_expr(exprt &expr)
567568
return static_cast<sva_until_with_exprt &>(expr);
568569
}
569570

571+
/// SVA s_until_with operator -- like LTL strong R, but lhs/rhs swapped
570572
class sva_s_until_with_exprt : public binary_predicate_exprt
571573
{
572574
public:

0 commit comments

Comments
 (0)