|
12 | 12 | #include <util/json.h>
|
13 | 13 | #include <util/message.h>
|
14 | 14 | #include <util/replace_expr.h>
|
| 15 | +#include <util/replace_symbol.h> |
15 | 16 | #include <util/std_expr.h>
|
16 | 17 |
|
17 | 18 | #include <solvers/prop/literal_expr.h>
|
@@ -237,6 +238,11 @@ void arrayst::collect_arrays(const exprt &a)
|
237 | 238 | else if(a.id() == ID_array_comprehension)
|
238 | 239 | {
|
239 | 240 | }
|
| 241 | + else if(auto let_expr = expr_try_dynamic_cast<let_exprt>(a)) |
| 242 | + { |
| 243 | + arrays.make_union(a, let_expr->where()); |
| 244 | + collect_arrays(let_expr->where()); |
| 245 | + } |
240 | 246 | else
|
241 | 247 | {
|
242 | 248 | DATA_INVARIANT(
|
@@ -528,6 +534,33 @@ void arrayst::add_array_constraints(
|
528 | 534 | else if(expr.id()==ID_index)
|
529 | 535 | {
|
530 | 536 | }
|
| 537 | + else if(auto let_expr = expr_try_dynamic_cast<let_exprt>(expr)) |
| 538 | + { |
| 539 | + // we got x=let(a=e, A) |
| 540 | + // add x[i]=A[a/e][i] |
| 541 | + |
| 542 | + exprt where = let_expr->where(); |
| 543 | + replace_symbolt replace_symbol; |
| 544 | + for(const auto &binding : |
| 545 | + make_range(let_expr->variables()).zip(let_expr->values())) |
| 546 | + { |
| 547 | + replace_symbol.insert(binding.first, binding.second); |
| 548 | + } |
| 549 | + replace_symbol(where); |
| 550 | + |
| 551 | + for(const auto &index : index_set) |
| 552 | + { |
| 553 | + index_exprt index_expr{expr, index}; |
| 554 | + index_exprt where_indexed{where, index}; |
| 555 | + |
| 556 | + // add constraint |
| 557 | + lazy_constraintt lazy{ |
| 558 | + lazy_typet::ARRAY_LET, equal_exprt{index_expr, where_indexed}}; |
| 559 | + |
| 560 | + add_array_constraint(lazy, false); // added immediately |
| 561 | + array_constraint_count[constraint_typet::ARRAY_LET]++; |
| 562 | + } |
| 563 | + } |
531 | 564 | else
|
532 | 565 | {
|
533 | 566 | DATA_INVARIANT(
|
@@ -875,6 +908,8 @@ std::string arrayst::enum_to_string(constraint_typet type)
|
875 | 908 | return "arrayComprehension";
|
876 | 909 | case constraint_typet::ARRAY_EQUALITY:
|
877 | 910 | return "arrayEquality";
|
| 911 | + case constraint_typet::ARRAY_LET: |
| 912 | + return "arrayLet"; |
878 | 913 | default:
|
879 | 914 | UNREACHABLE;
|
880 | 915 | }
|
|
0 commit comments