21
21
#include < iostream>
22
22
#endif
23
23
24
+ #include < unordered_set>
25
+
24
26
arrayst::arrayst (const namespacet &_ns, propt &_prop)
25
27
: equalityt(_prop), ns(_ns)
26
28
{
@@ -504,22 +506,18 @@ void arrayst::add_array_constraints(
504
506
void arrayst::add_array_constraints_with (
505
507
const index_sett &index_set,
506
508
const with_exprt &expr)
507
- {
508
- const exprt::operandst &operands = expr.operands ();
509
- for (std::size_t i = 1 ; i + 1 < operands.size (); i += 2 )
510
- add_array_constraints_with (index_set, expr, operands[i], operands[i + 1 ]);
511
- }
512
-
513
- void arrayst::add_array_constraints_with (
514
- const index_sett &index_set,
515
- const with_exprt &expr,
516
- const exprt &index,
517
- const exprt &value)
518
509
{
519
510
// we got x=(y with [i:=v])
520
511
// add constraint x[i]=v
521
512
513
+ std::unordered_set<exprt, irep_hash> updated_indices;
514
+
515
+ const exprt::operandst &operands = expr.operands ();
516
+ for (std::size_t i = 1 ; i + 1 < operands.size (); i += 2 )
522
517
{
518
+ const exprt &index = operands[i];
519
+ const exprt &value = operands[i + 1 ];
520
+
523
521
index_exprt index_expr (expr, index , expr.type ().subtype ());
524
522
525
523
if (index_expr.type ()!=value.type ())
@@ -531,22 +529,29 @@ void arrayst::add_array_constraints_with(
531
529
}
532
530
533
531
lazy_constraintt lazy (
534
- lazy_typet::ARRAY_WITH, equal_exprt (index_expr, value));
535
- add_array_constraint (lazy, false ); // added immediately
532
+ lazy_typet::ARRAY_WITH, equal_exprt (index_expr, value));
533
+ add_array_constraint (lazy, false ); // added immediately
534
+
535
+ updated_indices.insert (index );
536
536
}
537
537
538
538
// use other array index applications for "else" case
539
539
// add constraint x[I]=y[I] for I!=i
540
540
541
541
for (auto other_index : index_set)
542
542
{
543
- if (other_index!= index )
543
+ if (updated_indices. find ( other_index) == updated_indices. end () )
544
544
{
545
545
// we first build the guard
546
+ exprt::operandst disjuncts;
547
+ disjuncts.reserve (updated_indices.size ());
548
+ for (const auto &index : updated_indices)
549
+ {
550
+ disjuncts.push_back (equal_exprt{
551
+ index , typecast_exprt::conditional_cast (other_index, index .type ())});
552
+ }
546
553
547
- other_index = typecast_exprt::conditional_cast (other_index, index .type ());
548
-
549
- literalt guard_lit=convert (equal_exprt (index , other_index));
554
+ literalt guard_lit = convert (disjunction (disjuncts));
550
555
551
556
if (guard_lit!=const_literal (true ))
552
557
{
0 commit comments