8
8
9
9
#include " property.h"
10
10
11
+ #include < util/arith_tools.h>
11
12
#include < util/expr_iterator.h>
12
13
#include < util/namespace.h>
13
14
#include < util/std_expr.h>
14
15
#include < util/symbol_table.h>
15
16
17
+ #include < ebmc/ebmc_error.h>
16
18
#include < temporal-logic/temporal_expr.h>
17
19
#include < temporal-logic/temporal_logic.h>
18
20
#include < verilog/sva_expr.h>
@@ -56,6 +58,8 @@ bool bmc_supports_property(const exprt &expr)
56
58
return bmc_supports_property (to_X_expr (expr).op ());
57
59
else if (expr.id () == ID_sva_always)
58
60
return true ;
61
+ else if (expr.id () == ID_sva_ranged_always)
62
+ return true ;
59
63
else
60
64
return false ;
61
65
}
@@ -75,12 +79,12 @@ Function: property_obligations_rec
75
79
static void property_obligations_rec (
76
80
const exprt &property_expr,
77
81
decision_proceduret &solver,
78
- std:: size_t current,
79
- std:: size_t no_timeframes,
82
+ mp_integer current,
83
+ mp_integer no_timeframes,
80
84
const namespacet &ns,
81
- std::map<std:: size_t , exprt::operandst> &obligations)
85
+ std::map<mp_integer , exprt::operandst> &obligations)
82
86
{
83
- PRECONDITION (current < no_timeframes);
87
+ PRECONDITION (current >= 0 && current < no_timeframes);
84
88
85
89
if (property_expr.id () == ID_X)
86
90
{
@@ -108,11 +112,51 @@ static void property_obligations_rec(
108
112
PRECONDITION (false );
109
113
}(property_expr);
110
114
111
- for (std:: size_t c = current; c < no_timeframes; c++ )
115
+ for (mp_integer c = current; c < no_timeframes; ++c )
112
116
{
113
117
property_obligations_rec (phi, solver, c, no_timeframes, ns, obligations);
114
118
}
115
119
}
120
+ else if (
121
+ property_expr.id () == ID_sva_ranged_always ||
122
+ property_expr.id () == ID_sva_s_always)
123
+ {
124
+ auto &phi = property_expr.id () == ID_sva_ranged_always
125
+ ? to_sva_ranged_always_expr (property_expr).op ()
126
+ : to_sva_s_always_expr (property_expr).op ();
127
+ auto &range = property_expr.id () == ID_sva_ranged_always
128
+ ? to_sva_ranged_always_expr (property_expr).range ()
129
+ : to_sva_s_always_expr (property_expr).range ();
130
+
131
+ mp_integer from, to;
132
+
133
+ auto from_opt = numeric_cast<mp_integer>(range.op0 ());
134
+ if (!from_opt.has_value ())
135
+ throw ebmc_errort () << " failed to convert SVA always from index" ;
136
+
137
+ from = *from_opt;
138
+
139
+ if (range.op1 ().id () == ID_infinity)
140
+ {
141
+ to = no_timeframes - 1 ;
142
+ }
143
+ else
144
+ {
145
+ auto to_opt = numeric_cast<mp_integer>(range.op1 ());
146
+ if (!to_opt.has_value ())
147
+ throw ebmc_errort () << " failed to convert SVA always to index" ;
148
+ to = *to_opt;
149
+ }
150
+
151
+ for (mp_integer c = from; c <= to; ++c)
152
+ {
153
+ if (c >= 0 && c < no_timeframes)
154
+ {
155
+ property_obligations_rec (
156
+ phi, solver, c, no_timeframes, ns, obligations);
157
+ }
158
+ }
159
+ }
116
160
else
117
161
{
118
162
// current state property
@@ -133,13 +177,13 @@ Function: property_obligations
133
177
134
178
\*******************************************************************/
135
179
136
- static std::map<std:: size_t , exprt::operandst> property_obligations (
180
+ static std::map<mp_integer , exprt::operandst> property_obligations (
137
181
const exprt &property_expr,
138
182
decision_proceduret &solver,
139
- std:: size_t no_timeframes,
183
+ mp_integer no_timeframes,
140
184
const namespacet &ns)
141
185
{
142
- std::map<std:: size_t , exprt::operandst> obligations;
186
+ std::map<mp_integer , exprt::operandst> obligations;
143
187
144
188
property_obligations_rec (
145
189
property_expr, solver, 0 , no_timeframes, ns, obligations);
@@ -178,8 +222,10 @@ void property(
178
222
for (auto &obligation_it : obligations)
179
223
{
180
224
auto t = obligation_it.first ;
181
- DATA_INVARIANT (t < no_timeframes, " obligation must have valid timeframe" );
182
- prop_handles[t] = conjunction (obligation_it.second );
225
+ DATA_INVARIANT (
226
+ t >= 0 && t < no_timeframes, " obligation must have valid timeframe" );
227
+ auto t_int = numeric_cast_v<std::size_t >(t);
228
+ prop_handles[t_int] = conjunction (obligation_it.second );
183
229
}
184
230
}
185
231
0 commit comments