Skip to content

Commit 88c664c

Browse files
Add a function that fill an array represented by a with expression
This interpret the result by propagating values that are set, to the left.
1 parent 1fd5bb2 commit 88c664c

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

src/solvers/refinement/string_refinement.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,42 @@ exprt string_refinementt::substitute_array_with_expr(
863863
}
864864
}
865865

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+
866902
/// create an equivalent expression where array accesses and 'with' expressions
867903
/// are replaced by 'if' expressions, in particular:
868904
/// * for an array access `arr[x]`, where:

0 commit comments

Comments
 (0)