@@ -52,6 +52,8 @@ bool bmc_supports_property(const exprt &expr)
5252 return true ;
5353 else if (expr.id () == ID_G)
5454 return true ;
55+ else if (expr.id () == ID_X)
56+ return bmc_supports_property (to_X_expr (expr).op ());
5557 else if (expr.id () == ID_sva_always)
5658 return true ;
5759 else
@@ -60,7 +62,7 @@ bool bmc_supports_property(const exprt &expr)
6062
6163/* ******************************************************************\
6264
63- Function: property
65+ Function: property_obligations_rec
6466
6567 Inputs:
6668
@@ -70,51 +72,77 @@ Function: property
7072
7173\*******************************************************************/
7274
73- std::map<std:: size_t , exprt::operandst> property_obligations (
75+ void property_obligations_rec (
7476 const exprt &property_expr,
75- message_handlert &message_handler,
7677 decision_proceduret &solver,
78+ std::size_t current,
7779 std::size_t no_timeframes,
78- const namespacet &ns)
80+ const namespacet &ns,
81+ std::map<std::size_t , exprt::operandst> &obligations)
7982{
80- PRECONDITION (no_timeframes > 0 );
83+ PRECONDITION (current < no_timeframes );
8184
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)
9286 {
93- exprt tmp = instantiate (property_expr, 0 , no_timeframes, ns);
94- obligations[0 ].push_back (solver.handle (tmp));
95- return obligations;
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+ }
9694 }
95+ else if (
96+ property_expr.id () == ID_AG || property_expr.id () == ID_G ||
97+ property_expr.id () == ID_sva_always)
98+ {
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+ }
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+ }
97123
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+ /* ******************************************************************\
109125
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
114127
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+ 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);
118146
119147 return obligations;
120148}
@@ -142,8 +170,8 @@ void property(
142170 // The first element of the pair is the length of the
143171 // counterexample, and the second is the condition that
144172 // 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);
147175
148176 // Map obligations onto timeframes.
149177 prop_handles.resize (no_timeframes, true_exprt ());
0 commit comments