|
18 | 18 | #include "obligations.h"
|
19 | 19 | #include "property.h"
|
20 | 20 |
|
| 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 | + |
21 | 78 | sequence_matchest instantiate_sequence(
|
22 | 79 | exprt expr,
|
23 | 80 | sva_sequence_semanticst semantics,
|
@@ -307,7 +364,7 @@ sequence_matchest instantiate_sequence(
|
307 | 364 |
|
308 | 365 | return result;
|
309 | 366 | }
|
310 |
| - else if(expr.id() == ID_sva_sequence_consecutive_repetition) |
| 367 | + else if(expr.id() == ID_sva_sequence_consecutive_repetition) // [*...] |
311 | 368 | {
|
312 | 369 | // x[*n] is syntactic sugar for x ##1 ... ##1 x, with n repetitions
|
313 | 370 | auto &repetition = to_sva_sequence_consecutive_repetition_expr(expr);
|
@@ -344,69 +401,59 @@ sequence_matchest instantiate_sequence(
|
344 | 401 |
|
345 | 402 | return result;
|
346 | 403 | }
|
347 |
| - else if(expr.id() == ID_sva_sequence_goto_repetition) |
| 404 | + else if(expr.id() == ID_sva_sequence_goto_repetition) // [->...] |
348 | 405 | {
|
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(); |
354 | 408 |
|
355 | 409 | sequence_matchest result;
|
356 | 410 |
|
357 | 411 | // We add up the number of matches of 'op' starting from
|
358 | 412 | // 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); |
363 | 416 | exprt matches = zero;
|
364 | 417 |
|
365 | 418 | for(mp_integer u = t; u < no_timeframes; ++u)
|
366 | 419 | {
|
367 | 420 | // match of op in timeframe u?
|
368 |
| - auto rec_op = instantiate(op, u, no_timeframes); |
| 421 | + auto rec_op = instantiate(condition, u, no_timeframes); |
369 | 422 |
|
370 | 423 | // add up
|
371 | 424 | matches = plus_exprt{matches, if_exprt{rec_op, one, zero}};
|
372 | 425 |
|
373 | 426 | // We have a match for op[->n] if there is a match in timeframe
|
374 | 427 | // 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)); |
377 | 429 | }
|
378 | 430 |
|
379 | 431 | return result;
|
380 | 432 | }
|
381 |
| - else if(expr.id() == ID_sva_sequence_non_consecutive_repetition) |
| 433 | + else if(expr.id() == ID_sva_sequence_non_consecutive_repetition) // [=...] |
382 | 434 | {
|
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(); |
388 | 437 |
|
389 | 438 | sequence_matchest result;
|
390 | 439 |
|
391 | 440 | // We add up the number of matches of 'op' starting from
|
392 | 441 | // 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); |
398 | 445 | exprt matches = zero;
|
399 | 446 |
|
400 | 447 | for(mp_integer u = t; u < no_timeframes; ++u)
|
401 | 448 | {
|
402 | 449 | // match of op in timeframe u?
|
403 |
| - auto rec_op = instantiate(op, u, no_timeframes); |
| 450 | + auto rec_op = instantiate(condition, u, no_timeframes); |
404 | 451 |
|
405 | 452 | // add up
|
406 | 453 | matches = plus_exprt{matches, if_exprt{rec_op, one, zero}};
|
407 | 454 |
|
408 | 455 | // 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)); |
410 | 457 | }
|
411 | 458 |
|
412 | 459 | return result;
|
|
0 commit comments