Skip to content

Commit 3e5b3f1

Browse files
Minor code improvements in string refinement
Remove unused function: associate_char_array_to_char_pointers. Rename solver in symbol_resolve. Rename function in generate_symbol_resolution_from_eq. Rename function get_char_array_and_concretize. Documentation update for generate_symbol_resolution, add_lemma, substitute_function_application, is_char_type. Some documentation and style fixes.
1 parent 3d5465e commit 3e5b3f1

File tree

1 file changed

+41
-61
lines changed

1 file changed

+41
-61
lines changed

src/solvers/refinement/string_refinement.cpp

+41-61
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,9 @@ static std::vector<exprt> generate_instantiations(
201201
return lemmas;
202202
}
203203

204-
/// remove functions applications and create the necessary axioms
205-
/// \par parameters: an expression containing function applications
204+
/// Remove functions applications and create the necessary axioms.
205+
/// \param expr: an expression possibly containing function applications
206+
/// \param generator: generator for the string constraints
206207
/// \return an expression containing no function application
207208
static exprt substitute_function_applications(
208209
exprt expr,
@@ -218,6 +219,10 @@ static exprt substitute_function_applications(
218219
return expr;
219220
}
220221

222+
/// Remove functions applications and create the necessary axioms.
223+
/// \param equations: vector of equations
224+
/// \param generator: generator for the string constraints
225+
/// \return vector of equations where function application have been replaced
221226
static void substitute_function_applications_in_equations(
222227
std::vector<equal_exprt> &equations,
223228
string_constraint_generatort &generator)
@@ -228,6 +233,9 @@ static void substitute_function_applications_in_equations(
228233

229234
/// For now, any unsigned bitvector type of width smaller or equal to 16 is
230235
/// considered a character.
236+
/// \note type that are not characters maybe detected as characters (for
237+
/// instance unsigned char in C), this will make dec_solve do unnecessary
238+
/// steps for these, but should not affect correctness.
231239
/// \param type: a type
232240
/// \return true if the given type represents characters
233241
bool is_char_type(const typet &type)
@@ -293,49 +301,12 @@ static bool has_char_array_subexpr(const exprt &expr, const namespacet &ns)
293301
return false;
294302
}
295303

296-
///
297-
void associate_char_array_to_char_pointers(
298-
exprt &expr,
299-
string_constraint_generatort &generator,
300-
std::map<exprt, exprt> &array_of_pointers)
301-
{
302-
for(auto it = expr.depth_begin(); it != expr.depth_end();)
303-
{
304-
if(it->type().id() == ID_pointer)
305-
{
306-
if(it->id() == ID_array)
307-
++it;
308-
else if(
309-
it->id() == ID_address_of && it->op0().id() == ID_index &&
310-
it->op0().op0().id() == ID_array)
311-
{
312-
// We have to be careful not to replace constants
313-
PRECONDITION(it->op0().op1().is_zero());
314-
// it.mutate()=address_of_exprt(it->op0().op0());
315-
it.next_sibling_or_parent();
316-
}
317-
else
318-
{
319-
symbol_exprt length_sym =
320-
generator.fresh_symbol("data_length", java_int_type());
321-
symbol_exprt array_sym = generator.fresh_symbol(
322-
"data_array", array_typet(java_char_type(), length_sym));
323-
324-
array_of_pointers.insert(std::make_pair(*it, array_sym));
325-
it.next_sibling_or_parent();
326-
}
327-
}
328-
else
329-
++it;
330-
}
331-
}
332-
333304
void replace_symbols_in_equations(
334-
const union_find_replacet &solver,
305+
const union_find_replacet &symbol_resolve,
335306
std::vector<equal_exprt> &equations)
336307
{
337308
for(equal_exprt &eq : equations)
338-
solver.replace_expr(eq);
309+
symbol_resolve.replace_expr(eq);
339310
}
340311

341312
/// Add equation to `m_equation_list` or give them to `supert::set_to`
@@ -361,14 +332,19 @@ void string_refinementt::set_to(const exprt &expr, bool value)
361332
}
362333

