@@ -863,6 +863,42 @@ exprt string_refinementt::substitute_array_with_expr(
863
863
}
864
864
}
865
865
866
+ // / Fill an array represented by a list of with_expr by propagating values to
867
+ // / the left. For instance `ARRAY_OF(12) WITH[2:=24] WITH[4:=42]` will give
868
+ // / `{ 24, 24, 24, 42, 42 }`
869
+ // / \param expr: an array expression in the form
870
+ // / `ARRAY_OF(x) WITH [i0:=v0] ... WITH [iN:=vN]`
871
+ // / \param string_max_length: bound on the length of strings
872
+ // / \return an array expression with filled in values, or expr if it is simply
873
+ // / an `ARRAY_OF(x)` expression
874
+ exprt fill_in_array_with_expr (const exprt &expr, std::size_t string_max_length)
875
+ {
876
+ PRECONDITION (expr.type ().id ()==ID_array);
877
+ PRECONDITION (expr.id ()==ID_with || expr.id ()==ID_array_of);
878
+
879
+ // Nothing to do for empty array
880
+ if (expr.id ()==ID_array_of)
881
+ return expr;
882
+
883
+ // Map of the parts of the array that are initialized
884
+ std::map<std::size_t , exprt> initial_map;
885
+
886
+ for (exprt it=expr; it.id ()==ID_with; it=to_with_expr (it).old ())
887
+ {
888
+ // Add to `initial_map` all the pairs (index,value) contained in `WITH`
889
+ // statements
890
+ const with_exprt with_expr=to_with_expr (it);
891
+ const exprt &then_expr=with_expr.new_value ();
892
+ const auto index =expr_cast<std::size_t >(with_expr.where ());
893
+ if (index <string_max_length)
894
+ initial_map.emplace (index , then_expr);
895
+ }
896
+
897
+ array_exprt result (to_array_type (expr.type ()));
898
+ result.operands ()=fill_in_map_as_vector (initial_map);
899
+ return result;
900
+ }
901
+
866
902
// / create an equivalent expression where array accesses and 'with' expressions
867
903
// / are replaced by 'if' expressions, in particular:
868
904
// / * for an array access `arr[x]`, where:
0 commit comments