@@ -2222,8 +2222,8 @@ exprt substitute_array_lists(exprt expr, size_t string_max_length)
2222
2222
// / Evaluates the given expression in the valuation found by
2223
2223
// / string_refinementt::dec_solve.
2224
2224
// /
2225
- // / The difference with supert::get is that arrays of characters need to be
2226
- // / concretized. See concretize_arrays_in_expression for how it is done .
2225
+ // / Arrays of characters are interpreted differently from the result of
2226
+ // / supert::get: values are propagated to the left to fill unknown .
2227
2227
// / \param expr: an expression
2228
2228
// / \return evaluated expression
2229
2229
exprt string_refinementt::get (const exprt &expr) const
@@ -2234,6 +2234,41 @@ exprt string_refinementt::get(const exprt &expr) const
2234
2234
exprt ecopy (expr);
2235
2235
(void )symbol_resolve.replace_expr (ecopy);
2236
2236
2237
+ // Special treatment for index expressions
2238
+ const auto &index_expr = expr_try_dynamic_cast<index_exprt>(ecopy);
2239
+ if (index_expr && is_char_type (index_expr->type ()))
2240
+ {
2241
+ std::reference_wrapper<const exprt> current (index_expr->array ());
2242
+ while (current.get ().id () == ID_if)
2243
+ {
2244
+ const auto &if_expr = expr_dynamic_cast<if_exprt>(current.get ());
2245
+ const exprt cond = get (if_expr.cond ());
2246
+ if (cond.is_true ())
2247
+ current = std::cref (if_expr.true_case ());
2248
+ else if (cond.is_false ())
2249
+ current = std::cref (if_expr.false_case ());
2250
+ else
2251
+ UNREACHABLE;
2252
+ }
2253
+ const auto array = supert::get (current.get ());
2254
+ const auto index = get (index_expr->index ());
2255
+ const exprt unknown =
2256
+ from_integer (CHARACTER_FOR_UNKNOWN, index_expr->type ());
2257
+ if (
2258
+ const auto sparse_array = interval_sparse_arrayt::of_expr (array, unknown))
2259
+ {
2260
+ if (const auto index_value = numeric_cast<std::size_t >(index ))
2261
+ return sparse_array->at (*index_value);
2262
+ return sparse_array->to_if_expression (index );
2263
+ }
2264
+
2265
+ INVARIANT (
2266
+ array.id () == ID_symbol,
2267
+ " apart from symbols, array valuations can be interpreted as sparse "
2268
+ " arrays" );
2269
+ return index_exprt (array, index );
2270
+ }
2271
+
2237
2272
if (is_char_array_type (ecopy.type (), ns))
2238
2273
{
2239
2274
array_string_exprt &arr = to_array_string_expr (ecopy);
0 commit comments