Skip to content

Commit

Permalink
Engine heuristic: fix for assumptions unsupported by k-induction
Browse files Browse the repository at this point in the history
The k-induction engine now correctly reports unsupported assumptions, and is
then skipped by the engine selection heuristic.

Fixes #921.
  • Loading branch information
kroening committed Jan 14, 2025
1 parent cbad677 commit 05174ba
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 11 deletions.
7 changes: 4 additions & 3 deletions regression/ebmc/k-induction/k-induction6.desc
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
KNOWNBUG
CORE
k-induction6.sv

--k-induction
^\[main\.a0\] always not s_eventually !main\.x: FAILURE: property unsupported by k-induction$
^\[main\.p0\] always main\.x: INCONCLUSIVE$
^EXIT=10$
^SIGNAL=0$
--
^warning: ignoring
--
The property should hold, but is reported as refuted.
11 changes: 11 additions & 0 deletions regression/ebmc/k-induction/k-induction7.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CORE
k-induction7.sv
--k-induction
^\[main\.a0\] always not s_eventually !main\.y: FAILURE: property unsupported by k-induction$
^\[main\.a1\] always !main\.x: ASSUMED$
^\[main\.p0\] always !main\.z: PROVED$
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
--
15 changes: 15 additions & 0 deletions regression/ebmc/k-induction/k-induction7.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module main(input clk, input x, input y);

reg z = 0;
always_ff @(posedge clk) z <= z || x;

// unsupported assumption
a0: assume property (not s_eventually !y);

// supported assumption
a1: assume property (!x);

// inductive property
p0: assert property (!z);

endmodule
4 changes: 2 additions & 2 deletions src/ebmc/ebmc_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ ebmc_propertiest ebmc_propertiest::from_transition_system(
id2string(symbol.location.get_comment());

// Don't try to prove assumption properties.
if(symbol.value.id() == ID_sva_assume)
if(properties.properties.back().is_assumption())
{
properties.properties.back().status = propertyt::statust::ASSUMED;
properties.properties.back().assumed();
properties.properties.back().normalized_expr =
normalize_property(to_sva_assume_expr(symbol.value).op());
}
Expand Down
21 changes: 19 additions & 2 deletions src/ebmc/ebmc_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ class ebmc_propertiest
return status == statust::INCONCLUSIVE;
}

void assumed()
{
status = statust::ASSUMED;
}

void unknown()
{
status = statust::UNKNOWN;
Expand Down Expand Up @@ -164,6 +169,11 @@ class ebmc_propertiest
{
return ::is_exists_path(original_expr);
}

bool is_assumption() const
{
return original_expr.id() == ID_sva_assume;
}
};

typedef std::list<propertyt> propertiest;
Expand Down Expand Up @@ -209,11 +219,18 @@ class ebmc_propertiest
return result;
}

void reset_failure_to_unknown()
/// Resets properties/assumptions in FAILURE state to
/// ASSUMED/UNKNOWN respectively.
void reset_failure()
{
for(auto &p : properties)
if(p.is_failure())
p.unknown();
{
if(p.is_assumption())
p.assumed();
else
p.unknown();
}
}
};

Expand Down
25 changes: 24 additions & 1 deletion src/ebmc/k_induction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,39 @@ Function: k_inductiont::operator()

void k_inductiont::operator()()
{
// Unsupported assumption? Mark as such.
bool assumption_unsupported = false;
for(auto &property : properties.properties)
{
if(!supported(property) && property.is_assumed())
{
assumption_unsupported = true;
property.failure("assumption unsupported by k-induction");
}
}

// Fail unsupported properties
for(auto &property : properties.properties)
{
if(!supported(property))
if(!supported(property) && !property.is_assumed())
property.failure("property unsupported by k-induction");
}

// do induction base
induction_base();

// Any refuted properties are really inconclusive if there are
// unsupported assumptions, as the assumption might have
// proven the property.
if(assumption_unsupported)
{
for(auto &property : properties.properties)
{
if(property.is_refuted())
property.unknown();
}
}

// do induction step
induction_step();
}
Expand Down
5 changes: 3 additions & 2 deletions src/ebmc/property_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,12 +384,13 @@ property_checker_resultt engine_heuristic(
k_induction(
1, transition_system, properties, solver_factory, message_handler);

properties.reset_failure_to_unknown();
properties.reset_failure();

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

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

bmc(
5, // bound
Expand All @@ -400,7 +401,7 @@ property_checker_resultt engine_heuristic(
solver_factory,
message_handler);

properties.reset_failure_to_unknown();
properties.reset_failure();

if(!properties.has_unknown_property())
return property_checker_resultt{properties}; // done
Expand Down
8 changes: 7 additions & 1 deletion src/ebmc/property_checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,18 @@ class property_checker_resultt
bool all_properties_proved() const
{
for(const auto &p : properties)
if(
{
if(p.is_assumption())
{
// ignore
}
else if(
!p.is_proved() && !p.is_proved_with_bound() && !p.is_disabled() &&
!p.is_assumed())
{
return false;
}
}

return true;
}
Expand Down

0 comments on commit 05174ba

Please sign in to comment.