}
else if (tk == STRING_STRIDOF || tk == STRING_INDEXOF_RE)
{
- // (and (>= (f x y n) (- 1)) (<= (f x y n) (str.len x)))
+ // (and
+ // (or (= (f x y n) (- 1)) (>= (f x y n) n))
+ // (<= (f x y n) (str.len x)))
//
// where f in { str.indexof, str.indexof_re }
Node l = nm->mkNode(STRING_LENGTH, t[0]);
- lemma = nm->mkNode(AND,
- nm->mkNode(GEQ, t, nm->mkConst(Rational(-1))),
- nm->mkNode(LEQ, t, l));
+ lemma = nm->mkNode(
+ AND,
+ nm->mkNode(
+ OR, nm->mkConst(Rational(-1)).eqNode(t), nm->mkNode(GEQ, t, t[2])),
+ nm->mkNode(LEQ, t, l));
}
else if (tk == STRING_STOI)
{
Node bvll = nm->mkNode(BOUND_VAR_LIST, l);
Node validLen =
nm->mkNode(AND,
- nm->mkNode(GEQ, l, n),
+ nm->mkNode(GEQ, l, zero),
nm->mkNode(LEQ, l, nm->mkNode(MINUS, sLen, skk)));
Node matchBody = nm->mkNode(
AND,
validLen,
nm->mkNode(STRING_IN_REGEXP, nm->mkNode(STRING_SUBSTR, s, skk, l), r));
// skk != -1 =>
- // exists l. n <= l < len(s) - skk ^ in_re(substr(s, skk, l), r))
+ // exists l. (0 <= l < len(s) - skk) ^ in_re(substr(s, skk, l), r))
Node match = nm->mkNode(
OR, retNegOne, mkForallInternal(bvll, matchBody.negate()).negate());
// n <= i < ite(skk = -1, len(s), skk) ^ 0 < l <= len(s) - i =>
// ~in_re(substr(s, i, l), r)) ^
// (skk != -1 =>
- // exists l. n <= l < len(s) - skk ^ in_re(substr(s, skk, l), r))
+ // exists l. 0 <= l < len(s) - skk ^ in_re(substr(s, skk, l), r))
//
// Note that this reduction relies on eager reduction lemmas being sent to
// properly limit the range of skk.
Node emp = Word::mkEmptyWord(t.getType());
Node yp = nm->mkNode(REGEXP_DIFF, y, nm->mkNode(STRING_TO_REGEXP, emp));
- Node idx = nm->mkNode(STRING_INDEXOF_RE, x, yp, zero);
// indexof_re(x, y', 0) = -1
- Node noMatch = idx.eqNode(negOne);
+ Node noMatch = nm->mkNode(STRING_INDEXOF_RE, x, yp, zero).eqNode(negOne);
Node ufno = nm->mkNode(APPLY_UF, uf, numOcc);
Node usno = nm->mkNode(APPLY_UF, us, numOcc);
Node ii = nm->mkNode(MINUS, ufip1, ulip1);
std::vector<Node> flem;
- // Ul(i) > 0
+ // Ul(i + 1) > 0
flem.push_back(nm->mkNode(GT, ulip1, zero));
// Uf(i + 1) = indexof_re(x, yp, Uf(i)) + Ul(i + 1)
flem.push_back(ufip1.eqNode(
// k = Us(0) ^ Us(numOcc) = substr(x, Uf(numOcc)) ^
// Uf(0) = 0 ^ indexof_re(substr(x, Uf(numOcc)), y', 0) = -1 ^
// forall i. 0 <= i < nummOcc =>
- // Ul(i) > 0 ^
+ // Ul(i + 1) > 0 ^
// Uf(i + 1) = indexof_re(x, yp, Uf(i)) + Ul(i + 1) ^
// in_re(substr(x, ii, Ul(i + 1)), y') ^
// forall l. 0 < l < Ul(i + 1) =>
- // ~in_re(substr(x, Uf(i + 1) - Ul(i + 1), l), y')
+ // ~in_re(substr(x, ii, l), y')
// Us(i) = substr(x, Uf(i), ii - Uf(i)) ++ z ++ Us(i + 1)
- // where ii = Uf(i + 1) - Ul(i)
+ // where ii = Uf(i + 1) - Ul(i + 1)
// where y' = re.diff(y, "")
//
// Conceptually, y' is the regex y but excluding the empty string (because
regress0/strings/ilc-like.smt2
regress0/strings/indexof-sym-simp.smt2
regress0/strings/indexof_re.smt2
+ regress0/strings/indexof_re-start-index.smt2
regress0/strings/is_digit_simple.smt2
regress0/strings/issue1189.smt2
regress0/strings/issue2958.smt2
regress2/strings/issue6483.smt2
regress2/strings/issue6057-replace-re-all.smt2
regress2/strings/issue6057-replace-re-all-simplified.smt2
+ regress2/strings/issue6636-replace-re-all.smt2
+ regress2/strings/issue6637-replace-re-all.smt2
regress2/strings/issue918.smt2
regress2/strings/non_termination_regular_expression6.smt2
regress2/strings/range-perf.smt2