@@ -456,17 +456,27 @@ bool string_refinementt::add_axioms_for_string_assigns(
456
456
// / same value as the next index that is present in the index set.
457
457
// / We do so by traversing the array backward, remembering the
458
458
// / last value that has been initialized.
459
- void string_refinementt::concretize_string (const exprt &expr)
459
+ static void concretize_string (
460
+ std::function<exprt(const exprt&)> get,
461
+ std::map<exprt, exprt> &found_length,
462
+ std::map<exprt, array_exprt> &found_content,
463
+ const replace_mapt &symbol_resolve,
464
+ std::map<exprt, std::set<exprt>> &index_set,
465
+ std::size_t max_string_length,
466
+ messaget::mstreamt &stream,
467
+ const namespacet &ns,
468
+ const exprt &expr)
460
469
{
461
470
if (const auto str=expr_cast<string_exprt>(expr))
462
471
{
472
+ const auto & eom=messaget::eom;
463
473
const exprt length=get (str->length ());
464
474
exprt content=str->content ();
465
475
replace_expr (symbol_resolve, content);
466
476
found_length[content]=length;
467
477
const auto string_length=expr_cast_v<std::size_t >(length);
468
478
INVARIANT (
469
- string_length<=generator. max_string_length ,
479
+ string_length<=max_string_length,
470
480
string_refinement_invariantt (" string length must be less than the max "
471
481
" length" ));
472
482
if (index_set[str->content ()].empty ())
@@ -485,31 +495,59 @@ void string_refinementt::concretize_string(const exprt &expr)
485
495
}
486
496
else
487
497
{
488
- debug () << " concretize_string: ignoring out of bound index: "
489
- << from_expr (ns, " " , simple_i) << eom;
498
+ stream << " concretize_string: ignoring out of bound index: "
499
+ << from_expr (ns, " " , simple_i) << eom;
490
500
}
491
501
}
492
502
array_exprt arr (to_array_type (content.type ()));
493
503
arr.operands ()=fill_in_map_as_vector (map);
494
- debug () << " Concretized " << from_expr (ns, " " , str->content ())
495
- << " = " << from_expr (ns, " " , arr) << eom;
504
+ stream << " Concretized " << from_expr (ns, " " , str->content ())
505
+ << " = " << from_expr (ns, " " , arr) << eom;
496
506
found_content[content]=arr;
497
507
}
498
508
}
499
509
500
510
// / For each string whose length has been solved, add constants to the index set
501
511
// / to force the solver to pick concrete values for each character, and fill the
502
512
// / map `found_length`
503
- void string_refinementt::concretize_results ()
513
+ std::vector<exprt> concretize_results (
514
+ std::function<exprt(const exprt&)> get,
515
+ std::map<exprt, exprt> &found_length,
516
+ std::map<exprt, array_exprt> &found_content,
517
+ const replace_mapt &symbol_resolve,
518
+ std::map<exprt, std::set<exprt>> &index_set,
519
+ std::size_t max_string_length,
520
+ messaget::mstreamt &stream,
521
+ const namespacet &ns,
522
+ const std::set<string_exprt> &created_strings,
523
+ const std::map<exprt, std::set<exprt>>& current_index_set,
524
+ const std::vector<string_constraintt> &universal_axioms)
504
525
{
505
- for (const auto &it : symbol_resolve)
506
- concretize_string (it.second );
507
- for (const auto &it : generator.get_created_strings ())
508
- concretize_string (it);
509
- for (const auto & lemma :
510
- generate_instantiations (current_index_set, universal_axioms))
511
- add_lemma (lemma);
512
- display_current_index_set (debug (), ns, current_index_set);
526
+ for (const auto &it : symbol_resolve) {
527
+ concretize_string (
528
+ get,
529
+ found_length,
530
+ found_content,
531
+ symbol_resolve,
532
+ index_set,
533
+ max_string_length,
534
+ stream,
535
+ ns,
536
+ it.second );
537
+ }
538
+ for (const auto &expr : created_strings) {
539
+ concretize_string (
540
+ get,
541
+ found_length,
542
+ found_content,
543
+ symbol_resolve,
544
+ index_set,
545
+ max_string_length,
546
+ stream,
547
+ ns,
548
+ expr);
549
+ }
550
+ return generate_instantiations (current_index_set, universal_axioms);
513
551
}
514
552
515
553
// / For each string whose length has been solved, add constants to the map
@@ -763,7 +801,21 @@ decision_proceduret::resultt string_refinementt::dec_solve()
763
801
debug () << " current index set is empty" << eom;
764
802
if (config_.trace )
765
803
{
766
- concretize_results ();
804
+ const auto lemmas = concretize_results (
805
+ [this ](const exprt& expr){ return this ->get (expr); },
806
+ found_length,
807
+ found_content,
808
+ symbol_resolve,
809
+ index_set,
810
+ generator.max_string_length ,
811
+ debug (),
812
+ ns,
813
+ generator.get_created_strings (),
814
+ current_index_set,
815
+ universal_axioms);
816
+ for (const auto & lemma : lemmas)
817
+ add_lemma (lemma);
818
+ display_current_index_set (debug (), ns, current_index_set);
767
819
return resultt::D_SATISFIABLE;
768
820
}
769
821
else
0 commit comments