@@ -1924,9 +1924,13 @@ exprt substitute_array_lists(exprt expr, size_t string_max_length)
1924
1924
// / \return an expression
1925
1925
exprt string_refinementt::get (const exprt &expr) const
1926
1926
{
1927
- const auto super_get = [this ](const exprt &expr) { // NOLINT
1927
+ // clang-format off
1928
+ const auto super_get = [this ](const exprt &expr)
1929
+ {
1928
1930
return supert::get (expr);
1929
1931
};
1932
+ // clang-format on
1933
+
1930
1934
exprt ecopy (expr);
1931
1935
(void )symbol_resolve.replace_expr (ecopy);
1932
1936
@@ -2003,31 +2007,21 @@ static optionalt<exprt> find_counter_example(
2003
2007
typedef std::map<exprt, std::vector<exprt>> array_index_mapt;
2004
2008
2005
2009
// / \related string_constraintt
2006
- class gather_indices_visitort : public const_expr_visitort
2010
+ static array_index_mapt gather_indices ( const exprt &expr)
2007
2011
{
2008
- public:
2009
2012
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)
2016
2018
{
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;
2031
2025
}
2032
2026
2033
2027
// / \param expr: an expression
@@ -2064,33 +2058,14 @@ is_linear_arithmetic_expr(const exprt &expr, const symbol_exprt &var)
2064
2058
// / false otherwise.
2065
2059
static bool universal_only_in_index (const string_constraintt &expr)
2066
2060
{
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 ();)
2080
2062
{
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 ())
2090
2064
return false ;
2065
+ if (it->id () == ID_index)
2066
+ it.next_sibling_or_parent ();
2091
2067
else
2092
- forall_operands (it, e)
2093
- stack.push (valuet (*it, child_index_depth));
2068
+ ++it;
2094
2069
}
2095
2070
return true ;
2096
2071
}
0 commit comments