Skip to content

Commit 0ec097c

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

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

src/solvers/refinement/string_refinement.cpp

+24-13
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 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,31 @@ static void update_index_set(
21052106
static optionalt<exprt>
21062107
find_index(const exprt &expr, const exprt &str, const symbol_exprt &qvar)
21072108
{
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+
21082119
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-
});
2120+
expr.depth_begin(), expr.depth_end(), index_str_containing_qvar);
2121+
if(it == expr.depth_end())
2122+
return {};
2123+
2124+
// Check that there are no two such indexes
2125+
auto next_it = it;
2126+
next_it.next_sibling_or_parent();
2127+
bool has_second_index =
2128+
std::find_if(next_it, expr.depth_end(), index_str_containing_qvar)
2129+
!= expr.depth_end();
2130+
INVARIANT(
2131+
!has_second_index, "string should only be indexed once in a given formula");
21192132

2120-
if(it != expr.depth_end())
2121-
return to_index_expr(*it).index();
2122-
return {};
2133+
return to_index_expr(*it).index();
21232134
}
21242135

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

0 commit comments

Comments
 (0)