Skip to content

Commit 9301bc9

Browse files
Correct initial index set computation
The initial_index_set function was not taking into account if expressions. We now recursively add the components of the if expression. The function was also performing an unecessary look-up for a quantified variable.
1 parent d157f50 commit 9301bc9

File tree

1 file changed

+52
-37
lines changed

1 file changed

+52
-37
lines changed

src/solvers/refinement/string_refinement.cpp

+52-37
Original file line numberDiff line numberDiff line change
@@ -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+
19682010
static 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

Comments
 (0)