@@ -1924,9 +1924,13 @@ exprt substitute_array_lists(exprt expr, size_t string_max_length)
19241924// / \return an expression
19251925exprt string_refinementt::get (const exprt &expr) const
19261926{
1927- const auto super_get = [this ](const exprt &expr) { // NOLINT
1927+ // clang-format off
1928+ const auto super_get = [this ](const exprt &expr)
1929+ {
19281930 return supert::get (expr);
19291931 };
1932+ // clang-format on
1933+
19301934 exprt ecopy (expr);
19311935 (void )symbol_resolve.replace_expr (ecopy);
19321936
@@ -2003,31 +2007,21 @@ static optionalt<exprt> find_counter_example(
20032007typedef std::map<exprt, std::vector<exprt>> array_index_mapt;
20042008
20052009// / \related string_constraintt
2006- class gather_indices_visitort : public const_expr_visitort
2010+ static array_index_mapt gather_indices ( const exprt &expr)
20072011{
2008- public:
20092012 array_index_mapt indices;
2010-
2011- gather_indices_visitort (): indices() {}
2012-
2013- void operator ()(const exprt &expr) override
2014- {
2015- if (expr.id ()==ID_index)
2013+ // clang-format off
2014+ std::for_each (
2015+ expr.depth_begin (),
2016+ expr.depth_end (),
2017+ [&](const exprt &expr)
20162018 {
2017- const index_exprt &index=to_index_expr (expr);
2018- const exprt &s (index.array ());
2019- const exprt &i (index.index ());
2020- indices[s].push_back (i);
2021- }
2022- }
2023- };
2024-
2025- // / \related string_constraintt
2026- static array_index_mapt gather_indices (const exprt &expr)
2027- {
2028- gather_indices_visitort v;
2029- expr.visit (v);
2030- return v.indices ;
2019+ const auto index_expr = expr_try_dynamic_cast<const index_exprt>(expr);
2020+ if (index_expr)
2021+ indices[index_expr->array ()].push_back (index_expr->index ());
2022+ });
2023+ // clang-format on
2024+ return indices;
20312025}
20322026
20332027// / \param expr: an expression
@@ -2064,33 +2058,14 @@ is_linear_arithmetic_expr(const exprt &expr, const symbol_exprt &var)
20642058// / false otherwise.
20652059static bool universal_only_in_index (const string_constraintt &expr)
20662060{
2067- // For efficiency, we do a depth-first search of the
2068- // body. The exprt visitors do a BFS and hide the stack/queue, so we would
2069- // need to store a map from child to parent.
2070-
2071- // The unsigned int represents index depth we are. For example, if we are
2072- // considering the fragment `a[b[x]]` (not inside an index expression), then
2073- // the stack would look something like `[..., (a, 0), (b, 1), (x, 2)]`.
2074- typedef std::pair<exprt, unsigned > valuet;
2075- std::stack<valuet> stack;
2076- // We start at 0 since expr is not an index expression, so expr.body() is not
2077- // in an index expression.
2078- stack.push (valuet (expr.body (), 0 ));
2079- while (!stack.empty ())
2061+ for (auto it = expr.body ().depth_begin (); it != expr.body ().depth_end ();)
20802062 {
2081- // Inspect current value
2082- const valuet cur=stack.top ();
2083- stack.pop ();
2084- const exprt e=cur.first ;
2085- const unsigned index_depth=cur.second ;
2086- const unsigned child_index_depth=index_depth+(e.id ()==ID_index?0 :1 );
2087-
2088- // If we found the universal variable not in an index_exprt, fail
2089- if (e==expr.univ_var () && index_depth==0 )
2063+ if (*it == expr.univ_var ())
20902064 return false ;
2065+ if (it->id () == ID_index)
2066+ it.next_sibling_or_parent ();
20912067 else
2092- forall_operands (it, e)
2093- stack.push (valuet (*it, child_index_depth));
2068+ ++it;
20942069 }
20952070 return true ;
20962071}
0 commit comments