Skip to content

Commit 4fbc67e

Browse files
committed
Buechi: identify special cases where reachability is sufficient
This adds treatment for the special case where all nonaccepting states of the Buechi automaton have an unconditional self-loop. In this case, when these nonaccepting states is reached, the trace cannot be extended to an accepting trace, and will hence be rejected. Hence, in this case, the Buechi acceptance condition is unnecessary, and a simple reachability property is sufficient.
1 parent f817354 commit 4fbc67e

File tree

7 files changed

+55
-23
lines changed

7 files changed

+55
-23
lines changed

regression/ebmc-spot/sva-buechi/sequence5.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
../../verilog/SVA/sequence5.sv
33
--buechi
4-
^\[main\.p0\] 1: PROVED up to bound \d+$
4+
^\[main\.p0\] 1: PROVED \(1-induction\)$
55
^\[main\.p1\] 0: REFUTED$
66
^\[main\.p2\] 1'bx: REFUTED$
77
^\[main\.p3\] 1'bz: REFUTED$

regression/ebmc-spot/sva-buechi/sva_and1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
../../verilog/SVA/sva_and1.sv
33
--buechi
4-
^\[main\.p0\] always \(1 and 1\): PROVED up to bound \d+$
4+
^\[main\.p0\] always \(1 and 1\): PROVED \(1-induction\)$
55
^\[main\.p1\] always \(1 and 0\): REFUTED$
66
^\[main\.p2\] always \(1 and 32'b0000000000000000000000000000000x\): REFUTED$
77
^EXIT=10$

regression/ebmc-spot/sva-buechi/sva_iff1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
../../verilog/SVA/sva_iff1.sv
33
--buechi
4-
^\[main\.p0\] always \(1 iff 1\): PROVED up to bound \d+$
4+
^\[main\.p0\] always \(1 iff 1\): PROVED \(1-induction\)$
55
^\[main\.p1\] always \(1 iff 0\): REFUTED$
66
^\[main\.p2\] always \(1 iff 32'b0000000000000000000000000000000x\): REFUTED$
77
^EXIT=10$

regression/ebmc-spot/sva-buechi/sva_implies1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
../../verilog/SVA/sva_implies1.sv
33
--buechi
4-
^\[main\.p0\] always \(1 implies 1\): PROVED up to bound \d+$
4+
^\[main\.p0\] always \(1 implies 1\): PROVED \(1-induction\)$
55
^\[main\.p1\] always \(1 implies 0\): REFUTED$
66
^\[main\.p2\] always \(1 implies 32'b0000000000000000000000000000000x\): REFUTED$
77
^EXIT=10$

regression/ebmc-spot/sva-buechi/sva_not1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
../../verilog/SVA/sva_not1.sv
33
--buechi
4-
^\[main\.p0] always not 0: PROVED up to bound \d+$
4+
^\[main\.p0] always not 0: PROVED \(1-induction\)$
55
^\[main\.p1] always not 1: REFUTED$
66
^EXIT=10$
77
^SIGNAL=0$

src/ebmc/instrument_buechi.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,24 @@ void instrument_buechi(
6464
transition_system.trans_expr.trans() =
6565
and_exprt{transition_system.trans_expr.trans(), buechi.trans};
6666

67-
// Replace the normalized property expression.
68-
// Note that we have negated the property,
69-
// so this is the negation of the Buechi acceptance condition.
70-
property.normalized_expr =
71-
F_exprt{G_exprt{not_exprt{buechi.liveness_signal}}};
67+
// Replace the normalized property expression
68+
// by the Buechi acceptance condition.
69+
exprt::operandst property_conjuncts;
70+
71+
if(!buechi.liveness_signal.is_false())
72+
{
73+
// Note that we have negated the property,
74+
// so this is the negation of the Buechi acceptance condition.
75+
property_conjuncts.push_back(
76+
F_exprt{G_exprt{not_exprt{buechi.liveness_signal}}});
77+
}
7278

7379
if(!buechi.error_signal.is_true())
74-
property.normalized_expr = and_exprt{
75-
property.normalized_expr, G_exprt{not_exprt{buechi.error_signal}}};
80+
{
81+
property_conjuncts.push_back(G_exprt{not_exprt{buechi.error_signal}});
82+
}
83+
84+
property.normalized_expr = conjunction(property_conjuncts);
7685

7786
message.debug() << "New property: " << format(property.normalized_expr)
7887
<< messaget::eom;

src/temporal-logic/ltl_to_buechi.cpp

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ bool is_error_state(const std::pair<hoat::state_namet, hoat::edgest> &state)
100100
return false;
101101
}
102102

103+
/// Returns true iff all accepting states of the automaton have
104+
/// unconditional self loops
105+
bool is_safety_only(const hoat &hoa)
106+
{
107+
for(auto &state : hoa.body)
108+
if(state.first.is_accepting() && !is_error_state(state))
109+
return false;
110+
111+
return true;
112+
}
113+
103114
buechi_transt
104115
ltl_to_buechi(const exprt &property, message_handlert &message_handler)
105116
{
@@ -159,20 +170,32 @@ ltl_to_buechi(const exprt &property, message_handlert &message_handler)
159170
message.debug() << "Buechi initial state: " << format(init)
160171
<< messaget::eom;
161172

162-
// construct the liveness signal
163-
std::vector<exprt> liveness_disjuncts;
173+
exprt liveness_signal;
164174

165-
for(auto &state : hoa.body)
166-
if(state.first.is_accepting())
167-
{
168-
liveness_disjuncts.push_back(equal_exprt{
169-
buechi_state, from_integer(state.first.number, state_type)});
170-
}
175+
// Is safety sufficient?
176+
if(is_safety_only(hoa))
177+
{
178+
liveness_signal = false_exprt{};
171179

172-
auto liveness_signal = disjunction(liveness_disjuncts);
180+
message.debug() << "Buechi liveness signal not required" << messaget::eom;
181+
}
182+
else
183+
{
184+
// construct the liveness signal
185+
std::vector<exprt> liveness_disjuncts;
173186

174-
message.debug() << "Buechi liveness signal: " << format(liveness_signal)
175-
<< messaget::eom;
187+
for(auto &state : hoa.body)
188+
if(state.first.is_accepting())
189+
{
190+
liveness_disjuncts.push_back(equal_exprt{
191+
buechi_state, from_integer(state.first.number, state_type)});
192+
}
193+
194+
liveness_signal = disjunction(liveness_disjuncts);
195+
196+
message.debug() << "Buechi liveness signal: " << format(liveness_signal)
197+
<< messaget::eom;
198+
}
176199

177200
// construct the error signal -- true when the next automaton state
178201
// is nonaccepting with an unconditional self-loop.

0 commit comments

Comments
 (0)