Skip to content

Commit fa2b500

Browse files
Add a cache for eval in string dependences
This improves the performances since the model for one string can depend on the model for two other strings, which model may have already been computed. The cache must be cleared every time the model changes.
1 parent 40f3b05 commit fa2b500

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

src/solvers/refinement/string_refinement.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
757757

758758
// Initial try without index set
759759
const auto get = [this](const exprt &expr) { return this->get(expr); };
760+
dependencies.clean_cache();
760761
const decision_proceduret::resultt res=supert::dec_solve();
761762
if(res==resultt::D_SATISFIABLE)
762763
{
@@ -804,6 +805,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
804805

805806
while((loop_bound_--)>0)
806807
{
808+
dependencies.clean_cache();
807809
const decision_proceduret::resultt res=supert::dec_solve();
808810

809811
if(res==resultt::D_SATISFIABLE)

src/solvers/refinement/string_refinement_util.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ equation_symbol_mappingt::find_equations(const exprt &expr)
172172
return equations_containing[expr];
173173
}
174174

175-
string_transformation_builtin_functiont::string_transformation_builtin_functiont(
175+
string_transformation_builtin_functiont
176+
::string_transformation_builtin_functiont(
176177
const std::vector<exprt> &fun_args,
177178
array_poolt &array_pool)
178179
{
@@ -507,17 +508,36 @@ optionalt<exprt> string_dependenciest::eval(
507508
const array_string_exprt &s,
508509
const std::function<exprt(const exprt &)> &get_value) const
509510
{
510-
const auto node = node_at(s);
511-
if(node && node->dependencies.size() == 1)
511+
const auto &it = node_index_pool.find(s);
512+
if(it == node_index_pool.end())
513+
return {};
514+
515+
if(eval_string_cache[it->second])
516+
return eval_string_cache[it->second];
517+
518+
const auto node = string_nodes[it->second];
519+
520+
if(node.dependencies.size() == 1)
512521
{
513-
const auto &f = get_builtin_function(node->dependencies[0]);
522+
const auto &f = get_builtin_function(node.dependencies[0]);
514523
const auto result = f.string_result();
515524
if(result && *result == s)
516-
return f.eval(get_value);
525+
{
526+
const auto value_opt = f.eval(get_value);
527+
eval_string_cache[it->second] = value_opt;
528+
return value_opt;
529+
}
517530
}
518531
return {};
519532
}
520533

534+
void string_dependenciest::clean_cache()
535+
{
536+
eval_string_cache.resize(string_nodes.size());
537+
for(auto &e : eval_string_cache)
538+
e = {};
539+
}
540+
521541
bool add_node(
522542
string_dependenciest &dependencies,
523543
const equal_exprt &equation,

src/solvers/refinement/string_refinement_util.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,15 @@ class string_dependenciest
332332

333333
/// Attempt to evaluate the given string from the dependencies and valuation
334334
/// of strings on which it depends
335+
/// Warning: eval uses a cache which must be cleaned everytime the valuations
336+
/// given by get_value can change.
335337
optionalt<exprt> eval(
336338
const array_string_exprt &s,
337339
const std::function<exprt(const exprt&)> &get_value) const;
338340

341+
/// Clean the cache used by `eval`
342+
void clean_cache();
343+
339344
void output_dot(std::ostream &stream) const;
340345

341346
private:
@@ -345,6 +350,8 @@ class string_dependenciest
345350
/// Set of nodes representing strings
346351
std::vector<string_nodet> string_nodes;
347352

353+
mutable std::vector<optionalt<exprt>> eval_string_cache;
354+
348355
/// Nodes describing dependencies of a string: values of the map correspond
349356
/// to indexes in the vector `string_nodes`.
350357
std::unordered_map<array_string_exprt, std::size_t, irep_hash>

0 commit comments

Comments
 (0)