@@ -201,8 +201,9 @@ static std::vector<exprt> generate_instantiations(
201
201
return lemmas;
202
202
}
203
203
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
206
207
// / \return an expression containing no function application
207
208
static exprt substitute_function_applications (
208
209
exprt expr,
@@ -218,6 +219,10 @@ static exprt substitute_function_applications(
218
219
return expr;
219
220
}
220
221
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
221
226
static void substitute_function_applications_in_equations (
222
227
std::vector<equal_exprt> &equations,
223
228
string_constraint_generatort &generator)
@@ -228,6 +233,9 @@ static void substitute_function_applications_in_equations(
228
233
229
234
// / For now, any unsigned bitvector type of width smaller or equal to 16 is
230
235
// / 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.
231
239
// / \param type: a type
232
240
// / \return true if the given type represents characters
233
241
bool is_char_type (const typet &type)
@@ -293,49 +301,12 @@ static bool has_char_array_subexpr(const exprt &expr, const namespacet &ns)
293
301
return false ;
294
302
}
295
303
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
-
333
304
void replace_symbols_in_equations (
334
- const union_find_replacet &solver ,
305
+ const union_find_replacet &symbol_resolve ,
335
306
std::vector<equal_exprt> &equations)
336
307
{
337
308
for (equal_exprt &eq : equations)
338
- solver .replace_expr (eq);
309
+ symbol_resolve .replace_expr (eq);
339
310
}
340
311
341
312
// / 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)
361
332
}
362
333
363
334
// / 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 (
365
341
const std::vector<equal_exprt> &equations,
366
342
const namespacet &ns,
367
343
messaget::mstreamt &stream)
368
344
{
369
345
const auto eom = messaget::eom;
370
346
const std::string log_message =
371
- " WARNING string_refinement.cpp symbol_solver_from_equations :" ;
347
+ " WARNING string_refinement.cpp generate_symbol_resolution_from_equations :" ;
372
348
union_find_replacet solver;
373
349
for (const equal_exprt &eq : equations)
374
350
{
@@ -395,7 +371,8 @@ static union_find_replacet symbol_solver_from_equations(
395
371
}
396
372
else if (rhs.id () == ID_function_application)
397
373
{
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
399
376
}
400
377
else if (has_char_pointer_subtype (lhs.type (), ns))
401
378
{
@@ -415,12 +392,9 @@ static union_find_replacet symbol_solver_from_equations(
415
392
}
416
393
else
417
394
{
418
- // #ifdef DEBUG
419
395
stream << log_message << " non struct with char pointer subexpr "
420
396
<< from_expr (ns, " " , rhs) << " \n * of type "
421
397
<< from_type (ns, " " , rhs.type ()) << eom;
422
- // #endif
423
- // UNREACHABLE;
424
398
}
425
399
}
426
400
}
@@ -449,7 +423,8 @@ decision_proceduret::resultt string_refinementt::dec_solve()
449
423
450
424
debug () << " dec_solve: Build symbol solver from equations" << eom;
451
425
// 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 ());
453
428
#ifdef DEBUG
454
429
debug () << " symbol resolve:" << eom;
455
430
for (const auto &pair : symbol_resolve.to_vector ())
@@ -630,9 +605,10 @@ decision_proceduret::resultt string_refinementt::dec_solve()
630
605
return resultt::D_ERROR;
631
606
}
632
607
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.
636
612
void string_refinementt::add_lemma (
637
613
const exprt &lemma,
638
614
const bool simplify_lemma)
@@ -656,7 +632,8 @@ void string_refinementt::add_lemma(
656
632
657
633
symbol_resolve.replace_expr (simple_lemma);
658
634
659
- // Should be careful for empty arrays
635
+ // Replace empty arrays with array_of expression because the solver cannot
636
+ // handle empty arrays.
660
637
for (auto it = simple_lemma.depth_begin (); it != simple_lemma.depth_end ();)
661
638
{
662
639
if (it->id () == ID_array && it->operands ().empty ())
@@ -771,7 +748,15 @@ static std::string string_of_array(const array_exprt &arr)
771
748
return utf16_constant_array_to_java (arr, n);
772
749
}
773
750
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 (
775
760
const std::function<exprt(const exprt &)> &super_get,
776
761
const namespacet &ns,
777
762
const std::size_t max_string_length,
@@ -835,8 +820,8 @@ void debug_model(
835
820
for (const auto &pointer_array : generator.get_arrays_of_pointers ())
836
821
{
837
822
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);
840
825
841
826
stream << " - " << from_expr (ns, " " , arr) << " :\n "
842
827
<< indent << " - pointer: " << from_expr (ns, " " , pointer_array.first )
@@ -906,11 +891,6 @@ exprt fill_in_array_with_expr(
906
891
PRECONDITION (expr.type ().id ()==ID_array);
907
892
PRECONDITION (expr.id ()==ID_with || expr.id ()==ID_array_of);
908
893
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
914
894
915
895
// Map of the parts of the array that are initialized
916
896
std::map<std::size_t , exprt> initial_map;
@@ -1930,7 +1910,7 @@ exprt string_refinementt::get(const exprt &expr) const
1930
1910
arr.length () = generator.get_length_of_string_array (arr);
1931
1911
const auto arr_model_opt =
1932
1912
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
1934
1914
if (arr_model_opt)
1935
1915
{
1936
1916
const exprt arr_model = simplify_expr (*arr_model_opt, ns);
0 commit comments