Skip to content

Commit d32489b

Browse files
authored
Merge pull request #283 from diffblue/bdd-refuse
ebmc: BDD engine now refuses properties it does not support
2 parents cfd7ca6 + 2375d3f commit d32489b

File tree

5 files changed

+91
-8
lines changed

5 files changed

+91
-8
lines changed

regression/ebmc/BDD/BDD_SVA1.desc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CORE
2+
BDD_SVA1.sv
3+
--bdd
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[top\.property\.p0\] always top\.my_bit: PROVED$
7+
^\[top\.property\.p1\] always top\.my_bit: PROVED$
8+
^\[top\.property\.p2\] always \(top\.counter == 3 \|-> \(nexttime top\.counter == 4\)\): UNKNOWN$
9+
^\[top\.property\.p3\] always \(top\.counter == 3 \|=> top\.counter == 4\): PROVED$
10+
^\[top\.property\.p4\] always \(top\.counter == 3 \|=> \(nexttime top\.counter == 5\)\): UNKNOWN$
11+
^\[top\.property\.p5\] always eventually top\.counter == 8: UNKNOWN$
12+
^\[top\.property\.p6\] always \(top\.counter == 0 \|-> \(eventually top\.counter == 8\)\): UNKNOWN$
13+
^\[top\.property\.p7\] always \(top\.counter == 0 \|-> \(top\.counter <= 5 until top\.counter == 6\)\): UNKNOWN$
14+
^\[top\.property\.p8\] always \(top\.counter == 0 \|-> \(top\.counter <= 5 until_with top\.counter == 5\)\): UNKNOWN$
15+
--
16+
^warning: ignoring

regression/ebmc/BDD/BDD_SVA1.sv

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module top(input clock);
2+
3+
reg my_bit;
4+
reg [31:0] counter;
5+
6+
initial my_bit=1;
7+
initial counter=0;
8+
9+
always @(posedge clock) begin
10+
my_bit=my_bit;
11+
counter=counter+1;
12+
end
13+
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 (eventually counter==8);
20+
p6: assert property (counter==0 |-> 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);
23+
24+
endmodule

src/ebmc/bdd_engine.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -419,12 +419,14 @@ void bdd_enginet::check_property(propertyt &property)
419419
message.status() << "Checking " << property.name << messaget::eom;
420420
property.status=propertyt::statust::UNKNOWN;
421421

422-
// special treatment for always
422+
// special treatment for AGp
423+
auto is_AGp = [](const exprt &expr) {
424+
return (expr.id() == ID_AG || expr.id() == ID_sva_always) &&
425+
!has_temporal_operator(to_unary_expr(expr).op());
426+
};
423427

424-
if(property.expr.id()==ID_AG ||
425-
property.expr.id()==ID_sva_always)
428+
if(is_AGp(property.expr))
426429
{
427-
// recursive call
428430
const exprt &sub_expr = to_unary_expr(property.expr).op();
429431
BDD p=property2BDD(sub_expr);
430432

@@ -491,7 +493,7 @@ void bdd_enginet::check_property(propertyt &property)
491493
peak_bdd_nodes=std::max(peak_bdd_nodes, mgr.number_of_nodes());
492494
}
493495
}
494-
else
496+
else if(!has_temporal_operator(property.expr))
495497
{
496498
// We check whether the BDD for the negation of the property
497499
// contains an initial state.

src/trans-word-level/property.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,45 @@ bool requires_lasso_constraints(const exprt &expr)
214214

215215
return false;
216216
}
217+
218+
/*******************************************************************\
219+
220+
Function: has_temporal_operator
221+
222+
Inputs:
223+
224+
Outputs:
225+
226+
Purpose:
227+
228+
\*******************************************************************/
229+
230+
bool has_temporal_operator(const exprt &expr)
231+
{
232+
for(auto subexpr_it = expr.depth_cbegin(), subexpr_end = expr.depth_cend();
233+
subexpr_it != subexpr_end;
234+
subexpr_it++)
235+
{
236+
// clang-format off
237+
if(
238+
subexpr_it->id() == ID_AG || subexpr_it->id() == ID_EG ||
239+
subexpr_it->id() == ID_AF || subexpr_it->id() == ID_EF ||
240+
subexpr_it->id() == ID_AX || subexpr_it->id() == ID_EX ||
241+
subexpr_it->id() == ID_A || subexpr_it->id() == ID_E ||
242+
subexpr_it->id() == ID_U || subexpr_it->id() == ID_R ||
243+
subexpr_it->id() == ID_G || subexpr_it->id() == ID_F ||
244+
subexpr_it->id() == ID_X ||
245+
subexpr_it->id() == ID_sva_always || subexpr_it->id() == ID_sva_always ||
246+
subexpr_it->id() == ID_sva_nexttime || subexpr_it->id() == ID_sva_s_nexttime ||
247+
subexpr_it->id() == ID_sva_until || subexpr_it->id() == ID_sva_s_until ||
248+
subexpr_it->id() == ID_sva_until_with || subexpr_it->id() == ID_sva_s_until_with ||
249+
subexpr_it->id() == ID_sva_eventually ||
250+
subexpr_it->id() == ID_sva_s_eventually)
251+
{
252+
return true;
253+
}
254+
// clang-format on
255+
}
256+
257+
return false;
258+
}

src/trans-word-level/property.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ symbol_exprt lasso_symbol(std::size_t k, std::size_t i);
3838
/// Returns true iff the given property requires lasso constraints for BMC.
3939
bool requires_lasso_constraints(const exprt &);
4040

41-
/// Returns true iff the given property is a liveness property when
42-
/// given an infinite trace.
43-
bool is_liveness_property(const exprt &);
41+
/// Returns true iff the given expression contains a temporal operator
42+
bool has_temporal_operator(const exprt &);
4443

4544
#endif

0 commit comments

Comments
 (0)