@@ -270,12 +270,15 @@ static void make_char_array_pointer_associations(
270
270
}
271
271
}
272
272
273
- void replace_symbols_in_equations (
274
- const union_find_replacet &symbol_resolve,
275
- std::vector<equal_exprt> &equations)
273
+ // / Substitute sub-expressions in equation by representative elements of
274
+ // / `symbol_resolve` whenever possible.
275
+ // / Similar to `symbol_resolve.replace_expr` but doesn't mutate the expression
276
+ // / and returns the transformed expression instead.
277
+ static exprt
278
+ replace_expr_copy (const union_find_replacet &symbol_resolve, exprt expr)
276
279
{
277
- for (equal_exprt &eq : equations)
278
- symbol_resolve. replace_expr (eq) ;
280
+ symbol_resolve. replace_expr (expr);
281
+ return expr ;
279
282
}
280
283
281
284
// / Record the constraints to ensure that the expression is true when
@@ -301,20 +304,22 @@ void string_refinementt::set_to(const exprt &expr, bool value)
301
304
}
302
305
303
306
// / Add association for each char pointer in the equation
307
+ // / \param symbol_solver: a union_find_replacet object to keep track of
308
+ // / char pointer equations
304
309
// / \param equations: vector of equations
305
310
// / \param ns: namespace
306
311
// / \param stream: output stream
307
312
// / \return union_find_replacet where char pointer that have been set equal
308
313
// / by an equation are associated to the same element
309
- static union_find_replacet generate_symbol_resolution_from_equations (
314
+ static void add_equations_for_symbol_resolution (
315
+ union_find_replacet &symbol_solver,
310
316
const std::vector<equal_exprt> &equations,
311
317
const namespacet &ns,
312
318
messaget::mstreamt &stream)
313
319
{
314
320
const auto eom = messaget::eom;
315
321
const std::string log_message =
316
322
" WARNING string_refinement.cpp generate_symbol_resolution_from_equations:" ;
317
- union_find_replacet solver;
318
323
for (const equal_exprt &eq : equations)
319
324
{
320
325
const exprt &lhs = eq.lhs ();
@@ -335,7 +340,7 @@ static union_find_replacet generate_symbol_resolution_from_equations(
335
340
336
341
if (is_char_pointer_type (rhs.type ()))
337
342
{
338
- solver .make_union (lhs, rhs);
343
+ symbol_solver .make_union (lhs, rhs);
339
344
}
340
345
else if (rhs.id () == ID_function_application)
341
346
{
@@ -355,7 +360,7 @@ static union_find_replacet generate_symbol_resolution_from_equations(
355
360
const member_exprt lhs_data (lhs, comp.get_name (), comp.type ());
356
361
const exprt rhs_data = simplify_expr (
357
362
member_exprt (rhs, comp.get_name (), comp.type ()), ns);
358
- solver .make_union (lhs_data, rhs_data);
363
+ symbol_solver .make_union (lhs_data, rhs_data);
359
364
}
360
365
}
361
366
}
@@ -366,7 +371,6 @@ static union_find_replacet generate_symbol_resolution_from_equations(
366
371
}
367
372
}
368
373
}
369
- return solver;
370
374
}
371
375
372
376
// / This is meant to be used on the lhs of an equation with string subtype.
@@ -613,9 +617,9 @@ decision_proceduret::resultt string_refinementt::dec_solve()
613
617
#endif
614
618
615
619
debug () << " dec_solve: Build symbol solver from equations" << eom;
616
- // This is used by get, that's why we use a class member here
617
- symbol_resolve =
618
- generate_symbol_resolution_from_equations ( equations, ns, debug ());
620
+ // symbol_resolve is used by get and is kept between calls to dec_solve,
621
+ // that's why we use a class member here
622
+ add_equations_for_symbol_resolution (symbol_resolve, equations, ns, debug ());
619
623
#ifdef DEBUG
620
624
debug () << " symbol resolve:" << eom;
621
625
for (const auto &pair : symbol_resolve.to_vector ())
@@ -632,9 +636,6 @@ decision_proceduret::resultt string_refinementt::dec_solve()
632
636
}
633
637
#endif
634
638
635
- debug () << " dec_solve: Replacing char pointer symbols" << eom;
636
- replace_symbols_in_equations (symbol_resolve, equations);
637
-
638
639
debug () << " dec_solve: Replacing string ids in function applications" << eom;
639
640
for (equal_exprt &eq : equations)
640
641
{
@@ -653,10 +654,18 @@ decision_proceduret::resultt string_refinementt::dec_solve()
653
654
654
655
debug () << " dec_solve: compute dependency graph and remove function "
655
656
<< " applications captured by the dependencies:" << eom;
656
- std::vector<exprt > local_equations;
657
+ std::vector<equal_exprt > local_equations;
657
658
for (const equal_exprt &eq : equations)
658
659
{
659
- if (!add_node (dependencies, eq, generator.array_pool ))
660
+ // Ensures that arrays that are equal, are associated to the same nodes
661
+ // in the graph.
662
+ const equal_exprt eq_with_char_array_replaced_with_representative_elements =
663
+ to_equal_expr (replace_expr_copy (symbol_resolve, eq));
664
+ const bool node_added = add_node (
665
+ dependencies,
666
+ eq_with_char_array_replaced_with_representative_elements,
667
+ generator.array_pool );
668
+ if (!node_added)
660
669
local_equations.push_back (eq);
661
670
}
662
671
equations.clear ();
0 commit comments