@@ -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 different 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,38 @@ 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
{
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
+ }
2119
2139
2120
- if (it != expr.depth_end ())
2121
- return to_index_expr (*it).index ();
2122
- return {};
2140
+ return index;
2123
2141
}
2124
2142
2125
2143
// / Instantiates a string constraint by substituting the quantifiers.
0 commit comments