@@ -2054,33 +2054,14 @@ is_linear_arithmetic_expr(const exprt &expr, const symbol_exprt &var)
2054
2054
// / false otherwise.
2055
2055
static bool universal_only_in_index (const string_constraintt &expr)
2056
2056
{
2057
- // For efficiency, we do a depth-first search of the
2058
- // body. The exprt visitors do a BFS and hide the stack/queue, so we would
2059
- // need to store a map from child to parent.
2060
-
2061
- // The unsigned int represents index depth we are. For example, if we are
2062
- // considering the fragment `a[b[x]]` (not inside an index expression), then
2063
- // the stack would look something like `[..., (a, 0), (b, 1), (x, 2)]`.
2064
- typedef std::pair<exprt, unsigned > valuet;
2065
- std::stack<valuet> stack;
2066
- // We start at 0 since expr is not an index expression, so expr.body() is not
2067
- // in an index expression.
2068
- stack.push (valuet (expr.body (), 0 ));
2069
- while (!stack.empty ())
2057
+ for (auto it = expr.body ().depth_begin (); it != expr.body ().depth_end ();)
2070
2058
{
2071
- // Inspect current value
2072
- const valuet cur=stack.top ();
2073
- stack.pop ();
2074
- const exprt e=cur.first ;
2075
- const unsigned index_depth=cur.second ;
2076
- const unsigned child_index_depth=index_depth+(e.id ()==ID_index?0 :1 );
2077
-
2078
- // If we found the universal variable not in an index_exprt, fail
2079
- if (e==expr.univ_var () && index_depth==0 )
2059
+ if (*it == expr.univ_var ())
2080
2060
return false ;
2061
+ if (it->id () == ID_index)
2062
+ it.next_sibling_or_parent ();
2081
2063
else
2082
- forall_operands (it, e)
2083
- stack.push (valuet (*it, child_index_depth));
2064
+ ++it;
2084
2065
}
2085
2066
return true ;
2086
2067
}
0 commit comments