15
15
#include < solvers/refinement/string_constraint_generator.h>
16
16
17
17
// / Add axioms stating that the returned value is the index within str of the
18
- // / first occurence of c starting the search at from_index, or -1 if no such
18
+ // / first occurrence of c starting the search at from_index, or -1 if no such
19
19
// / character occurs at or after position from_index.
20
20
// / \param str: a string expression
21
21
// / \param c: an expression representing a character
@@ -69,7 +69,7 @@ exprt string_constraint_generatort::add_axioms_for_index_of(
69
69
}
70
70
71
71
// / Add axioms stating that the returned value is the index within haystack of
72
- // / the first occurence of needle starting the search at from_index, or -1 if
72
+ // / the first occurrence of needle starting the search at from_index, or -1 if
73
73
// / needle does not occur at or after position from_index.
74
74
// / \param haystack: a string expression
75
75
// / \param needle: a string expression
@@ -92,7 +92,7 @@ exprt string_constraint_generatort::add_axioms_for_index_of_string(
92
92
// contains ==> haystack[n+offset]=needle[n]
93
93
// a4 : forall n:[from_index,offset[.
94
94
// contains ==> (exists m:[0,|needle|[. haystack[m+n] != needle[m]])
95
- // a5: forall n:[from_index,|haystack|-|needle|[ .
95
+ // a5: forall n:[from_index,|haystack|-|needle|] .
96
96
// !contains ==> (exists m:[0,|needle|[. haystack[m+n] != needle[m])
97
97
98
98
implies_exprt a1 (
@@ -116,70 +116,35 @@ exprt string_constraint_generatort::add_axioms_for_index_of_string(
116
116
equal_exprt (haystack[plus_exprt (qvar, offset)], needle[qvar]));
117
117
axioms.push_back (a3);
118
118
119
- if (!is_constant_string (needle))
120
- {
121
- // string_not contains_constraintt are formulas of the form:
122
- // forall x in [lb,ub[. p(x) => exists y in [lb,ub[. s1[x+y] != s2[y]
123
- string_not_contains_constraintt a4 (
124
- from_index,
125
- offset,
126
- contains,
127
- from_integer (0 , index_type),
128
- needle.length (),
129
- haystack,
130
- needle);
131
- axioms.push_back (a4);
132
-
133
- string_not_contains_constraintt a5 (
134
- from_index,
119
+ // string_not contains_constraintt are formulas of the form:
120
+ // forall x in [lb,ub[. p(x) => exists y in [lb,ub[. s1[x+y] != s2[y]
121
+ string_not_contains_constraintt a4 (
122
+ from_index,
123
+ offset,
124
+ contains,
125
+ from_integer (0 , index_type),
126
+ needle.length (),
127
+ haystack,
128
+ needle);
129
+ axioms.push_back (a4);
130
+
131
+ string_not_contains_constraintt a5 (
132
+ from_index,
133
+ plus_exprt ( // Add 1 for inclusive upper bound.
135
134
minus_exprt (haystack.length (), needle.length ()),
136
- not_exprt (contains),
137
- from_integer (0 , index_type),
138
- needle.length (),
139
- haystack,
140
- needle);
141
- axioms.push_back (a5);
142
- }
143
- else
144
- {
145
- // Unfold the existential quantifier as a disjunction in case of a constant
146
- // a4 && a5 <=> a6:
147
- // forall n:[from_index,|haystack|-|needle|].
148
- // !contains || n < offset ==>
149
- // haystack[n] != needle[0] || ... ||
150
- // haystack[n+|needle|-1] != needle[|needle|-1]
151
- symbol_exprt qvar2=fresh_univ_index (" QA_index_of_string_2" , index_type);
152
- mp_integer sub_length;
153
- INVARIANT (
154
- !to_integer (needle.length (), sub_length),
155
- string_refinement_invariantt (" a constant string must have constant "
156
- " length" ));
157
- exprt::operandst disjuncts;
158
- for (mp_integer offset=0 ; offset<sub_length; ++offset)
159
- {
160
- exprt expr_offset=from_integer (offset, index_type);
161
- plus_exprt shifted (expr_offset, qvar2);
162
- disjuncts.push_back (
163
- not_exprt (equal_exprt (haystack[shifted], needle[expr_offset])));
164
- }
165
-
166
- or_exprt premise (
167
- not_exprt (contains), binary_relation_exprt (qvar2, ID_lt, offset));
168
- minus_exprt length_diff (haystack.length (), needle.length ());
169
- string_constraintt a6 (
170
- qvar2,
171
- from_index,
172
- plus_exprt (from_integer (1 , index_type), length_diff),
173
- premise,
174
- disjunction (disjuncts));
175
- axioms.push_back (a6);
176
- }
135
+ from_integer (1 , index_type)),
136
+ not_exprt (contains),
137
+ from_integer (0 , index_type),
138
+ needle.length (),
139
+ haystack,
140
+ needle);
141
+ axioms.push_back (a5);
177
142
178
143
return offset;
179
144
}
180
145
181
146
// / Add axioms stating that the returned value is the index within haystack of
182
- // / the last occurence of needle starting the search backward at from_index (ie
147
+ // / the last occurrence of needle starting the search backward at from_index (ie
183
148
// / the index is smaller or equal to from_index), or -1 if needle does not occur
184
149
// / before from_index.
185
150
// / \param haystack: a string expression
@@ -235,62 +200,25 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of_string(
235
200
from_index,
236
201
length_diff);
237
202
238
- if (!is_constant_string (needle))
239
- {
240
- string_not_contains_constraintt a4 (
241
- plus_exprt (offset, from_integer (1 , index_type)),
242
- plus_exprt (end_index, from_integer (1 , index_type)),
243
- contains,
244
- from_integer (0 , index_type),
245
- needle.length (),
246
- haystack,
247
- needle);
248
- axioms.push_back (a4);
249
-
250
- string_not_contains_constraintt a5 (
251
- from_integer (0 , index_type),
252
- plus_exprt (end_index, from_integer (1 , index_type)),
253
- not_exprt (contains),
254
- from_integer (0 , index_type),
255
- needle.length (),
256
- haystack,
257
- needle);
258
- axioms.push_back (a5);
259
- }
260
- else
261
- {
262
- // Unfold the existential quantifier as a disjunction in case of a constant
263
- // a4 && a5 <=> a6:
264
- // forall n:[0, min(from_index, |haystack| - |needle|)].
265
- // !contains || (n > offset) ==>
266
- // haystack[n] != needle[0] || ... ||
267
- // haystack[n+|needle|-1] != needle[|needle|-1]
268
- symbol_exprt qvar2=fresh_univ_index (" QA_index_of_string_2" , index_type);
269
- mp_integer sub_length;
270
- INVARIANT (
271
- !to_integer (needle.length (), sub_length),
272
- string_refinement_invariantt (" a constant string must have constant "
273
- " length" ));
274
- exprt::operandst disjuncts;
275
- for (mp_integer offset=0 ; offset<sub_length; ++offset)
276
- {
277
- exprt expr_offset=from_integer (offset, index_type);
278
- plus_exprt shifted (expr_offset, qvar2);
279
- disjuncts.push_back (
280
- not_exprt (equal_exprt (haystack[shifted], needle[expr_offset])));
281
- }
282
-
283
- or_exprt premise (
284
- not_exprt (contains), binary_relation_exprt (qvar2, ID_gt, offset));
285
-
286
- string_constraintt a6 (
287
- qvar2,
288
- from_integer (0 , index_type),
289
- plus_exprt (from_integer (1 , index_type), end_index),
290
- premise,
291
- disjunction (disjuncts));
292
- axioms.push_back (a6);
293
- }
203
+ string_not_contains_constraintt a4 (
204
+ plus_exprt (offset, from_integer (1 , index_type)),
205
+ plus_exprt (end_index, from_integer (1 , index_type)),
206
+ contains,
207
+ from_integer (0 , index_type),
208
+ needle.length (),
209
+ haystack,
210
+ needle);
211
+ axioms.push_back (a4);
212
+
213
+ string_not_contains_constraintt a5 (
214
+ from_integer (0 , index_type),
215
+ plus_exprt (end_index, from_integer (1 , index_type)),
216
+ not_exprt (contains),
217
+ from_integer (0 , index_type),
218
+ needle.length (),
219
+ haystack,
220
+ needle);
221
+ axioms.push_back (a5);
294
222
295
223
return offset;
296
224
}
@@ -333,7 +261,7 @@ exprt string_constraint_generatort::add_axioms_for_index_of(
333
261
}
334
262
335
263
// / Add axioms stating that the returned value is the index within str of the
336
- // / last occurence of c starting the search backward at from_index, or -1 if no
264
+ // / last occurrence of c starting the search backward at from_index, or -1 if no
337
265
// / such character occurs at or before position from_index.
338
266
// / \param str: a string expression
339
267
// / \param c: an expression representing a character
@@ -373,7 +301,7 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of(
373
301
equal_exprt (str[index], c)));
374
302
axioms.push_back (a3);
375
303
376
- symbol_exprt n=fresh_univ_index (" QA_last_index_of " , index_type);
304
+ symbol_exprt n=fresh_univ_index (" QA_last_index_of1 " , index_type);
377
305
string_constraintt a4 (
378
306
n,
379
307
plus_exprt (index, index1),
@@ -382,7 +310,7 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of(
382
310
not_exprt (equal_exprt (str[n], c)));
383
311
axioms.push_back (a4);
384
312
385
- symbol_exprt m=fresh_univ_index (" QA_last_index_of " , index_type);
313
+ symbol_exprt m=fresh_univ_index (" QA_last_index_of2 " , index_type);
386
314
string_constraintt a5 (
387
315
m,
388
316
from_index_plus_one,
0 commit comments