@@ -78,6 +78,54 @@ bool bmc_supports_property(const exprt &expr)
78
78
79
79
/* ******************************************************************\
80
80
81
+ Function: max_property_obligation
82
+
83
+ Inputs:
84
+
85
+ Outputs:
86
+
87
+ Purpose:
88
+
89
+ \*******************************************************************/
90
+
91
+ static void property_obligations_rec (
92
+ const exprt &property_expr,
93
+ decision_proceduret &,
94
+ const mp_integer ¤t,
95
+ const mp_integer &no_timeframes,
96
+ const namespacet &,
97
+ std::map<mp_integer, exprt::operandst> &obligations);
98
+
99
+ static std::pair<mp_integer, exprt> max_property_obligation (
100
+ const exprt &property_expr,
101
+ decision_proceduret &solver,
102
+ const mp_integer ¤t,
103
+ const mp_integer &no_timeframes,
104
+ const namespacet &ns)
105
+ {
106
+ // Generate one obligation, equivalent to the conjunction
107
+ // for the maximum timeframe.
108
+
109
+ std::map<mp_integer, exprt::operandst> obligations;
110
+
111
+ property_obligations_rec (
112
+ property_expr, solver, current, no_timeframes, ns, obligations);
113
+
114
+ exprt::operandst conjuncts;
115
+ mp_integer max_timeframe = 0 ;
116
+
117
+ for (auto &[timeframe, exprs] : obligations)
118
+ {
119
+ max_timeframe = std::max (max_timeframe, timeframe);
120
+ for (auto &conjunct : exprs)
121
+ conjuncts.push_back (conjunct);
122
+ }
123
+
124
+ return std::pair<mp_integer, exprt>{max_timeframe, conjunction (conjuncts)};
125
+ }
126
+
127
+ /* ******************************************************************\
128
+
81
129
Function: property_obligations_rec
82
130
83
131
Inputs:
@@ -198,10 +246,28 @@ static void property_obligations_rec(
198
246
}
199
247
else if (property_expr.id () == ID_and)
200
248
{
249
+ // generate seperate obligations for each conjunct
201
250
for (auto &op : to_and_expr (property_expr).operands ())
202
251
property_obligations_rec (
203
252
op, solver, current, no_timeframes, ns, obligations);
204
253
}
254
+ else if (property_expr.id () == ID_or)
255
+ {
256
+ // generate one obligation, equivalent to the disjunction,
257
+ // for the maximum timeframe
258
+ mp_integer max_timeframe = 0 ;
259
+ exprt::operandst disjuncts;
260
+
261
+ for (auto &op : to_or_expr (property_expr).operands ())
262
+ {
263
+ auto obligation =
264
+ max_property_obligation (op, solver, current, no_timeframes, ns);
265
+ max_timeframe = std::max (max_timeframe, obligation.first );
266
+ disjuncts.push_back (obligation.second );
267
+ }
268
+
269
+ obligations[max_timeframe].push_back (disjunction (disjuncts));
270
+ }
205
271
else
206
272
{
207
273
// current state property
0 commit comments