@@ -18,6 +18,63 @@ Author: Daniel Kroening, kroening@kroening.com
1818#include " obligations.h"
1919#include " property.h"
2020
21+ // condition on counters for ocurrences of non-consecutive repetitions
22+ exprt sequence_count_condition (
23+ const sva_sequence_repetition_exprt &expr,
24+ const exprt &counter)
25+ {
26+ if (expr.is_range ())
27+ {
28+ // number of repetitions inside a range
29+ auto from = numeric_cast_v<mp_integer>(expr.from ());
30+
31+ if (expr.is_unbounded ())
32+ {
33+ return binary_relation_exprt{
34+ counter, ID_ge, from_integer (from, counter.type ())};
35+ }
36+ else
37+ {
38+ auto to = numeric_cast_v<mp_integer>(expr.to ());
39+
40+ return and_exprt{
41+ binary_relation_exprt{
42+ counter, ID_ge, from_integer (from, counter.type ())},
43+ binary_relation_exprt{
44+ counter, ID_le, from_integer (to, counter.type ())}};
45+ }
46+ }
47+ else
48+ {
49+ // fixed number of repetitions
50+ auto repetitions = numeric_cast_v<mp_integer>(expr.repetitions ());
51+ return equal_exprt{counter, from_integer (repetitions, counter.type ())};
52+ }
53+ }
54+
55+ // / determine type for the repetition counter
56+ typet sequence_count_type (
57+ const sva_sequence_repetition_exprt &expr,
58+ const mp_integer &no_timeframes)
59+ {
60+ mp_integer max;
61+
62+ if (expr.is_range ())
63+ {
64+ if (expr.is_unbounded ())
65+ max = numeric_cast_v<mp_integer>(expr.from ());
66+ else
67+ max = numeric_cast_v<mp_integer>(expr.to ());
68+ }
69+ else
70+ max = numeric_cast_v<mp_integer>(expr.repetitions ());
71+
72+ max = std::max (no_timeframes, max);
73+
74+ auto bits = address_bits (max + 1 );
75+ return unsignedbv_typet{bits};
76+ }
77+
2178sequence_matchest instantiate_sequence (
2279 exprt expr,
2380 sva_sequence_semanticst semantics,
@@ -307,7 +364,7 @@ sequence_matchest instantiate_sequence(
307364
308365 return result;
309366 }
310- else if (expr.id () == ID_sva_sequence_consecutive_repetition)
367+ else if (expr.id () == ID_sva_sequence_consecutive_repetition) // [*...]
311368 {
312369 // x[*n] is syntactic sugar for x ##1 ... ##1 x, with n repetitions
313370 auto &repetition = to_sva_sequence_consecutive_repetition_expr (expr);
@@ -344,69 +401,59 @@ sequence_matchest instantiate_sequence(
344401
345402 return result;
346403 }
347- else if (expr.id () == ID_sva_sequence_goto_repetition)
404+ else if (expr.id () == ID_sva_sequence_goto_repetition) // [->...]
348405 {
349- // The 'op' is a Boolean condition, not a sequence.
350- auto &op = to_sva_sequence_goto_repetition_expr (expr).op ();
351- auto repetitions_int = numeric_cast_v<mp_integer>(
352- to_sva_sequence_goto_repetition_expr (expr).repetitions ());
353- PRECONDITION (repetitions_int >= 1 );
406+ auto &repetition = to_sva_sequence_goto_repetition_expr (expr);
407+ auto &condition = repetition.op ();
354408
355409 sequence_matchest result;
356410
357411 // We add up the number of matches of 'op' starting from
358412 // timeframe u, until the end of our unwinding.
359- const auto bits = address_bits (no_timeframes);
360- const auto zero = from_integer (0 , unsignedbv_typet{bits});
361- const auto one = from_integer (1 , unsignedbv_typet{bits});
362- const auto repetitions = from_integer (repetitions_int, zero.type ());
413+ const auto type = sequence_count_type (repetition, no_timeframes);
414+ const auto zero = from_integer (0 , type);
415+ const auto one = from_integer (1 , type);
363416 exprt matches = zero;
364417
365418 for (mp_integer u = t; u < no_timeframes; ++u)
366419 {
367420 // match of op in timeframe u?
368- auto rec_op = instantiate (op , u, no_timeframes);
421+ auto rec_op = instantiate (condition , u, no_timeframes);
369422
370423 // add up
371424 matches = plus_exprt{matches, if_exprt{rec_op, one, zero}};
372425
373426 // We have a match for op[->n] if there is a match in timeframe
374427 // u and matches is n.
375- result.emplace_back (
376- u, and_exprt{rec_op, equal_exprt{matches, repetitions}});
428+ result.emplace_back (u, sequence_count_condition (repetition, matches));
377429 }
378430
379431 return result;
380432 }
381- else if (expr.id () == ID_sva_sequence_non_consecutive_repetition)
433+ else if (expr.id () == ID_sva_sequence_non_consecutive_repetition) // [=...]
382434 {
383- // The 'op' is a Boolean condition, not a sequence.
384- auto &op = to_sva_sequence_non_consecutive_repetition_expr (expr).op ();
385- auto repetitions_int = numeric_cast_v<mp_integer>(
386- to_sva_sequence_non_consecutive_repetition_expr (expr).repetitions ());
387- PRECONDITION (repetitions_int >= 1 );
435+ auto &repetition = to_sva_sequence_non_consecutive_repetition_expr (expr);
436+ auto &condition = repetition.op ();
388437
389438 sequence_matchest result;
390439
391440 // We add up the number of matches of 'op' starting from
392441 // timeframe u, until the end of our unwinding.
393- const auto bits =
394- address_bits (std::max (no_timeframes, repetitions_int + 1 ));
395- const auto zero = from_integer (0 , unsignedbv_typet{bits});
396- const auto one = from_integer (1 , zero.type ());
397- const auto repetitions = from_integer (repetitions_int, zero.type ());
442+ const auto type = sequence_count_type (repetition, no_timeframes);
443+ const auto zero = from_integer (0 , type);
444+ const auto one = from_integer (1 , type);
398445 exprt matches = zero;
399446
400447 for (mp_integer u = t; u < no_timeframes; ++u)
401448 {
402449 // match of op in timeframe u?
403- auto rec_op = instantiate (op , u, no_timeframes);
450+ auto rec_op = instantiate (condition , u, no_timeframes);
404451
405452 // add up
406453 matches = plus_exprt{matches, if_exprt{rec_op, one, zero}};
407454
408455 // We have a match for op[=n] if matches is n.
409- result.emplace_back (u, equal_exprt{matches, repetitions} );
456+ result.emplace_back (u, sequence_count_condition (repetition, matches) );
410457 }
411458
412459 return result;
0 commit comments