Skip to content

Commit 8495451

Browse files
committed
For contains, added bounds for substring index in !contains case
Previously, the startpos variable (the index at which the substring occurs) was only bound properly when the substring was contained in the string being searched. Hence, in the case where the substring was not contained, the notdet string would become enourmous, and during evaluation would cause out of memory errors. Now with startpos constrained, the solver does not attempt these enourmous strings.
1 parent 9ab281b commit 8495451

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

src/solvers/refinement/string_constraint_generator_testing.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,10 @@ exprt string_constraint_generatort::add_axioms_for_contains(
194194

195195
// We add axioms:
196196
// a1 : contains ==> |s0| >= |s1|
197-
// a2 : 0 <= startpos <= |s0|-|s1|
198-
// a3 : forall qvar < |s1|. contains ==> s1[qvar] = s0[startpos + qvar]
199-
// a4 : !contains ==> |s1| > |s0| ||
197+
// a2 : contains ==> 0 <= startpos <= |s0|-|s1|
198+
// a3 : !contains ==> startpos = -1
199+
// a4 : forall qvar < |s1|. contains ==> s1[qvar] = s0[startpos + qvar]
200+
// a5 : !contains ==> |s1| > |s0| ||
200201
// (forall startpos <= |s0| - |s1|.
201202
// exists witness < |s1|. s1[witness] != s0[witness + startpos])
202203

@@ -211,9 +212,14 @@ exprt string_constraint_generatort::add_axioms_for_contains(
211212
implies_exprt a2(contains, bounds);
212213
axioms.push_back(a2);
213214

215+
implies_exprt a3(
216+
not_exprt(contains),
217+
equal_exprt(startpos, from_integer(-1, index_type)));
218+
axioms.push_back(a3);
219+
214220
if(constant)
215221
{
216-
// If the string is constant, we can use a more efficient axiom for a3:
222+
// If the string is constant, we can use a more efficient axiom for a4:
217223
// contains ==> AND_{i < |s1|} s1[i] = s0[startpos + i]
218224
mp_integer s1_length;
219225
assert(!to_integer(s1.length(), s1_length));
@@ -224,10 +230,10 @@ exprt string_constraint_generatort::add_axioms_for_contains(
224230
plus_exprt shifted_i(expr_i, startpos);
225231
conjuncts.push_back(equal_exprt(s1[expr_i], s0[shifted_i]));
226232
}
227-
implies_exprt a3(contains, conjunction(conjuncts));
228-
axioms.push_back(a3);
233+
implies_exprt a4(contains, conjunction(conjuncts));
234+
axioms.push_back(a4);
229235

230-
// The a4 constraint for constant strings translates to:
236+
// The a5 constraint for constant strings translates to:
231237
// !contains ==> |s1| > |s0| ||
232238
// (forall qvar <= |s0| - |s1|.
233239
// !(AND_{i < |s1|} s1[i] == s0[i + qvar])
@@ -244,30 +250,30 @@ exprt string_constraint_generatort::add_axioms_for_contains(
244250
conjuncts1.push_back(equal_exprt(s1[expr_i], s0[shifted_i]));
245251
}
246252

247-
string_constraintt a4(
253+
string_constraintt a5(
248254
qvar,
249255
plus_exprt(from_integer(1, index_type), length_diff),
250256
and_exprt(not_exprt(contains), s0.axiom_for_is_longer_than(s1)),
251257
not_exprt(conjunction(conjuncts1)));
252-
axioms.push_back(a4);
258+
axioms.push_back(a5);
253259
}
254260
else
255261
{
256262
symbol_exprt qvar=fresh_univ_index("QA_contains", index_type);
257263
exprt qvar_shifted=plus_exprt(qvar, startpos);
258-
string_constraintt a3(
264+
string_constraintt a4(
259265
qvar, s1.length(), contains, equal_exprt(s1[qvar], s0[qvar_shifted]));
260-
axioms.push_back(a3);
266+
axioms.push_back(a4);
261267

262268
// We rewrite axiom a4 as:
263269
// forall startpos <= |s0|-|s1|. (!contains && |s0| >= |s1|)
264270
// ==> exists witness < |s1|. s1[witness] != s0[startpos+witness]
265-
string_not_contains_constraintt a4(
271+
string_not_contains_constraintt a5(
266272
from_integer(0, index_type),
267273
plus_exprt(from_integer(1, index_type), length_diff),
268274
and_exprt(not_exprt(contains), s0.axiom_for_is_longer_than(s1)),
269275
from_integer(0, index_type), s1.length(), s0, s1);
270-
axioms.push_back(a4);
276+
axioms.push_back(a5);
271277
}
272278
return typecast_exprt(contains, f.type());
273279
}

0 commit comments

Comments
 (0)