@@ -77,7 +77,8 @@ class wl_instantiatet
7777 }
7878
7979 // / Instantiate the given expression for timeframe t
80- [[nodiscard]] exprt operator ()(exprt expr, const mp_integer &t) const
80+ [[nodiscard]] std::pair<mp_integer, exprt>
81+ operator ()(exprt expr, const mp_integer &t) const
8182 {
8283 return instantiate_rec (std::move (expr), t);
8384 }
@@ -86,7 +87,8 @@ class wl_instantiatet
8687 const mp_integer &no_timeframes;
8788 const namespacet &ns;
8889
89- [[nodiscard]] exprt instantiate_rec (exprt, const mp_integer &t) const ;
90+ [[nodiscard]] std::pair<mp_integer, exprt>
91+ instantiate_rec (exprt, const mp_integer &t) const ;
9092 [[nodiscard]] typet instantiate_rec (typet, const mp_integer &t) const ;
9193};
9294
@@ -123,18 +125,20 @@ Function: wl_instantiatet::instantiate_rec
123125
124126\*******************************************************************/
125127
126- exprt wl_instantiatet::instantiate_rec (exprt expr, const mp_integer &t) const
128+ std::pair<mp_integer, exprt>
129+ wl_instantiatet::instantiate_rec (exprt expr, const mp_integer &t) const
127130{
128131 expr.type () = instantiate_rec (expr.type (), t);
129132
130133 if (expr.id () == ID_next_symbol)
131134 {
132135 expr.id (ID_symbol);
133- return timeframe_symbol (t + 1 , to_symbol_expr (std::move (expr)));
136+ auto u = t + 1 ;
137+ return {u, timeframe_symbol (u, to_symbol_expr (std::move (expr)))};
134138 }
135139 else if (expr.id () == ID_symbol)
136140 {
137- return timeframe_symbol (t, to_symbol_expr (std::move (expr)));
141+ return {t, timeframe_symbol (t, to_symbol_expr (std::move (expr)))} ;
138142 }
139143 else if (expr.id ()==ID_sva_cycle_delay) // ##[1:2] something
140144 {
@@ -150,7 +154,7 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
150154
151155 // Do we exceed the bound? Make it 'true'
152156 if (u >= no_timeframes)
153- return true_exprt ();
157+ return {no_timeframes - 1 , true_exprt ()} ;
154158 else
155159 return instantiate_rec (sva_cycle_delay_expr.op (), u);
156160 }
@@ -168,35 +172,29 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
168172 else if (to_integer_non_constant (sva_cycle_delay_expr.to (), to))
169173 throw " failed to convert sva_cycle_delay offsets" ;
170174
171- // This is an 'or', and we let it fail if the bound is too small.
175+ auto lower = t + from;
176+ auto upper = t + to;
177+
178+ // Do we exceed the bound? Make it 'true'
179+ if (upper >= no_timeframes)
180+ return {no_timeframes - 1 , true_exprt ()};
172181
173182 exprt::operandst disjuncts;
174183
175- for (mp_integer offset = from; offset < to ; ++offset )
184+ for (mp_integer u = lower; u <= upper ; ++u )
176185 {
177- auto u = t + offset;
178-
179- if (u >= no_timeframes)
180- {
181- }
182- else
183- {
184- disjuncts.push_back (instantiate_rec (sva_cycle_delay_expr.op (), u));
185- }
186+ disjuncts.push_back (
187+ instantiate_rec (sva_cycle_delay_expr.op (), u).second );
186188 }
187189
188- return disjunction (disjuncts);
190+ return {upper, disjunction (disjuncts)} ;
189191 }
190192 }
191193 else if (expr.id ()==ID_sva_sequence_concatenation)
192194 {
193195 // much like regular 'and'
194196 expr.id (ID_and);
195-
196- for (auto &op : expr.operands ())
197- op = instantiate_rec (op, t);
198-
199- return expr;
197+ return instantiate_rec (expr, t);
200198 }
201199 else if (expr.id ()==ID_sva_always)
202200 {
@@ -206,10 +204,10 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
206204
207205 for (auto u = t; u < no_timeframes; ++u)
208206 {
209- conjuncts.push_back (instantiate_rec (op, u));
207+ conjuncts.push_back (instantiate_rec (op, u). second );
210208 }
211209
212- return conjunction (conjuncts);
210+ return {no_timeframes - 1 , conjunction (conjuncts)} ;
213211 }
214212 else if (expr.id () == ID_X)
215213 {
@@ -220,7 +218,7 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
220218 return instantiate_rec (to_X_expr (expr).op (), next);
221219 }
222220 else
223- return true_exprt (); // works on NNF only
221+ return {no_timeframes - 1 , true_exprt ()} ; // works on NNF only
224222 }
225223 else if (expr.id () == ID_sva_eventually)
226224 {
@@ -238,14 +236,14 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
238236 // This is weak, and passes if any of the timeframes
239237 // does not exist.
240238 if (t + lower >= no_timeframes || t + upper >= no_timeframes)
241- return true_exprt ();
239+ return {no_timeframes - 1 , true_exprt ()} ;
242240
243241 exprt::operandst disjuncts = {};
244242
245243 for (mp_integer u = t + lower; u <= t + upper; ++u)
246- disjuncts.push_back (instantiate_rec (op, u));
244+ disjuncts.push_back (instantiate_rec (op, u). second );
247245
248- return disjunction (disjuncts);
246+ return {no_timeframes - 1 , disjunction (disjuncts)} ;
249247 }
250248 else if (
251249 expr.id () == ID_sva_s_eventually || expr.id () == ID_F || expr.id () == ID_AF)
@@ -273,13 +271,13 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
273271
274272 for (mp_integer j = k; j <= i; ++j)
275273 {
276- disjuncts.push_back (instantiate_rec (p, j));
274+ disjuncts.push_back (instantiate_rec (p, j). second );
277275 }
278276
279277 conjuncts.push_back (disjunction (disjuncts));
280278 }
281279
282- return conjunction (conjuncts);
280+ return {no_timeframes - 1 , conjunction (conjuncts)} ;
283281 }
284282 else if (expr.id ()==ID_sva_until ||
285283 expr.id ()==ID_sva_s_until)
@@ -292,19 +290,19 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
292290
293291 // we expand: p U q <=> q || (p && X(p U q))
294292 exprt tmp_q = to_binary_expr (expr).op1 ();
295- tmp_q = instantiate_rec (tmp_q, t);
293+ tmp_q = instantiate_rec (tmp_q, t). second ;
296294
297295 exprt expansion = to_binary_expr (expr).op0 ();
298- expansion = instantiate_rec (expansion, t);
296+ expansion = instantiate_rec (expansion, t). second ;
299297
300298 const auto next = t + 1 ;
301299
302300 if (next < no_timeframes)
303301 {
304- expansion = and_exprt (expansion, instantiate_rec (expr, next));
302+ expansion = and_exprt (expansion, instantiate_rec (expr, next). second );
305303 }
306304
307- return or_exprt (tmp_q, expansion);
305+ return {no_timeframes - 1 , or_exprt (tmp_q, expansion)} ;
308306 }
309307 else if (expr.id ()==ID_sva_until_with ||
310308 expr.id ()==ID_sva_s_until_with)
@@ -335,7 +333,7 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
335333 if (ticks > t)
336334 {
337335 // return the 'default value' for the type
338- return default_value (verilog_past.type ());
336+ return {t, default_value (verilog_past.type ())} ;
339337 }
340338 else
341339 {
@@ -344,9 +342,15 @@ exprt wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
344342 }
345343 else
346344 {
345+ mp_integer max = t;
347346 for (auto &op : expr.operands ())
348- op = instantiate_rec (op, t);
349- return expr;
347+ {
348+ auto tmp = instantiate_rec (op, t);
349+ op = tmp.second ;
350+ max = std::max (max, tmp.first );
351+ }
352+
353+ return {max, expr};
350354 }
351355}
352356
@@ -386,5 +390,27 @@ exprt instantiate(
386390 const namespacet &ns)
387391{
388392 wl_instantiatet wl_instantiate (no_timeframes, ns);
389- return wl_instantiate (expr, t);
393+ return wl_instantiate (expr, t).second ;
394+ }
395+
396+ /* ******************************************************************\
397+
398+ Function: instantiate_property
399+
400+ Inputs:
401+
402+ Outputs:
403+
404+ Purpose:
405+
406+ \*******************************************************************/
407+
408+ std::pair<mp_integer, exprt> instantiate_property (
409+ const exprt &expr,
410+ const mp_integer ¤t,
411+ const mp_integer &no_timeframes,
412+ const namespacet &ns)
413+ {
414+ wl_instantiatet wl_instantiate (no_timeframes, ns);
415+ return wl_instantiate (expr, current);
390416}
0 commit comments