Skip to content

Commit 78303df

Browse files
author
Lukasz A.J. Wrona
committed
Static concretize strings, lengths and results
1 parent 918297c commit 78303df

File tree

2 files changed

+68
-19
lines changed

2 files changed

+68
-19
lines changed

src/solvers/refinement/string_refinement.cpp

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -456,17 +456,27 @@ bool string_refinementt::add_axioms_for_string_assigns(
456456
/// same value as the next index that is present in the index set.
457457
/// We do so by traversing the array backward, remembering the
458458
/// 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)
460469
{
461470
if(const auto str=expr_cast<string_exprt>(expr))
462471
{
472+
const auto& eom=messaget::eom;
463473
const exprt length=get(str->length());
464474
exprt content=str->content();
465475
replace_expr(symbol_resolve, content);
466476
found_length[content]=length;
467477
const auto string_length=expr_cast_v<std::size_t>(length);
468478
INVARIANT(
469-
string_length<=generator.max_string_length,
479+
string_length<=max_string_length,
470480
string_refinement_invariantt("string length must be less than the max "
471481
"length"));
472482
if(index_set[str->content()].empty())
@@ -485,31 +495,59 @@ void string_refinementt::concretize_string(const exprt &expr)
485495
}
486496
else
487497
{
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;
490500
}
491501
}
492502
array_exprt arr(to_array_type(content.type()));
493503
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;
496506
found_content[content]=arr;
497507
}
498508
}
499509

500510
/// For each string whose length has been solved, add constants to the index set
501511
/// to force the solver to pick concrete values for each character, and fill the
502512
/// 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)
504525
{
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);
513551
}
514552

515553
/// For each string whose length has been solved, add constants to the map
@@ -763,7 +801,21 @@ decision_proceduret::resultt string_refinementt::dec_solve()
763801
debug() << "current index set is empty" << eom;
764802
if(config_.trace)
765803
{
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);
767819
return resultt::D_SATISFIABLE;
768820
}
769821
else

src/solvers/refinement/string_refinement.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,6 @@ class string_refinementt final: public bv_refinementt
107107
std::vector<exprt> instantiate_not_contains(
108108
const string_not_contains_constraintt &axiom);
109109

110-
void concretize_string(const exprt &expr);
111-
void concretize_results();
112-
113110
exprt get_array(const exprt &arr, const exprt &size) const;
114111
exprt get_array(const exprt &arr) const;
115112

0 commit comments

Comments
 (0)