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
{
@@ -505,21 +507,16 @@ void arrayst::add_array_constraints_with(
505
507
const index_sett &index_set,
506
508
const with_exprt &expr)
507
509
{
510
+ // We got x=(y with [i:=v, j:=w, ...]).
511
+ // First add constraints x[i]=v, x[j]=w, ...
512
+ std::unordered_set<exprt, irep_hash> updated_indices;
513
+
508
514
const exprt::operandst &operands = expr.operands ();
509
515
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
- {
519
- // we got x=(y with [i:=v])
520
- // add constraint x[i]=v
521
-
522
516
{
517
+ const exprt &index = operands[i];
518
+ const exprt &value = operands[i + 1 ];
519
+
523
520
index_exprt index_expr (expr, index , expr.type ().subtype ());
524
521
525
522
if (index_expr.type ()!=value.type ())
@@ -531,22 +528,29 @@ void arrayst::add_array_constraints_with(
531
528
}
532
529
533
530
lazy_constraintt lazy (
534
- lazy_typet::ARRAY_WITH, equal_exprt (index_expr, value));
535
- add_array_constraint (lazy, false ); // added immediately
531
+ lazy_typet::ARRAY_WITH, equal_exprt (index_expr, value));
532
+ add_array_constraint (lazy, false ); // added immediately
533
+
534
+ updated_indices.insert (index );
536
535
}
537
536
538
- // use other array index applications for "else" case
539
- // add constraint x[I]=y[I] for I!=i
537
+ // For all other indices use the existing value, i.e., add constraints
538
+ // x[I]=y[I] for I!=i,j,...
540
539
541
540
for (auto other_index : index_set)
542
541
{
543
- if (other_index!= index )
542
+ if (updated_indices. find ( other_index) == updated_indices. end () )
544
543
{
545
544
// we first build the guard
545
+ exprt::operandst disjuncts;
546
+ disjuncts.reserve (updated_indices.size ());
547
+ for (const auto &index : updated_indices)
548
+ {
549
+ disjuncts.push_back (equal_exprt{
550
+ index , typecast_exprt::conditional_cast (other_index, index .type ())});
551
+ }
546
552
547
- other_index = typecast_exprt::conditional_cast (other_index, index .type ());
548
-
549
- literalt guard_lit=convert (equal_exprt (index , other_index));
553
+ literalt guard_lit = convert (disjunction (disjuncts));
550
554
551
555
if (guard_lit!=const_literal (true ))
552
556
{
0 commit comments