@@ -2054,33 +2054,14 @@ is_linear_arithmetic_expr(const exprt &expr, const symbol_exprt &var)
20542054// / false otherwise.
20552055static bool universal_only_in_index (const string_constraintt &expr)
20562056{
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 ();)
20702058 {
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 ())
20802060 return false ;
2061+ if (it->id () == ID_index)
2062+ it.next_sibling_or_parent ();
20812063 else
2082- forall_operands (it, e)
2083- stack.push (valuet (*it, child_index_depth));
2064+ ++it;
20842065 }
20852066 return true ;
20862067}
0 commit comments