@@ -2097,6 +2097,7 @@ static void update_index_set(
2097
2097
// / Finds an index on `str` used in `expr` that contains `qvar`, for instance
2098
2098
// / with arguments ``(str[k]=='a')``, `str`, and `k`, the function should
2099
2099
// / return `k`.
2100
+ // / If two such indexes exist, an invariant will fail.
2100
2101
// / \param [in] expr: the expression to search
2101
2102
// / \param [in] str: the string which must be indexed
2102
2103
// / \param [in] qvar: the universal variable that must be in the index
@@ -2105,21 +2106,31 @@ static void update_index_set(
2105
2106
static optionalt<exprt>
2106
2107
find_index (const exprt &expr, const exprt &str, const symbol_exprt &qvar)
2107
2108
{
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
+
2108
2119
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" );
2119
2132
2120
- if (it != expr.depth_end ())
2121
- return to_index_expr (*it).index ();
2122
- return {};
2133
+ return to_index_expr (*it).index ();
2123
2134
}
2124
2135
2125
2136
// / Instantiates a string constraint by substituting the quantifiers.
0 commit comments