363334
/// Add association for each char pointer in the equation
364-
static union_find_replacet symbol_solver_from_equations(
335+
/// \param equations: vector of equations
336+
/// \param ns: namespace
337+
/// \param stream: output stream
338+
/// \return union_find_replacet where char pointer that have been set equal
339+
/// by an equation are associated to the same element
340+
static union_find_replacet generate_symbol_resolution_from_equations(
365341
const std::vector<equal_exprt> &equations,
366342
const namespacet &ns,
367343
messaget::mstreamt &stream)
368344
{
369345
const auto eom = messaget::eom;
370346
const std::string log_message =
371-
"WARNING string_refinement.cpp symbol_solver_from_equations:";
347+
"WARNING string_refinement.cpp generate_symbol_resolution_from_equations:";
372348
union_find_replacet solver;
373349
for(const equal_exprt &eq : equations)
374350
{
@@ -395,7 +371,8 @@ static union_find_replacet symbol_solver_from_equations(
395371
}
396372
else if(rhs.id() == ID_function_application)
397373
{
398-
// ignore function application
374+
// function applications can be ignored because they will be replaced
375+
// in the convert_function_application step of dec_solve
399376
}
400377
else if(has_char_pointer_subtype(lhs.type(), ns))
401378
{
@@ -415,12 +392,9 @@ static union_find_replacet symbol_solver_from_equations(
415392
}
416393
else
417394
{
418-
// #ifdef DEBUG
419395
stream << log_message << "non struct with char pointer subexpr "
420396
<< from_expr(ns, "", rhs) << "\n * of type "
421397
<< from_type(ns, "", rhs.type()) << eom;
422-
// #endif
423-
// UNREACHABLE;
424398
}
425399
}
426400
}
@@ -449,7 +423,8 @@ decision_proceduret::resultt string_refinementt::dec_solve()
449423

450424
debug() << "dec_solve: Build symbol solver from equations" << eom;
451425
// This is used by get, that's why we use a class member here
452-
symbol_resolve = symbol_solver_from_equations(equations, ns, debug());
426+
symbol_resolve =
427+
generate_symbol_resolution_from_equations(equations, ns, debug());
453428
#ifdef DEBUG
454429
debug() << "symbol resolve:" << eom;
455430
for(const auto &pair : symbol_resolve.to_vector())
@@ -630,9 +605,10 @@ decision_proceduret::resultt string_refinementt::dec_solve()
630605
return resultt::D_ERROR;
631606
}
632607

633-
/// add the given lemma to the solver
634-
/// \par parameters: a lemma and Boolean value stating whether the lemma should
635-
/// be added to the index set.
608+
/// Add the given lemma to the solver.
609+
/// \param lemma: a Boolean expression
610+
/// \param simplify_lemma: whether the lemma should be simplified before being
611+
/// given to the underlying solver.
636612
void string_refinementt::add_lemma(
637613
const exprt &lemma,
638614
const bool simplify_lemma)
@@ -656,7 +632,8 @@ void string_refinementt::add_lemma(
656632

657633
symbol_resolve.replace_expr(simple_lemma);
658634

659-
// Should be careful for empty arrays
635+
// Replace empty arrays with array_of expression because the solver cannot
636+
// handle empty arrays.
660637
for(auto it = simple_lemma.depth_begin(); it != simple_lemma.depth_end();)
661638
{
662639
if(it->id() == ID_array && it->operands().empty())
@@ -771,7 +748,15 @@ static std::string string_of_array(const array_exprt &arr)
771748
return utf16_constant_array_to_java(arr, n);
772749
}
773750

774-
static exprt get_char_array_in_model(
751+
/// Debugging function which finds the valuation of the given array in
752+
/// `super_get` and concretize unknown characters.
753+
/// \param super_get: give a valuation to variables
754+
/// \param ns: namespace
755+
/// \param max_string_length: limit up to which we concretize strings
756+
/// \param stream: output stream
757+
/// \param arr: array expression
758+
/// \return expression corresponding to `arr` in the model
759+
static exprt get_char_array_and_concretize(
775760
const std::function<exprt(const exprt &)> &super_get,
776761
const namespacet &ns,
777762
const std::size_t max_string_length,
@@ -835,8 +820,8 @@ void debug_model(
835820
for(const auto &pointer_array : generator.get_arrays_of_pointers())
836821
{
837822
const auto arr = pointer_array.second;
838-
const exprt model =
839-
get_char_array_in_model(super_get, ns, max_string_length, stream, arr);
823+
const exprt model = get_char_array_and_concretize(
824+
super_get, ns, max_string_length, stream, arr);
840825

841826
stream << "- " << from_expr(ns, "", arr) << ":\n"
842827
<< indent << "- pointer: " << from_expr(ns, "", pointer_array.first)
@@ -906,11 +891,6 @@ exprt fill_in_array_with_expr(
906891
PRECONDITION(expr.type().id()==ID_array);
907892
PRECONDITION(expr.id()==ID_with || expr.id()==ID_array_of);
908893
const array_typet &array_type = to_array_type(expr.type());
909-
#if 0
910-
// Nothing to do for empty array
911-
if(expr.id()==ID_array_of)
912-
return expr;
913-
#endif
914894

915895
// Map of the parts of the array that are initialized
916896
std::map<std::size_t, exprt> initial_map;
@@ -1930,7 +1910,7 @@ exprt string_refinementt::get(const exprt &expr) const
19301910
arr.length() = generator.get_length_of_string_array(arr);
19311911
const auto arr_model_opt =
19321912
get_array(super_get, ns, generator.max_string_length, debug(), arr);
1933-
// Should be refactored with get array or get array in model
1913+
// \todo Refactor with get array in model
19341914
if(arr_model_opt)
19351915
{
19361916
const exprt arr_model = simplify_expr(*arr_model_opt, ns);

0 commit comments

Comments
 (0)