@@ -11,6 +11,7 @@ Author: Daniel Kroening, kroening@kroening.com
1111#include < util/ebmc_util.h>
1212#include < util/expr_util.h>
1313
14+ #include < ebmc/ebmc_error.h>
1415#include < temporal-logic/temporal_expr.h>
1516#include < temporal-logic/temporal_logic.h>
1617#include < verilog/sva_expr.h>
@@ -428,6 +429,45 @@ wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
428429 DATA_INVARIANT (no_timeframes != 0 , " must have timeframe" );
429430 return {no_timeframes - 1 , conjunction (conjuncts)};
430431 }
432+ else if (expr.id () == ID_sva_ranged_s_eventually)
433+ {
434+ auto &phi = to_sva_ranged_s_eventually_expr (expr).op ();
435+ auto &lower = to_sva_ranged_s_eventually_expr (expr).lower ();
436+ auto &upper = to_sva_ranged_s_eventually_expr (expr).upper ();
437+
438+ auto from_opt = numeric_cast<mp_integer>(lower);
439+ if (!from_opt.has_value ())
440+ throw ebmc_errort () << " failed to convert SVA s_eventually from index" ;
441+
442+ auto from = t + std::max (mp_integer{0 }, *from_opt);
443+
444+ mp_integer to;
445+
446+ if (upper.id () == ID_infinity)
447+ {
448+ throw ebmc_errort ()
449+ << " failed to convert SVA s_eventually to index (infinity)" ;
450+ }
451+ else
452+ {
453+ auto to_opt = numeric_cast<mp_integer>(upper);
454+ if (!to_opt.has_value ())
455+ throw ebmc_errort () << " failed to convert SVA s_eventually to index" ;
456+ to = std::min (t + *to_opt, no_timeframes - 1 );
457+ }
458+
459+ exprt::operandst disjuncts;
460+ mp_integer time = 0 ;
461+
462+ for (mp_integer c = from; c <= to; ++c)
463+ {
464+ auto tmp = instantiate_property (phi, c, no_timeframes, ns);
465+ time = std::max (time, tmp.first );
466+ disjuncts.push_back (tmp.second );
467+ }
468+
469+ return {time, disjunction (disjuncts)};
470+ }
431471 else if (expr.id ()==ID_sva_until ||
432472 expr.id ()==ID_sva_s_until)
433473 {
0 commit comments