@@ -289,6 +289,22 @@ bool string_refinementt::add_axioms_for_string_assigns(
289
289
return true ;
290
290
}
291
291
292
+ template <typename T>
293
+ T expr_cast (const exprt&);
294
+
295
+ template <>
296
+ std::size_t expr_cast<std::size_t >(const exprt& val_expr)
297
+ {
298
+ mp_integer val_mb;
299
+ if (!to_integer (val_expr, val_mb))
300
+ throw std::bad_cast ();
301
+ if (!val_mb.is_long ())
302
+ throw std::bad_cast ();
303
+ if (val_mb<0 )
304
+ throw std::bad_cast ();
305
+ return val_mb.to_long ();
306
+ }
307
+
292
308
// / If the expression is of type string, then adds constants to the index set to
293
309
// / force the solver to pick concrete values for each character, and fill the
294
310
// / maps `found_length` and `found_content`.
@@ -304,70 +320,44 @@ void string_refinementt::concretize_string(const exprt &expr)
304
320
{
305
321
if (refined_string_typet::is_refined_string_type (expr.type ()))
306
322
{
307
- string_exprt str=to_string_expr (expr);
308
- exprt length=get (str.length ());
323
+ const string_exprt str=to_string_expr (expr);
324
+ const exprt length=get (str.length ());
309
325
exprt content=str.content ();
310
326
replace_expr (symbol_resolve, content);
311
327
found_length[content]=length;
312
- mp_integer found_length;
313
- if (!to_integer (length, found_length))
314
- {
315
- INVARIANT (
316
- found_length.is_long (),
317
- string_refinement_invariantt (" the length of a string should be a "
318
- " long" ));
319
- INVARIANT (
320
- found_length>=0 ,
321
- string_refinement_invariantt (" the length of a string should be >= 0" ));
322
- size_t concretize_limit=found_length.to_long ();
323
- INVARIANT (
324
- concretize_limit<=generator.max_string_length ,
325
- string_refinement_invariantt (" string length must be less than the max "
326
- " length" ));
327
- exprt content_expr=str.content ();
328
- std::vector<exprt> result;
329
-
330
- if (index_set[str.content ()].empty ())
331
- return ;
328
+ const auto string_length=expr_cast<std::size_t >(length);
329
+ INVARIANT (
330
+ string_length<=generator.max_string_length ,
331
+ string_refinement_invariantt (" string length must be less than the max "
332
+ " length" ));
333
+ if (index_set[str.content ()].empty ())
334
+ return ;
332
335
333
- // Use the last index as the default character value
334
- exprt last_concretized=simplify_expr (
335
- get (str[minus_exprt (length, from_integer (1 , length.type ()))]), ns);
336
- result.resize (concretize_limit, last_concretized);
336
+ // Use the last index as the default character value
337
+ const exprt last_concretized=simplify_expr (
338
+ get (str[minus_exprt (length, from_integer (1 , length.type ()))]), ns);
337
339
338
- // Keep track of the indexes for which we have actual values
339
- std::set<std::size_t > initialized;
340
+ std::map<std::size_t , exprt> map;
340
341
341
- for (const auto &i : index_set[str.content ()])
342
+ for (const auto &i : index_set[str.content ()])
343
+ {
344
+ const exprt simple_i=simplify_expr (get (i), ns);
345
+ try
342
346
{
343
- mp_integer mp_index;
344
- exprt simple_i=simplify_expr (get (i), ns);
345
- if (to_integer (simple_i, mp_index) ||
346
- mp_index<0 ||
347
- mp_index>=concretize_limit)
348
- {
349
- debug () << " concretize_string: ignoring out of bound index: "
350
- << from_expr (ns, " " , simple_i) << eom;
351
- }
352
- else
353
- {
354
- // Add an entry in the result vector
355
- size_t index=mp_index.to_long ();
356
- exprt str_i=simplify_expr (str[simple_i], ns);
357
- exprt value=simplify_expr (get (str_i), ns);
358
- result[index]=value;
359
- initialized.insert (index);
360
- }
347
+ const auto index=expr_cast<std::size_t >(simple_i);
348
+ const exprt str_i=simplify_expr (str[simple_i], ns);
349
+ const exprt value=simplify_expr (get (str_i), ns);
350
+ map.emplace (index, value);
351
+ }
352
+ catch (const std::bad_cast &)
353
+ {
354
+ debug () << " concretize_string: ignoring out of bound index: "
355
+ << from_expr (ns, " " , simple_i) << eom;
361
356
}
362
-
363
- // Pad the concretized values to the left to assign the uninitialized
364
- // values of result. The indices greater than concretize_limit are
365
- // already assigned to last_concretized.
366
- fill_in_vector (result, initialized);
367
357
368
358
array_exprt arr (to_array_type (content.type ()));
369
- arr.operands ()=result ;
370
- debug () << " Concretized " << from_expr (ns, " " , content_expr )
359
+ arr.operands ()=fill_in_map_as_vector (map) ;
360
+ debug () << " Concretized " << from_expr (ns, " " , str. content () )
371
361
<< " = " << from_expr (ns, " " , arr) << eom;
372
362
found_content[content]=arr;
373
363
}
0 commit comments