Skip to content

Commit b4b42b4

Browse files
authored
Merge pull request #1026 from diffblue/sva-constant-bounds
SVA: typing for constant bounds of ranged/indexed operators
2 parents cf8c331 + 5c4db76 commit b4b42b4

File tree

3 files changed

+74
-40
lines changed

3 files changed

+74
-40
lines changed

src/temporal-logic/normalize_property.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ exprt normalize_pre_sva_cycle_delay(sva_cycle_delay_exprt expr)
3838
{
3939
if(expr.is_unbounded())
4040
{
41-
if(
42-
expr.from().is_constant() &&
43-
numeric_cast_v<mp_integer>(to_constant_expr(expr.from())) == 0)
41+
if(numeric_cast_v<mp_integer>(expr.from()) == 0)
4442
{
4543
// ##[0:$] φ --> s_eventually φ
4644
return sva_s_eventually_exprt{expr.op()};

src/trans-word-level/sequence.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Author: Daniel Kroening, [email protected]
88

99
#include "sequence.h"
1010

11+
#include <util/arith_tools.h>
1112
#include <util/ebmc_util.h>
1213

1314
#include <verilog/sva_expr.h>
@@ -23,14 +24,11 @@ std::vector<std::pair<mp_integer, exprt>> instantiate_sequence(
2324
if(expr.id() == ID_sva_cycle_delay) // ##[1:2] something
2425
{
2526
auto &sva_cycle_delay_expr = to_sva_cycle_delay_expr(expr);
27+
const auto from = numeric_cast_v<mp_integer>(sva_cycle_delay_expr.from());
2628

2729
if(sva_cycle_delay_expr.to().is_nil()) // ##1 something
2830
{
29-
mp_integer offset;
30-
if(to_integer_non_constant(sva_cycle_delay_expr.from(), offset))
31-
throw "failed to convert sva_cycle_delay offset";
32-
33-
const auto u = t + offset;
31+
const auto u = t + from;
3432

3533
// Do we exceed the bound? Make it 'true'
3634
if(u >= no_timeframes)
@@ -44,9 +42,7 @@ std::vector<std::pair<mp_integer, exprt>> instantiate_sequence(
4442
}
4543
else
4644
{
47-
mp_integer from, to;
48-
if(to_integer_non_constant(sva_cycle_delay_expr.from(), from))
49-
throw "failed to convert sva_cycle_delay offsets";
45+
mp_integer to;
5046

5147
if(sva_cycle_delay_expr.to().id() == ID_infinity)
5248
{

src/verilog/sva_expr.h

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -137,22 +137,22 @@ static inline sva_s_nexttime_exprt &to_sva_s_nexttime_expr(exprt &expr)
137137
class sva_indexed_nexttime_exprt : public binary_predicate_exprt
138138
{
139139
public:
140-
sva_indexed_nexttime_exprt(exprt index, exprt op)
140+
sva_indexed_nexttime_exprt(constant_exprt index, exprt op)
141141
: binary_predicate_exprt(
142142
std::move(index),
143143
ID_sva_indexed_nexttime,
144144
std::move(op))
145145
{
146146
}
147147

148-
const exprt &index() const
148+
const constant_exprt &index() const
149149
{
150-
return op0();
150+
return static_cast<const constant_exprt &>(op0());
151151
}
152152

153-
exprt &index()
153+
constant_exprt &index()
154154
{
155-
return op0();
155+
return static_cast<constant_exprt &>(op0());
156156
}
157157

158158
const exprt &op() const
@@ -190,22 +190,22 @@ to_sva_indexed_nexttime_expr(exprt &expr)
190190
class sva_indexed_s_nexttime_exprt : public binary_predicate_exprt
191191
{
192192
public:
193-
sva_indexed_s_nexttime_exprt(exprt index, exprt op)
193+
sva_indexed_s_nexttime_exprt(constant_exprt index, exprt op)
194194
: binary_predicate_exprt(
195195
std::move(index),
196196
ID_sva_indexed_s_nexttime,
197197
std::move(op))
198198
{
199199
}
200200

201-
const exprt &index() const
201+
const constant_exprt &index() const
202202
{
203-
return op0();
203+
return static_cast<const constant_exprt &>(op0());
204204
}
205205

206-
exprt &index()
206+
constant_exprt &index()
207207
{
208-
return op0();
208+
return static_cast<constant_exprt &>(op0());
209209
}
210210

211211
const exprt &op() const
@@ -239,31 +239,34 @@ to_sva_indexed_s_nexttime_expr(exprt &expr)
239239
return static_cast<sva_indexed_s_nexttime_exprt &>(expr);
240240
}
241241

242+
/// For ranged SVA operators. The lower bound must be a constant
243+
/// post elaboration. The upper end need not be bounded,
244+
/// i.e., given as $
242245
class sva_ranged_predicate_exprt : public ternary_exprt
243246
{
244247
public:
245248
sva_ranged_predicate_exprt(
246249
irep_idt __id,
247-
exprt __lower,
250+
constant_exprt __lower,
248251
exprt __upper,
249252
exprt __op)
250253
: ternary_exprt(
251254
__id,
252255
std::move(__lower),
253256
std::move(__upper),
254257
std::move(__op),
255-
bool_typet())
258+
bool_typet{})
256259
{
257260
}
258261

259-
const exprt &lower() const
262+
const constant_exprt &lower() const
260263
{
261-
return op0();
264+
return static_cast<const constant_exprt &>(op0());
262265
}
263266

264-
exprt &lower()
267+
constant_exprt &lower()
265268
{
266-
return op0();
269+
return static_cast<constant_exprt &>(op0());
267270
}
268271

269272
const exprt &upper() const
@@ -292,11 +295,44 @@ class sva_ranged_predicate_exprt : public ternary_exprt
292295
using ternary_exprt::op2;
293296
};
294297

295-
class sva_eventually_exprt : public sva_ranged_predicate_exprt
298+
/// A specialisation of sva_ranged_predicate_exprt where both bounds
299+
/// are constants.
300+
class sva_bounded_range_predicate_exprt : public sva_ranged_predicate_exprt
296301
{
297302
public:
298-
sva_eventually_exprt(exprt __lower, exprt __upper, exprt __op)
303+
sva_bounded_range_predicate_exprt(
304+
irep_idt __id,
305+
constant_exprt __lower,
306+
constant_exprt __upper,
307+
exprt __op)
299308
: sva_ranged_predicate_exprt(
309+
__id,
310+
std::move(__lower),
311+
std::move(__upper),
312+
std::move(__op))
313+
{
314+
}
315+
316+
const constant_exprt &upper() const
317+
{
318+
return static_cast<const constant_exprt &>(
319+
sva_ranged_predicate_exprt::upper());
320+
}
321+
322+
constant_exprt &upper()
323+
{
324+
return static_cast<constant_exprt &>(sva_ranged_predicate_exprt::upper());
325+
}
326+
};
327+
328+
class sva_eventually_exprt : public sva_bounded_range_predicate_exprt
329+
{
330+
public:
331+
sva_eventually_exprt(
332+
constant_exprt __lower,
333+
constant_exprt __upper,
334+
exprt __op)
335+
: sva_bounded_range_predicate_exprt(
300336
ID_sva_eventually,
301337
std::move(__lower),
302338
std::move(__upper),
@@ -347,7 +383,10 @@ static inline sva_s_eventually_exprt &to_sva_s_eventually_expr(exprt &expr)
347383
class sva_ranged_s_eventually_exprt : public sva_ranged_predicate_exprt
348384
{
349385
public:
350-
explicit sva_ranged_s_eventually_exprt(exprt lower, exprt upper, exprt op)
386+
explicit sva_ranged_s_eventually_exprt(
387+
constant_exprt lower,
388+
exprt upper,
389+
exprt op)
351390
: sva_ranged_predicate_exprt(
352391
ID_sva_ranged_s_eventually,
353392
std::move(lower),
@@ -399,7 +438,7 @@ static inline sva_always_exprt &to_sva_always_expr(exprt &expr)
399438
class sva_ranged_always_exprt : public sva_ranged_predicate_exprt
400439
{
401440
public:
402-
sva_ranged_always_exprt(exprt lower, exprt upper, exprt op)
441+
sva_ranged_always_exprt(constant_exprt lower, exprt upper, exprt op)
403442
: sva_ranged_predicate_exprt(
404443
ID_sva_ranged_always,
405444
std::move(lower),
@@ -424,11 +463,11 @@ static inline sva_ranged_always_exprt &to_sva_ranged_always_expr(exprt &expr)
424463
return static_cast<sva_ranged_always_exprt &>(expr);
425464
}
426465

427-
class sva_s_always_exprt : public sva_ranged_predicate_exprt
466+
class sva_s_always_exprt : public sva_bounded_range_predicate_exprt
428467
{
429468
public:
430-
sva_s_always_exprt(exprt lower, exprt upper, exprt op)
431-
: sva_ranged_predicate_exprt(
469+
sva_s_always_exprt(constant_exprt lower, constant_exprt upper, exprt op)
470+
: sva_bounded_range_predicate_exprt(
432471
ID_sva_s_always,
433472
std::move(lower),
434473
std::move(upper),
@@ -841,7 +880,8 @@ static inline sva_followed_by_exprt &to_sva_followed_by_expr(exprt &expr)
841880
class sva_cycle_delay_exprt : public ternary_exprt
842881
{
843882
public:
844-
sva_cycle_delay_exprt(exprt from, exprt to, exprt op)
883+
/// The upper bound may be $
884+
sva_cycle_delay_exprt(constant_exprt from, exprt to, exprt op)
845885
: ternary_exprt(
846886
ID_sva_cycle_delay,
847887
std::move(from),
@@ -851,7 +891,7 @@ class sva_cycle_delay_exprt : public ternary_exprt
851891
{
852892
}
853893

854-
sva_cycle_delay_exprt(exprt cycles, exprt op)
894+
sva_cycle_delay_exprt(constant_exprt cycles, exprt op)
855895
: ternary_exprt(
856896
ID_sva_cycle_delay,
857897
std::move(cycles),
@@ -861,14 +901,14 @@ class sva_cycle_delay_exprt : public ternary_exprt
861901
{
862902
}
863903

864-
const exprt &from() const
904+
const constant_exprt &from() const
865905
{
866-
return op0();
906+
return static_cast<const constant_exprt &>(op0());
867907
}
868908

869-
exprt &from()
909+
constant_exprt &from()
870910
{
871-
return op0();
911+
return static_cast<constant_exprt &>(op0());
872912
}
873913

874914
// may be nil (just the singleton 'from') or

0 commit comments

Comments
 (0)