diff --git a/src/trans-word-level/obligations.h b/src/trans-word-level/obligations.h new file mode 100644 index 000000000..b3d4c7e92 --- /dev/null +++ b/src/trans-word-level/obligations.h @@ -0,0 +1,52 @@ +/*******************************************************************\ + +Module: Unwinding the Properties + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#ifndef CPROVER_TRANS_WORD_LEVEL_OBLIGATIONS_H +#define CPROVER_TRANS_WORD_LEVEL_OBLIGATIONS_H + +#include +#include + +#include + +class obligationst +{ +public: + obligationst() = default; + + explicit obligationst(const std::pair &pair) + { + add(pair.first, pair.second); + } + + // The value are conditions that must be met for the property to hold. + // The key is the length of the counterexample if the condition is violated. + std::map map; + + // add a condition + void add(const mp_integer &t, exprt expr) + { + map[t].push_back(std::move(expr)); + } + + void add(const std::pair &pair) + { + auto &entry = map[pair.first]; + for(auto &expr : pair.second) + entry.push_back(expr); + } + + // add a set of conditions + void add(const obligationst &obligations) + { + for(auto &obligation : obligations.map) + add(obligation); + } +}; + +#endif diff --git a/src/trans-word-level/property.cpp b/src/trans-word-level/property.cpp index 11673db45..f60373ee2 100644 --- a/src/trans-word-level/property.cpp +++ b/src/trans-word-level/property.cpp @@ -21,6 +21,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "instantiate_word_level.h" +#include "obligations.h" #include @@ -209,13 +210,12 @@ Function: property_obligations_rec \*******************************************************************/ -static void property_obligations_rec( +static obligationst property_obligations_rec( const exprt &property_expr, decision_proceduret &solver, const mp_integer ¤t, const mp_integer &no_timeframes, - const namespacet &ns, - std::map &obligations) + const namespacet &ns) { PRECONDITION(current >= 0 && current < no_timeframes); @@ -235,10 +235,15 @@ static void property_obligations_rec( PRECONDITION(false); }(property_expr); + obligationst obligations; + for(mp_integer c = current; c < no_timeframes; ++c) { - property_obligations_rec(phi, solver, c, no_timeframes, ns, obligations); + obligations.add( + property_obligations_rec(phi, solver, c, no_timeframes, ns)); } + + return obligations; } else if( property_expr.id() == ID_AF || property_expr.id() == ID_F || @@ -246,6 +251,8 @@ static void property_obligations_rec( { const auto &phi = to_unary_expr(property_expr).op(); + obligationst obligations; + // Counterexamples to Fφ must have a loop. // We consider l-k loops with l property_obligations( +obligationst property_obligations( const exprt &property_expr, decision_proceduret &solver, const mp_integer &no_timeframes, const namespacet &ns) { - std::map obligations; - - property_obligations_rec( - property_expr, solver, 0, no_timeframes, ns, obligations); - - return obligations; + return property_obligations_rec(property_expr, solver, 0, no_timeframes, ns); } /*******************************************************************\ @@ -378,7 +393,7 @@ void property( // Map obligations onto timeframes. prop_handles.resize(no_timeframes, true_exprt()); - for(auto &obligation_it : obligations) + for(auto &obligation_it : obligations.map) { auto t = obligation_it.first; DATA_INVARIANT(