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