Skip to content

Commit 5ecd3ed

Browse files
Stop using concretize_arrays_in_expression
This is now unecessary as get_array takes care of the concretization using sparse arrays. This allows use to delete concretize_arrays_in_expression which is now unused. Equivalent behavior to this function can be obtained using sparse arrays.
1 parent ce83412 commit 5ecd3ed

File tree

2 files changed

+2
-125
lines changed

2 files changed

+2
-125
lines changed

src/solvers/refinement/string_refinement.cpp

Lines changed: 2 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static optionalt<exprt> find_counter_example(
4646
/// * the negation of `a` is an existential formula `b`;
4747
/// * we substituted symbols in `b` by their values found in `get`;
4848
/// * arrays are concretized, meaning we attribute a value for characters that
49-
/// are unknown to get, for details see concretize_arrays_in_expression;
49+
/// are unknown to get, for details see substitute_array_access;
5050
/// * `b` is simplified and array accesses are replaced by expressions
5151
/// without arrays;
5252
/// * we give lemma `b` to a fresh solver;
@@ -1076,81 +1076,6 @@ static exprt substitute_array_access(
10761076
: sparse_arrayt(expr).to_if_expression(index);
10771077
}
10781078

1079-
/// Fill an array represented by a list of with_expr by propagating values to
1080-
/// the left. For instance `ARRAY_OF(12) WITH[2:=24] WITH[4:=42]` will give
1081-
/// `{ 24, 24, 24, 42, 42 }`
1082-
/// \param expr: an array expression in the form
1083-
/// `ARRAY_OF(x) WITH [i0:=v0] ... WITH [iN:=vN]`
1084-
/// \param string_max_length: bound on the length of strings
1085-
/// \return an array expression with filled in values, or expr if it is simply
1086-
/// an `ARRAY_OF(x)` expression
1087-
static array_exprt
1088-
fill_in_array_with_expr(const exprt &expr, const std::size_t string_max_length)
1089-
{
1090-
PRECONDITION(expr.type().id()==ID_array);
1091-
PRECONDITION(expr.id()==ID_with || expr.id()==ID_array_of);
1092-
const array_typet &array_type = to_array_type(expr.type());
1093-
1094-
// Map of the parts of the array that are initialized
1095-
std::map<std::size_t, exprt> initial_map;
1096-
1097-
// Set the last index to be sure the array will have the right length
1098-
const auto &array_size_opt = numeric_cast<std::size_t>(array_type.size());
1099-
if(array_size_opt && *array_size_opt > 0)
1100-
initial_map.emplace(
1101-
*array_size_opt - 1,
1102-
from_integer(CHARACTER_FOR_UNKNOWN, array_type.subtype()));
1103-
1104-
for(exprt it=expr; it.id()==ID_with; it=to_with_expr(it).old())
1105-
{
1106-
// Add to `initial_map` all the pairs (index,value) contained in `WITH`
1107-
// statements
1108-
const with_exprt &with_expr = to_with_expr(it);
1109-
const exprt &then_expr=with_expr.new_value();
1110-
const auto index =
1111-
numeric_cast_v<std::size_t>(to_constant_expr(with_expr.where()));
1112-
if(
1113-
index < string_max_length && (!array_size_opt || index < *array_size_opt))
1114-
initial_map.emplace(index, then_expr);
1115-
}
1116-
1117-
array_exprt result(array_type);
1118-
result.operands() = fill_in_map_as_vector(initial_map);
1119-
return result;
1120-
}
1121-
1122-
/// Fill an array represented by an array_expr by propagating values to
1123-
/// the left for unknown values. For instance `{ 24 , * , * , 42, * }` will give
1124-
/// `{ 24, 42, 42, 42, '?' }`
1125-
/// \param expr: an array expression
1126-
/// \param string_max_length: bound on the length of strings
1127-
/// \return an array expression with filled in values
1128-
exprt fill_in_array_expr(const array_exprt &expr, std::size_t string_max_length)
1129-
{
1130-
PRECONDITION(expr.type().id() == ID_array);
1131-
const array_typet &array_type = to_array_type(expr.type());
1132-
PRECONDITION(array_type.subtype().id() == ID_unsignedbv);
1133-
1134-
// Map of the parts of the array that are initialized
1135-
std::map<std::size_t, exprt> initial_map;
1136-
const auto &array_size_opt = numeric_cast<std::size_t>(array_type.size());
1137-
1138-
if(array_size_opt && *array_size_opt > 0)
1139-
initial_map.emplace(
1140-
*array_size_opt - 1,
1141-
from_integer(CHARACTER_FOR_UNKNOWN, array_type.subtype()));
1142-
1143-
for(std::size_t i = 0; i < expr.operands().size(); ++i)
1144-
{
1145-
if(i < string_max_length && expr.operands()[i].id() != ID_unknown)
1146-
initial_map[i] = expr.operands()[i];
1147-
}
1148-
1149-
array_exprt result(array_type);
1150-
result.operands()=fill_in_map_as_vector(initial_map);
1151-
return result;
1152-
}
1153-
11541079
/// Create an equivalent expression where array accesses are replaced by 'if'
11551080
/// expressions: for instance in array access `arr[index]`, where:
11561081
/// `arr := {12, 24, 48}` the constructed expression will be:
@@ -1344,46 +1269,6 @@ static exprt negation_of_constraint(const string_constraintt &axiom)
13441269
return negaxiom;
13451270
}
13461271

