@@ -52,6 +52,8 @@ bool bmc_supports_property(const exprt &expr)
52
52
return true ;
53
53
else if (expr.id () == ID_G)
54
54
return true ;
55
+ else if (expr.id () == ID_X)
56
+ return bmc_supports_property (to_X_expr (expr).op ());
55
57
else if (expr.id () == ID_sva_always)
56
58
return true ;
57
59
else
@@ -60,7 +62,7 @@ bool bmc_supports_property(const exprt &expr)
60
62
61
63
/* ******************************************************************\
62
64
63
- Function: property
65
+ Function: property_obligations_rec
64
66
65
67
Inputs:
66
68
@@ -70,51 +72,77 @@ Function: property
70
72
71
73
\*******************************************************************/
72
74
73
- std::map<std:: size_t , exprt::operandst> property_obligations (
75
+ static void property_obligations_rec (
74
76
const exprt &property_expr,
75
- message_handlert &message_handler,
76
77
decision_proceduret &solver,
78
+ std::size_t current,
77
79
std::size_t no_timeframes,
78
- const namespacet &ns)
80
+ const namespacet &ns,
81
+ std::map<std::size_t , exprt::operandst> &obligations)
79
82
{
80
- PRECONDITION (no_timeframes > 0 );
83
+ PRECONDITION (current < no_timeframes );
81
84
82
- std::map<std::size_t , exprt::operandst> obligations;
83
-
84
- messaget message (message_handler);
85
-
86
- // Initial state only property?
87
- if (
88
- !is_temporal_operator (property_expr) ||
89
- property_expr.id () == ID_sva_cycle_delay ||
90
- property_expr.id () == ID_sva_nexttime ||
91
- property_expr.id () == ID_sva_s_nexttime)
85
+ if (property_expr.id () == ID_X)
86
+ {
87
+ auto next = current + 1 ;
88
+ if (next < no_timeframes)
89
+ {
90
+ auto &op = to_X_expr (property_expr).op ();
91
+ property_obligations_rec (
92
+ op, solver, next, no_timeframes, ns, obligations);
93
+ }
94
+ }
95
+ else if (
96
+ property_expr.id () == ID_AG || property_expr.id () == ID_G ||
97
+ property_expr.id () == ID_sva_always)
92
98
{
93
- exprt tmp = instantiate (property_expr, 0 , no_timeframes, ns);
94
- obligations[0 ].push_back (solver.handle (tmp));
95
- return obligations;
99
+ // We want AG phi.
100
+ auto &phi = [](const exprt &expr) -> const exprt & {
101
+ if (expr.id () == ID_AG)
102
+ return to_AG_expr (expr).op ();
103
+ else if (expr.id () == ID_G)
104
+ return to_G_expr (expr).op ();
105
+ else if (expr.id () == ID_sva_always)
106
+ return to_sva_always_expr (expr).op ();
107
+ else
108
+ PRECONDITION (false );
109
+ }(property_expr);
110
+
111
+ for (std::size_t c = current; c < no_timeframes; c++)
112
+ {
113
+ property_obligations_rec (phi, solver, c, no_timeframes, ns, obligations);
114
+ }
96
115
}
116
+ else
117
+ {
118
+ // current state property
119
+ exprt tmp = instantiate (property_expr, current, no_timeframes, ns);
120
+ obligations[current].push_back (solver.handle (tmp));
121
+ }
122
+ }
97
123
98
- // We want AG p.
99
- auto &p = [](const exprt &expr) -> const exprt & {
100
- if (expr.id () == ID_AG)
101
- return to_AG_expr (expr).op ();
102
- else if (expr.id () == ID_G)
103
- return to_G_expr (expr).op ();
104
- else if (expr.id () == ID_sva_always)
105
- return to_sva_always_expr (expr).op ();
106
- else
107
- PRECONDITION (false );
108
- }(property_expr);
124
+ /* ******************************************************************\
109
125
110
- for (std::size_t c = 0 ; c < no_timeframes; c++)
111
- {
112
- exprt tmp=
113
- instantiate (p, c, no_timeframes, ns);
126
+ Function: property_obligations
114
127
115
- auto handle = solver.handle (tmp);
116
- obligations[c].push_back (std::move (handle));
117
- }
128
+ Inputs:
129
+
130
+ Outputs:
131
+
132
+ Purpose:
133
+
134
+ \*******************************************************************/
135
+
136
+ static std::map<std::size_t , exprt::operandst> property_obligations (
137
+ const exprt &property_expr,
138
+ decision_proceduret &solver,
139
+ std::size_t no_timeframes,
140
+ const namespacet &ns)
141
+ {
142
+ std::map<std::size_t , exprt::operandst> obligations;
143
+
144
+ property_obligations_rec (
145
+ property_expr, solver, 0 , no_timeframes, ns, obligations);
118
146
119
147
return obligations;
120
148
}
@@ -142,8 +170,8 @@ void property(
142
170
// The first element of the pair is the length of the
143
171
// counterexample, and the second is the condition that
144
172
// must be valid for the property to hold.
145
- auto obligations = property_obligations (
146
- property_expr, message_handler , solver, no_timeframes, ns);
173
+ auto obligations =
174
+ property_obligations ( property_expr, solver, no_timeframes, ns);
147
175
148
176
// Map obligations onto timeframes.
149
177
prop_handles.resize (no_timeframes, true_exprt ());
0 commit comments