@@ -82,8 +82,8 @@ Function: string_constraint_generatort::add_axioms_for_index_of_string
82
82
83
83
Purpose: add axioms stating that the returned value is an index greater than
84
84
from_index such that str at that index starts with substring and is
85
- the first occurence of substring in str, or -1 if str does not contain
86
- substring.
85
+ the first occurence of substring in str after from_index,
86
+ or returned value is -1 if str does not contain substring.
87
87
88
88
\*******************************************************************/
89
89
@@ -190,12 +190,17 @@ exprt string_constraint_generatort::add_axioms_for_index_of_string(
190
190
191
191
Function: string_constraint_generatort::add_axioms_for_last_index_of_string
192
192
193
- Inputs: two string expressions and an integer expression
193
+ Inputs:
194
+ str - a string expression
195
+ substring - a string expression
196
+ from_index - an expression representing an index in strings
194
197
195
198
Outputs: a integer expression
196
199
197
- Purpose: add axioms stating that the returned value is either -1 or less
198
- than from_index and the string beggining there has prefix substring
200
+ Purpose: add axioms stating that the returned value is an index less than
201
+ from_index such that str at that index starts with substring and is
202
+ the last occurence of substring in str before from_index,
203
+ or the returned value is -1 if str does not contain substring.
199
204
200
205
\*******************************************************************/
201
206
@@ -209,10 +214,16 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of_string(
209
214
symbol_exprt contains=fresh_boolean (" contains_substring" );
210
215
211
216
// We add axioms:
212
- // a1 : contains => |substring| >= length &&offset <= from_index
213
- // a2 : !contains => offset=-1
214
- // a3 : forall 0 <= witness<substring.length,
215
- // contains => str[witness+offset]=substring[witness]
217
+ // a1 : contains => |substring| >= length && offset <= from_index
218
+ // a2 : !contains <=> offset=-1
219
+ // a3 : forall n:[0, substring.length[,
220
+ // contains => str[n+offset]=substring[n]
221
+ // a4 : forall n:[offset+1, min(from_index, |str| - |substring|)].
222
+ // contains =>
223
+ // (exists m:[0,|substring|[. str[m+n]!=substring[m]])
224
+ // a5: forall n:[0, min(from_index, |str| - |substring|)].
225
+ // !contains =>
226
+ // (exists m:[0,|substring|[. str[m+n]!=substring[m])
216
227
217
228
implies_exprt a1 (
218
229
contains,
@@ -222,7 +233,7 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of_string(
222
233
binary_relation_exprt (offset, ID_le, from_index)));
223
234
axioms.push_back (a1);
224
235
225
- implies_exprt a2 (
236
+ equal_exprt a2 (
226
237
not_exprt (contains),
227
238
equal_exprt (offset, from_integer (-1 , index_type)));
228
239
axioms.push_back (a2);
@@ -232,6 +243,32 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of_string(
232
243
string_constraintt a3 (qvar, substring.length (), contains, constr3);
233
244
axioms.push_back (a3);
234
245
246
+ // end_index is min(from_index, |str| - |substring|)
247
+ minus_exprt length_diff (str.length (), substring.length ());
248
+ if_exprt end_index (
249
+ binary_relation_exprt (from_index, ID_le, length_diff),
250
+ from_index,
251
+ length_diff);
252
+ string_not_contains_constraintt a4 (
253
+ plus_exprt (offset, from_integer (1 , index_type)),
254
+ from_index,
255
+ end_index,
256
+ from_integer (0 , index_type),
257
+ substring.length (),
258
+ str,
259
+ substring);
260
+ axioms.push_back (a4);
261
+
262
+ string_not_contains_constraintt a5 (
263
+ from_integer (0 , index_type),
264
+ end_index,
265
+ not_exprt (contains),
266
+ from_integer (0 , index_type),
267
+ substring.length (),
268
+ str,
269
+ substring);
270
+ axioms.push_back (a5);
271
+
235
272
return offset;
236
273
}
237
274
0 commit comments