Skip to content

Commit a6c4010

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 6d87233 commit a6c4010

File tree

2 files changed

+2
-125
lines changed

2 files changed

+2
-125
lines changed

src/solvers/refinement/string_refinement.cpp

+2-121
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;
@@ -1080,81 +1080,6 @@ static exprt substitute_array_access(
10801080
: sparse_arrayt(expr).to_if_expression(index);
10811081
}
10821082

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

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

22622143
if(generator.get_created_strings().count(arr))
22632144
{

src/solvers/refinement/string_refinement.h

-4
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)