Skip to content

Commit 7eb7922

Browse files
fixup! Correct find_index function for if-expressions
1 parent 9301bc9 commit 7eb7922

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

src/solvers/refinement/string_refinement.cpp

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,7 @@ static void update_index_set(
20972097
/// Finds an index on `str` used in `expr` that contains `qvar`, for instance
20982098
/// with arguments ``(str[k]=='a')``, `str`, and `k`, the function should
20992099
/// return `k`.
2100+
/// If two different such indexes exist, an invariant will fail.
21002101
/// \param [in] expr: the expression to search
21012102
/// \param [in] str: the string which must be indexed
21022103
/// \param [in] qvar: the universal variable that must be in the index
@@ -2105,21 +2106,38 @@ static void update_index_set(
21052106
static optionalt<exprt>
21062107
find_index(const exprt &expr, const exprt &str, const symbol_exprt &qvar)
21072108
{
2108-
const auto it = std::find_if(
2109-
expr.depth_begin(), expr.depth_end(), [&](const exprt &e) { // NOLINT
2110-
if(auto index_expr = expr_try_dynamic_cast<index_exprt>(e))
2111-
{
2112-
const auto &arr = index_expr->array();
2113-
const auto str_it = std::find(arr.depth_begin(), arr.depth_end(), str);
2114-
return str_it != arr.depth_end() &&
2115-
find_qvar(index_expr->index(), qvar);
2116-
}
2117-
return false;
2118-
});
2109+
auto index_str_containing_qvar = [&](const exprt &e) { // NOLINT
2110+
if(auto index_expr = expr_try_dynamic_cast<index_exprt>(e))
2111+
{
2112+
const auto &arr = index_expr->array();
2113+
const auto str_it = std::find(arr.depth_begin(), arr.depth_end(), str);
2114+
return str_it != arr.depth_end() && find_qvar(index_expr->index(), qvar);
2115+
}
2116+
return false;
2117+
};
2118+
2119+
auto it = std::find_if(
2120+
expr.depth_begin(), expr.depth_end(), index_str_containing_qvar);
2121+
if(it == expr.depth_end())
2122+
return {};
2123+
const exprt &index = to_index_expr(*it).index();
2124+
2125+
// Check that there are no two such indexes
2126+
it.next_sibling_or_parent();
2127+
while(it != expr.depth_end())
2128+
{
2129+
if(index_str_containing_qvar(*it))
2130+
{
2131+
INVARIANT(
2132+
to_index_expr(*it).index() == index,
2133+
"string should always be indexed by same value in a given formula");
2134+
it.next_sibling_or_parent();
2135+
}
2136+
else
2137+
++it;
2138+
}
21192139

2120-
if(it != expr.depth_end())
2121-
return to_index_expr(*it).index();
2122-
return {};
2140+
return index;
21232141
}
21242142

21252143
/// Instantiates a string constraint by substituting the quantifiers.

0 commit comments

Comments
 (0)