Skip to content

Commit e7fbcd3

Browse files
Optimize last_index_of for constant argument
1 parent dbf6456 commit e7fbcd3

File tree

1 file changed

+52
-18
lines changed

1 file changed

+52
-18
lines changed

src/solvers/refinement/string_constraint_generator_indexof.cpp

+52-18
Original file line numberDiff line numberDiff line change
@@ -249,25 +249,59 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of_string(
249249
binary_relation_exprt(from_index, ID_le, length_diff),
250250
from_index,
251251
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);
261252

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);
253+
if(!is_constant_string(substring))
254+
{
255+
string_not_contains_constraintt a4(
256+
plus_exprt(offset, from_integer(1, index_type)),
257+
from_index,
258+
plus_exprt(end_index, from_integer(1, index_type)),
259+
from_integer(0, index_type),
260+
substring.length(),
261+
str,
262+
substring);
263+
axioms.push_back(a4);
264+
265+
string_not_contains_constraintt a5(
266+
from_integer(0, index_type),
267+
plus_exprt(end_index, from_integer(1, index_type)),
268+
not_exprt(contains),
269+
from_integer(0, index_type),
270+
substring.length(),
271+
str,
272+
substring);
273+
axioms.push_back(a5);
274+
}
275+
else
276+
{
277+
// Unfold the existential quantifier as a disjunction in case of a constant
278+
// a4 && a5 <=> a6:
279+
// forall n:[0, min(from_index,|str|-|substring|)].
280+
// !contains || n > offset =>
281+
// str[n]!=substring[0] || ... ||
282+
// str[n+|substring|-1]!=substring[|substring|-1]
283+
symbol_exprt qvar2=fresh_univ_index("QA_index_of_string_2", index_type);
284+
mp_integer sub_length;
285+
assert(!to_integer(substring.length(), sub_length));
286+
exprt::operandst disjuncts;
287+
for(mp_integer offset=0; offset<sub_length; ++offset)
288+
{
289+
exprt expr_offset=from_integer(offset, index_type);
290+
plus_exprt shifted(expr_offset, qvar2);
291+
disjuncts.push_back(
292+
not_exprt(equal_exprt(str[shifted], substring[expr_offset])));
293+
}
294+
295+
or_exprt premise(
296+
not_exprt(contains), binary_relation_exprt(qvar, ID_gt, offset));
297+
string_constraintt a6(
298+
qvar2,
299+
from_index,
300+
plus_exprt(from_integer(1, index_type), end_index),
301+
premise,
302+
disjunction(disjuncts));
303+
axioms.push_back(a6);
304+
}
271305

272306
return offset;
273307
}

0 commit comments

Comments
 (0)