Skip to content

Commit 1f7ba2a

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 fb7f6a6 commit 1f7ba2a

File tree

1 file changed

+48
-37
lines changed

1 file changed

+48
-37
lines changed

src/solvers/refinement/string_refinement.cpp

+48-37
Original file line numberDiff line numberDiff line change
@@ -1962,53 +1962,64 @@ static void add_to_index_set(
19621962
}
19631963
}
19641964

1965+
/// Given an expression of the form `\forall q<u. s[i]` initialize the index
1966+
/// 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+
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+
const minus_exprt u_minus_1(upper_bound, from_integer(1, upper_bound.type()));
1999+
replace_expr(qvar, u_minus_1, i);
2000+
add_to_index_set(index_set, ns, s, i);
2001+
}
2002+
19652003
static void initial_index_set(
19662004
index_set_pairt &index_set,
19672005
const namespacet &ns,
19682006
const string_constraintt &axiom)
19692007
{
19702008
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())
2009+
const auto &bound = axiom.upper_bound();
2010+
auto it = axiom.body().depth_begin();
2011+
const auto end = axiom.body().depth_end();
2012+
while(it != end)
19752013
{
1976-
const exprt cur = to_process.back();
1977-
to_process.pop_back();
1978-
if(cur.id() == ID_index && is_char_type(cur.type()))
2014+
if(it->id() == ID_index && is_char_type(it->type()))
19792015
{
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-
}
2016+
const auto &index_expr = to_index_expr(*it);
2017+
const auto &s = index_expr.array();
2018+
initial_index_set(index_set, ns, qvar, bound, s, index_expr.index());
2019+
it.next_sibling_or_parent();
20082020
}
20092021
else
2010-
forall_operands(it, cur)
2011-
to_process.push_back(*it);
2022+
++it;
20122023
}
20132024
}
20142025

0 commit comments

Comments
 (0)