Skip to content

Commit 05174ba

Browse files
committed
Engine heuristic: fix for assumptions unsupported by k-induction
The k-induction engine now correctly reports unsupported assumptions, and is then skipped by the engine selection heuristic. Fixes #921.
1 parent cbad677 commit 05174ba

File tree

8 files changed

+85
-11
lines changed

8 files changed

+85
-11
lines changed

regression/ebmc/k-induction/k-induction6.desc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
KNOWNBUG
1+
CORE
22
k-induction6.sv
3-
3+
--k-induction
4+
^\[main\.a0\] always not s_eventually !main\.x: FAILURE: property unsupported by k-induction$
5+
^\[main\.p0\] always main\.x: INCONCLUSIVE$
46
^EXIT=10$
57
^SIGNAL=0$
68
--
79
^warning: ignoring
810
--
9-
The property should hold, but is reported as refuted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
k-induction7.sv
3+
--k-induction
4+
^\[main\.a0\] always not s_eventually !main\.y: FAILURE: property unsupported by k-induction$
5+
^\[main\.a1\] always !main\.x: ASSUMED$
6+
^\[main\.p0\] always !main\.z: PROVED$
7+
^EXIT=0$
8+
^SIGNAL=0$
9+
--
10+
^warning: ignoring
11+
--
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module main(input clk, input x, input y);
2+
3+
reg z = 0;
4+
always_ff @(posedge clk) z <= z || x;
5+
6+
// unsupported assumption
7+
a0: assume property (not s_eventually !y);
8+
9+
// supported assumption
10+
a1: assume property (!x);
11+
12+
// inductive property
13+
p0: assert property (!z);
14+
15+
endmodule

src/ebmc/ebmc_properties.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ ebmc_propertiest ebmc_propertiest::from_transition_system(
7878
id2string(symbol.location.get_comment());
7979

8080
// Don't try to prove assumption properties.
81-
if(symbol.value.id() == ID_sva_assume)
81+
if(properties.properties.back().is_assumption())
8282
{
83-
properties.properties.back().status = propertyt::statust::ASSUMED;
83+
properties.properties.back().assumed();
8484
properties.properties.back().normalized_expr =
8585
normalize_property(to_sva_assume_expr(symbol.value).op());
8686
}

src/ebmc/ebmc_properties.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ class ebmc_propertiest
103103
return status == statust::INCONCLUSIVE;
104104
}
105105

106+
void assumed()
107+
{
108+
status = statust::ASSUMED;
109+
}
110+
106111
void unknown()
107112
{
108113
status = statust::UNKNOWN;
@@ -164,6 +169,11 @@ class ebmc_propertiest
164169
{
165170
return ::is_exists_path(original_expr);
166171
}
172+
173+
bool is_assumption() const
174+
{
175+
return original_expr.id() == ID_sva_assume;
176+
}
167177
};
168178

169179
typedef std::list<propertyt> propertiest;
@@ -209,11 +219,18 @@ class ebmc_propertiest
209219
return result;
210220
}
211221

212-
void reset_failure_to_unknown()
222+
/// Resets properties/assumptions in FAILURE state to
223+
/// ASSUMED/UNKNOWN respectively.
224+
void reset_failure()
213225
{
214226
for(auto &p : properties)
215227
if(p.is_failure())
216-
p.unknown();
228+
{
229+
if(p.is_assumption())
230+
p.assumed();
231+
else
232+
p.unknown();
233+
}
217234
}
218235
};
219236

src/ebmc/k_induction.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,39 @@ Function: k_inductiont::operator()
170170

171171
void k_inductiont::operator()()
172172
{
173+
// Unsupported assumption? Mark as such.
174+
bool assumption_unsupported = false;
175+
for(auto &property : properties.properties)
176+
{
177+
if(!supported(property) && property.is_assumed())
178+
{
179+
assumption_unsupported = true;
180+
property.failure("assumption unsupported by k-induction");
181+
}
182+
}
183+
173184
// Fail unsupported properties
174185
for(auto &property : properties.properties)
175186
{
176-
if(!supported(property))
187+
if(!supported(property) && !property.is_assumed())
177188
property.failure("property unsupported by k-induction");
178189
}
179190

180191
// do induction base
181192
induction_base();
182193

194+
// Any refuted properties are really inconclusive if there are
195+
// unsupported assumptions, as the assumption might have
196+
// proven the property.
197+
if(assumption_unsupported)
198+
{
199+
for(auto &property : properties.properties)
200+
{
201+
if(property.is_refuted())
202+
property.unknown();
203+
}
204+
}
205+
183206
// do induction step
184207
induction_step();
185208
}

src/ebmc/property_checker.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,12 +384,13 @@ property_checker_resultt engine_heuristic(
384384
k_induction(
385385
1, transition_system, properties, solver_factory, message_handler);
386386

387-
properties.reset_failure_to_unknown();
387+
properties.reset_failure();
388388

389389
if(!properties.has_unknown_property())
390390
return property_checker_resultt{properties}; // done
391391

392392
// Now try BMC with bound 5, word-level
393+
message.status() << "Attempting BMC with bound 5" << messaget::eom;
393394

394395
bmc(
395396
5, // bound
@@ -400,7 +401,7 @@ property_checker_resultt engine_heuristic(
400401
solver_factory,
401402
message_handler);
402403

403-
properties.reset_failure_to_unknown();
404+
properties.reset_failure();
404405

405406
if(!properties.has_unknown_property())
406407
return property_checker_resultt{properties}; // done

src/ebmc/property_checker.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,18 @@ class property_checker_resultt
5050
bool all_properties_proved() const
5151
{
5252
for(const auto &p : properties)
53-
if(
53+
{
54+
if(p.is_assumption())
55+
{
56+
// ignore
57+
}
58+
else if(
5459
!p.is_proved() && !p.is_proved_with_bound() && !p.is_disabled() &&
5560
!p.is_assumed())
5661
{
5762
return false;
5863
}
64+
}
5965

6066
return true;
6167
}

0 commit comments

Comments
 (0)