Skip to content

Commit bc21958

Browse files
author
Lukasz A.J. Wrona
committed
Refactor string_refinementt::concretize_string()
1 parent 0161397 commit bc21958

File tree

1 file changed

+44
-54
lines changed

1 file changed

+44
-54
lines changed

src/solvers/refinement/string_refinement.cpp

Lines changed: 44 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)