@@ -1965,53 +1965,68 @@ static void add_to_index_set(
19651965 }
19661966}
19671967
1968+ // / Given an array access of the form \a s[i] assumed to be part of a formula
1969+ // / \f$ \forall q < u. charconstraint \f$, initialize the index set of \a s
1970+ // / so that:
1971+ // / - \f$ i[q -> u - 1] \f$ appears in the index set of \a s if \a s is a
1972+ // / symbol
1973+ // / - if \a s is an array expression, all index from \a 0 to
1974+ // / \f$ s.length - 1 \f$ are in the index set
1975+ // / - if \a s is an if expression we apply this procedure to the true and
1976+ // / false cases
1977+ // / \param index_set: the index_set to initialize
1978+ // / \param ns: namespace, used for simplifying indexes
1979+ // / \param qvar: the quantified variable \a q
1980+ // / \param upper_bound: bound \a u on the quantified variable
1981+ // / \param s: expression representing a string
1982+ // / \param i: expression representing the index at which \a s is accessed
1983+ static void initial_index_set (
1984+ index_set_pairt &index_set,
1985+ const namespacet &ns,
1986+ const exprt &qvar,
1987+ const exprt &upper_bound,
1988+ const exprt &s,
1989+ const exprt &i)
1990+ {
1991+ PRECONDITION (s.id () == ID_symbol || s.id () == ID_array || s.id () == ID_if);
1992+ if (s.id () == ID_array)
1993+ {
1994+ for (std::size_t j = 0 ; j < s.operands ().size (); ++j)
1995+ add_to_index_set (index_set, ns, s, from_integer (j, i.type ()));
1996+ return ;
1997+ }
1998+ if (auto ite = expr_try_dynamic_cast<if_exprt>(s))
1999+ {
2000+ initial_index_set (index_set, ns, qvar, upper_bound, ite->true_case (), i);
2001+ initial_index_set (index_set, ns, qvar, upper_bound, ite->false_case (), i);
2002+ return ;
2003+ }
2004+ const minus_exprt u_minus_1 (upper_bound, from_integer (1 , upper_bound.type ()));
2005+ exprt i_copy = i;
2006+ replace_expr (qvar, u_minus_1, i_copy);
2007+ add_to_index_set (index_set, ns, s, i_copy);
2008+ }
2009+
19682010static void initial_index_set (
19692011 index_set_pairt &index_set,
19702012 const namespacet &ns,
19712013 const string_constraintt &axiom)
19722014{
19732015 const symbol_exprt &qvar=axiom.univ_var ();
1974- std::list<exprt> to_process ;
1975- to_process. push_back ( axiom.body ());
1976-
1977- while (!to_process. empty () )
2016+ const auto &bound = axiom. upper_bound () ;
2017+ auto it = axiom.body (). depth_begin ( );
2018+ const auto end = axiom. body (). depth_end ();
2019+ while (it != end )
19782020 {
1979- const exprt cur = to_process.back ();
1980- to_process.pop_back ();
1981- if (cur.id () == ID_index && is_char_type (cur.type ()))
2021+ if (it->id () == ID_index && is_char_type (it->type ()))
19822022 {
1983- const index_exprt &index_expr = to_index_expr (cur);
1984- const exprt &s = index_expr.array ();
1985- const exprt &i = index_expr.index ();
1986-
1987- if (s.id () == ID_array)
1988- {
1989- for (std::size_t j = 0 ; j < s.operands ().size (); ++j)
1990- add_to_index_set (index_set, ns, s, from_integer (j, i.type ()));
1991- }
1992- else
1993- {
1994- const bool has_quant_var = find_qvar (i, qvar);
1995-
1996- // if cur is of the form s[i] and no quantified variable appears in i
1997- if (!has_quant_var)
1998- {
1999- add_to_index_set (index_set, ns, s, i);
2000- }
2001- else
2002- {
2003- // otherwise we add k-1
2004- exprt copy (i);
2005- const minus_exprt kminus1 (
2006- axiom.upper_bound (), from_integer (1 , axiom.upper_bound ().type ()));
2007- replace_expr (qvar, kminus1, copy);
2008- add_to_index_set (index_set, ns, s, copy);
2009- }
2010- }
2023+ const auto &index_expr = to_index_expr (*it);
2024+ const auto &s = index_expr.array ();
2025+ initial_index_set (index_set, ns, qvar, bound, s, index_expr.index ());
2026+ it.next_sibling_or_parent ();
20112027 }
20122028 else
2013- forall_operands (it, cur)
2014- to_process.push_back (*it);
2029+ ++it;
20152030 }
20162031}
20172032
0 commit comments