Skip to content

Commit

Permalink
BMC for F phi
Browse files Browse the repository at this point in the history
This adds support for properties of the type F phi and AF p to the BMC
engine.
  • Loading branch information
kroening committed Apr 21, 2024
1 parent d3071f4 commit 8147a2a
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 4 deletions.
2 changes: 1 addition & 1 deletion regression/ebmc/smv/bmc_unsupported_property1.desc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ bmc_unsupported_property1.smv

^EXIT=10$
^SIGNAL=0$
^\[main::spec1\] !G main::var::x = FALSE: FAILURE: property not supported by BMC engine$
^\[main::spec1\] EG main::var::x = FALSE: FAILURE: property not supported by BMC engine$
^\[main::spec2\] G main::var::x = FALSE: REFUTED$
--
^warning: ignoring
2 changes: 1 addition & 1 deletion regression/ebmc/smv/bmc_unsupported_property1.smv
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ VAR x : boolean;

ASSIGN init(x) := 1;

LTLSPEC !G x=0
SPEC EG x=0
LTLSPEC G x=0
2 changes: 1 addition & 1 deletion regression/ebmc/smv/bmc_unsupported_property2.desc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ bmc_unsupported_property2.smv

^EXIT=10$
^SIGNAL=0$
^\[main::spec1\] !G main::var::x = FALSE: FAILURE: property not supported by BMC engine$
^\[main::spec1\] EG main::var::x = FALSE: FAILURE: property not supported by BMC engine$
^\[main::spec2\] G main::var::x = TRUE: PROVED up to bound 1$
--
^warning: ignoring
2 changes: 1 addition & 1 deletion regression/ebmc/smv/bmc_unsupported_property2.smv
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ VAR x : boolean;
ASSIGN init(x) := 1;
ASSIGN next(x) := x;

LTLSPEC !G x=0 -- unsupported
SPEC EG x=0 -- unsupported
LTLSPEC G x=1 -- should pass
13 changes: 13 additions & 0 deletions regression/ebmc/smv/smv_ltlspec4.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE broken-smt-backend
smv_ltlspec4.smv
--bound 10 --numbered-trace
^EXIT=10$
^SIGNAL=0$
^\[main::spec1\] F main::var::x = 0: REFUTED$
^main::var::x@0 = 1$
^main::var::x@1 = 2$
^main::var::x@2 = 2$
^\[main::spec2\] F main::var::x = 2: PROVED up to bound 10$
--
^warning: ignoring
--
10 changes: 10 additions & 0 deletions regression/ebmc/smv/smv_ltlspec4.smv
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
MODULE main

VAR x : 0..2;

ASSIGN
init(x) := 1;
next(x) := 2;

LTLSPEC F x=0 -- fails
LTLSPEC F x=2 -- holds
10 changes: 10 additions & 0 deletions src/temporal-logic/normalize_property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ exprt normalize_pre_not(not_exprt expr)
{
return to_not_expr(op).op();
}
else if(op.id() == ID_G)
{
// ¬Gφ --> F¬φ
return F_exprt{not_exprt{to_G_expr(op).op()}};
}
else if(op.id() == ID_F)
{
// ¬Fφ --> G¬φ
return G_exprt{not_exprt{to_F_expr(op).op()}};
}

return std::move(expr);
}
Expand Down
2 changes: 2 additions & 0 deletions src/temporal-logic/normalize_property.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Author: Daniel Kroening, [email protected]
/// ¬(a ∨ b) --> ¬a ∧ ¬b
/// ¬(a ∧ b) --> ¬a ∨ ¬b
/// ¬¬φ --> φ
/// ¬Gφ --> F¬φ
/// ¬Fφ --> G¬φ
exprt normalize_property(exprt);

#endif
35 changes: 35 additions & 0 deletions src/trans-word-level/property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ bool bmc_supports_property(const exprt &expr)
return true;
else if(expr.id() == ID_G)
return true;
else if(expr.id() == ID_AF)
return true;
else if(expr.id() == ID_F)
return true;
else if(expr.id() == ID_X)
return bmc_supports_property(to_X_expr(expr).op());
else if(expr.id() == ID_sva_always)
Expand Down Expand Up @@ -117,6 +121,37 @@ static void property_obligations_rec(
property_obligations_rec(phi, solver, c, no_timeframes, ns, obligations);
}
}
else if(
property_expr.id() == ID_AF || property_expr.id() == ID_F ||
property_expr.id() == ID_sva_s_eventually)
{
const auto &phi = to_unary_expr(property_expr).op();

// Counterexamples to Fφ must have a loop.
// We consider l-k loops with l<k.
for(mp_integer k = current + 1; k < no_timeframes; ++k)
{
// The following needs to be satisfied for a counterexample
// to Fφ that loops back in timeframe k:
//
// (1) There is a loop from timeframe k back to
// some earlier state l with current<=l<k.
// (2) No state j with current<=j<=k to the end of the
// lasso satisfies 'φ'.
for(mp_integer l = current; l < k; ++l)
{
exprt::operandst disjuncts = {not_exprt(lasso_symbol(l, k))};

for(mp_integer j = current; j <= k; ++j)
{
exprt tmp = instantiate(phi, j, no_timeframes, ns);
disjuncts.push_back(std::move(tmp));
}

obligations[k].push_back(disjunction(disjuncts));
}
}
}
else if(
property_expr.id() == ID_sva_ranged_always ||
property_expr.id() == ID_sva_s_always)
Expand Down

0 comments on commit 8147a2a

Please sign in to comment.