@@ -289,6 +289,22 @@ bool string_refinementt::add_axioms_for_string_assigns(
289289 return true ;
290290}
291291
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+
292308// / If the expression is of type string, then adds constants to the index set to
293309// / force the solver to pick concrete values for each character, and fill the
294310// / maps `found_length` and `found_content`.
@@ -304,70 +320,44 @@ void string_refinementt::concretize_string(const exprt &expr)
304320{
305321 if (refined_string_typet::is_refined_string_type (expr.type ()))
306322 {
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 ());
309325 exprt content=str.content ();
310326 replace_expr (symbol_resolve, content);
311327 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 ;
332335
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);
337339
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;
340341
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
342346 {
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;
361356 }
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);
367357
368358 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 () )
371361 << " = " << from_expr (ns, " " , arr) << eom;
372362 found_content[content]=arr;
373363 }
0 commit comments