1347-
/// Result of the solver `supert` should not be interpreted literally for char
1348-
/// arrays as not all indices are present in the index set.
1349-
/// In the given expression, we populate arrays at the indices for which the
1350-
/// solver has no constraint by copying values to the left.
1351-
/// For example an expression `ARRAY_OF(0) WITH [1:=2] WITH [4:=3]` would
1352-
/// be interpreted as `{ 2, 2, 3, 3, 3}`.
1353-
/// \param expr: expression to interpret
1354-
/// \param string_max_length: maximum size of arrays to consider
1355-
/// \param ns: namespace, used to determine what is an array of character
1356-
/// \return the interpreted expression
1357-
exprt concretize_arrays_in_expression(
1358-
exprt expr,
1359-
std::size_t string_max_length,
1360-
const namespacet &ns)
1361-
{
1362-
auto it=expr.depth_begin();
1363-
const auto end=expr.depth_end();
1364-
while(it!=end)
1365-
{
1366-
if(is_char_array_type(it->type(), ns))
1367-
{
1368-
if(it->id() == ID_with || it->id() == ID_array_of)
1369-
{
1370-
it.mutate() = fill_in_array_with_expr(*it, string_max_length);
1371-
it.next_sibling_or_parent();
1372-
}
1373-
else if(it->id() == ID_array)
1374-
{
1375-
it.mutate() = fill_in_array_expr(to_array_expr(*it), string_max_length);
1376-
it.next_sibling_or_parent();
1377-
}
1378-
else
1379-
++it; // ignoring other expressions
1380-
}
1381-
else
1382-
++it;
1383-
}
1384-
return expr;
1385-
}
1386-
13871272
/// Debugging function which outputs the different steps an axiom goes through
13881273
/// to be checked in check axioms.
13891274
static void debug_check_axioms_step(
@@ -2249,11 +2134,7 @@ exprt string_refinementt::get(const exprt &expr) const
22492134
if(
22502135
const auto arr_model_opt =
22512136
get_array(super_get, ns, generator.max_string_length, debug(), arr))
2252-
{
2253-
// \todo get_array should take care of the concretization
2254-
return concretize_arrays_in_expression(
2255-
*arr_model_opt, generator.max_string_length, ns);
2256-
}
2137+
return *arr_model_opt;
22572138

22582139
if(generator.get_created_strings().count(arr))
22592140
{

src/solvers/refinement/string_refinement.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,6 @@ class string_refinementt final: public bv_refinementt
9393
};
9494

9595
exprt substitute_array_lists(exprt expr, std::size_t string_max_length);
96-
exprt concretize_arrays_in_expression(
97-
exprt expr,
98-
std::size_t string_max_length,
99-
const namespacet &ns);
10096

10197
// Declaration required for unit-test:
10298
union_find_replacet string_identifiers_resolution_from_equations(

0 commit comments

Comments
 (0)