@@ -21,6 +21,8 @@ Author: Daniel Kroening, kroening@kroening.com
2121#include < iostream>
2222#endif
2323
24+ #include < unordered_set>
25+
2426arrayst::arrayst (const namespacet &_ns, propt &_prop)
2527 : equalityt(_prop), ns(_ns)
2628{
@@ -504,22 +506,18 @@ void arrayst::add_array_constraints(
504506void arrayst::add_array_constraints_with (
505507 const index_sett &index_set,
506508 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)
518509{
519510 // we got x=(y with [i:=v])
520511 // add constraint x[i]=v
521512
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 )
522517 {
518+ const exprt &index = operands[i];
519+ const exprt &value = operands[i + 1 ];
520+
523521 index_exprt index_expr (expr, index, expr.type ().subtype ());
524522
525523 if (index_expr.type ()!=value.type ())
@@ -531,22 +529,29 @@ void arrayst::add_array_constraints_with(
531529 }
532530
533531 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);
536536 }
537537
538538 // use other array index applications for "else" case
539539 // add constraint x[I]=y[I] for I!=i
540540
541541 for (auto other_index : index_set)
542542 {
543- if (other_index!=index )
543+ if (updated_indices. find ( other_index) == updated_indices. end () )
544544 {
545545 // 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+ }
546553
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));
550555
551556 if (guard_lit!=const_literal (true ))
552557 {
0 commit comments