Skip to content

Commit

Permalink
SVA: implement #-# and #=#
Browse files Browse the repository at this point in the history
This implements the SVA followed-by operators.
  • Loading branch information
kroening committed Oct 8, 2024
1 parent 5d49def commit fc953cb
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
CORE
sequence_followed_by1.sv
followed-by1.sv
--bound 20 --numbered-trace
^\[main\.p0\] main\.x == 0 #=# \(main\.x == 1 #=# main\.x == 2\): FAILURE: property not supported by BMC engine$
^\[main\.p1\] main\.x == 0 #-# \(\(##1 main\.x == 1\) #-# \(##1 main\.x == 2\)\): FAILURE: property not supported by BMC engine$
^EXIT=10$
^\[main\.p0\] main\.x == 0 #=# \(main\.x == 1 #=# main\.x == 2\): PROVED up to bound 20$
^\[main\.p1\] main\.x == 0 #-# \(\(##1 main\.x == 1\) #-# \(##1 main\.x == 2\)\): PROVED up to bound 20$
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
Expand Down
File renamed without changes.
16 changes: 16 additions & 0 deletions src/temporal-logic/nnf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,22 @@ std::optional<exprt> negate_property_node(const exprt &expr)
auto strong_R = strong_R_exprt{s_until_with.rhs(), s_until_with.lhs()};
return weak_U_exprt{not_exprt{strong_R.lhs()}, not_exprt{strong_R.rhs()}};
}
else if(expr.id() == ID_sva_overlapped_followed_by)
{
// 1800 2017 16.12.9
// !(a #-# b) ---> a |-> !b
auto &followed_by = to_sva_followed_by_expr(expr);
auto not_b = not_exprt{followed_by.property()};
return sva_overlapped_implication_exprt{followed_by.lhs(), not_b};
}
else if(expr.id() == ID_sva_nonoverlapped_followed_by)
{
// 1800 2017 16.12.9
// !(a #=# b) ---> a |=> !b
auto &followed_by = to_sva_followed_by_expr(expr);
auto not_b = not_exprt{followed_by.property()};
return sva_non_overlapped_implication_exprt{followed_by.lhs(), not_b};
}
else
return {};
}
52 changes: 44 additions & 8 deletions src/trans-word-level/property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Author: Daniel Kroening, [email protected]

#include "instantiate_word_level.h"
#include "obligations.h"
#include "sequence.h"

#include <cstdlib>

Expand Down Expand Up @@ -109,14 +110,6 @@ Function: bmc_supports_SVA_property

bool bmc_supports_SVA_property(const exprt &expr)
{
// sva_nonoverlapped_followed_by is not supported yet
if(has_subexpr(expr, ID_sva_nonoverlapped_followed_by))
return false;

// sva_overlapped_followed_by is not supported yet
if(has_subexpr(expr, ID_sva_overlapped_followed_by))
return false;

return true;
}

Expand Down Expand Up @@ -552,6 +545,49 @@ static obligationst property_obligations_rec(
auto equal_expr = equal_exprt{sva_iff_expr.lhs(), sva_iff_expr.rhs()};
return property_obligations_rec(equal_expr, current, no_timeframes);
}
else if(
property_expr.id() == ID_sva_nonoverlapped_followed_by ||
property_expr.id() == ID_sva_overlapped_followed_by)
{
// The LHS is a sequence, the RHS is a property expression,
// the result is a property expression.
auto &followed_by = to_sva_followed_by_expr(property_expr);

// get match points for LHS sequence
auto match_points =
instantiate_sequence(followed_by.sequence(), current, no_timeframes);

exprt::operandst disjuncts;
mp_integer t = current;

for(auto &match_point : match_points)
{
mp_integer property_start = match_point.first;

// #=# advances the clock by one from the sequence match point
if(property_expr.id() == ID_sva_nonoverlapped_followed_by)
property_start += 1;

// at the end?
if(property_start >= no_timeframes)
{
// relies on NNF
t = std::max(t, no_timeframes - 1);
disjuncts.push_back(match_point.second);
}
else
{
auto obligations_rec =
property_obligations_rec(
followed_by.property(), property_start, no_timeframes)
.conjunction();

disjuncts.push_back(and_exprt{match_point.second, obligations_rec.second});
t = std::max(t, obligations_rec.first);
}
}
return obligationst{t, disjunction(disjuncts)};
}
else
{
return obligationst{
Expand Down
43 changes: 43 additions & 0 deletions src/verilog/sva_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,49 @@ static inline sva_or_exprt &to_sva_or_expr(exprt &expr)
return static_cast<sva_or_exprt &>(expr);
}

class sva_followed_by_exprt : public binary_predicate_exprt
{
public:
const exprt &sequence() const
{
return op0();
}

exprt &sequence()
{
return op0();
}

const exprt &property() const
{
return op1();
}

exprt &property()
{
return op1();
}
};

static inline const sva_followed_by_exprt &
to_sva_followed_by_expr(const exprt &expr)
{
PRECONDITION(
expr.id() == ID_sva_overlapped_followed_by ||
expr.id() == ID_sva_nonoverlapped_followed_by);
sva_followed_by_exprt::check(expr, validation_modet::INVARIANT);
return static_cast<const sva_followed_by_exprt &>(expr);
}

static inline sva_followed_by_exprt &to_sva_followed_by_expr(exprt &expr)
{
PRECONDITION(
expr.id() == ID_sva_overlapped_followed_by ||
expr.id() == ID_sva_nonoverlapped_followed_by);
sva_followed_by_exprt::check(expr, validation_modet::INVARIANT);
return static_cast<sva_followed_by_exprt &>(expr);
}

class sva_cycle_delay_exprt : public ternary_exprt
{
public:
Expand Down

0 comments on commit fc953cb

Please sign in to comment.