@@ -98,16 +98,14 @@ exprt string_constraint_generatort::add_axioms_for_substring(
98
98
}
99
99
100
100
// / Add axioms ensuring that `res` corresponds to the substring of `str`
101
- // / between indexes `start` and `end`.
101
+ // / between indexes `start' = max(start, 0)` and
102
+ // / `end' = max(min(end, |str|), start')`.
102
103
// /
103
104
// / These axioms are:
104
- // / 1. \f$ {\tt start} < {\tt end} \Rightarrow
105
- // / |{\tt res}| = {\tt end} - {\tt start} \f$
106
- // / 2. \f$ {\tt start} \ge {\tt end} \Rightarrow |{\tt res}| = 0 \f$
107
- // / 3. \f$ |{\tt str}| > {\tt end} \f$
108
- // / 4. \f$ \forall i<|{\tt str}|.\ {\tt res}[i]={\tt str}[{\tt start}+i] \f$
109
- // / \todo Should return code different from 0 if `|str| <= |end|` instead of
110
- // / adding constraint 3.
105
+ // / 1. \f$ |{\tt res}| = end' - start' \f$
106
+ // / 2. \f$ \forall i<|{\tt res}|.\ {\tt res}[i]={\tt str}[{\tt start'}+i] \f$
107
+ // / \todo Should return code different from 0 if `start' != start` or
108
+ // / `end' != end`
111
109
// / \param res: array of characters expression
112
110
// / \param str: array of characters expression
113
111
// / \param start: integer expression
@@ -123,26 +121,19 @@ exprt string_constraint_generatort::add_axioms_for_substring(
123
121
PRECONDITION (start.type ()==index_type);
124
122
PRECONDITION (end.type ()==index_type);
125
123
126
- // We add axioms:
124
+ const exprt start1 = maximum (start, from_integer (0 , start.type ()));
125
+ const exprt end1 = maximum (minimum (end, str.length ()), start1);
127
126
128
- implies_exprt a1 (
129
- binary_relation_exprt (start, ID_lt, end),
130
- res.axiom_for_has_length (minus_exprt (end, start)));
131
- lemmas.push_back (a1);
127
+ // Axiom 1.
128
+ lemmas.push_back (equal_exprt (res.length (), minus_exprt (end1, start1)));
132
129
133
- exprt is_empty=res.axiom_for_has_length (from_integer (0 , index_type));
134
- implies_exprt a2 (binary_relation_exprt (start, ID_ge, end), is_empty);
135
- lemmas.push_back (a2);
130
+ // Axiom 2.
131
+ constraints.push_back ([&] { // NOLINT
132
+ const symbol_exprt idx = fresh_univ_index (" QA_index_substring" , index_type);
133
+ return string_constraintt (
134
+ idx, res.length (), equal_exprt (res[idx], str[plus_exprt (start1, idx)]));
135
+ }());
136
136
137
- // Warning: check what to do if the string is not long enough
138
- lemmas.push_back (str.axiom_for_length_ge (end));
139
-
140
- symbol_exprt idx=fresh_univ_index (" QA_index_substring" , index_type);
141
- string_constraintt a4 (idx,
142
- res.length (),
143
- equal_exprt (res[idx],
144
- str[plus_exprt (start, idx)]));
145
- constraints.push_back (a4);
146
137
return from_integer (0 , signedbv_typet (32 ));
147
138
}
148
139
0 commit comments