diff options
Diffstat (limited to 'src/theory/strings/sequences_rewriter.cpp')
-rw-r--r-- | src/theory/strings/sequences_rewriter.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/theory/strings/sequences_rewriter.cpp b/src/theory/strings/sequences_rewriter.cpp index 5b046fbc5..f3426690a 100644 --- a/src/theory/strings/sequences_rewriter.cpp +++ b/src/theory/strings/sequences_rewriter.cpp @@ -1458,6 +1458,10 @@ RewriteResponse SequencesRewriter::postRewrite(TNode node) { retNode = rewriteIndexof(node); } + else if (nk == kind::STRING_INDEXOF_RE) + { + retNode = rewriteIndexofRe(node); + } else if (nk == kind::STRING_STRREPL) { retNode = rewriteReplace(node); @@ -2526,6 +2530,64 @@ Node SequencesRewriter::rewriteIndexof(Node node) return node; } +Node SequencesRewriter::rewriteIndexofRe(Node node) +{ + Assert(node.getKind() == STRING_INDEXOF_RE); + NodeManager* nm = NodeManager::currentNM(); + Node s = node[0]; + Node r = node[1]; + Node n = node[2]; + Node zero = nm->mkConst(Rational(0)); + Node slen = nm->mkNode(STRING_LENGTH, s); + + if (ArithEntail::check(zero, n, true) || ArithEntail::check(n, slen, true)) + { + Node ret = nm->mkConst(Rational(-1)); + return returnRewrite(node, ret, Rewrite::INDEXOF_RE_INVALID_INDEX); + } + + if (RegExpEntail::isConstRegExp(r)) + { + if (s.isConst() && n.isConst()) + { + Rational nrat = n.getConst<Rational>(); + cvc5::Rational rMaxInt(cvc5::String::maxSize()); + if (nrat > rMaxInt) + { + // We know that, due to limitations on the size of string constants + // in our implementation, that accessing a position greater than + // rMaxInt is guaranteed to be out of bounds. + Node negone = nm->mkConst(Rational(-1)); + return returnRewrite(node, negone, Rewrite::INDEXOF_RE_MAX_INDEX); + } + + uint32_t start = nrat.getNumerator().toUnsignedInt(); + Node rem = nm->mkConst(s.getConst<String>().substr(start)); + std::pair<size_t, size_t> match = firstMatch(rem, r); + if (match.first != string::npos) + { + Node ret = nm->mkConst(Rational(start + match.first)); + return returnRewrite(node, ret, Rewrite::INDEXOF_RE_EVAL); + } + else + { + Node ret = nm->mkConst(Rational(-1)); + return returnRewrite(node, ret, Rewrite::INDEXOF_RE_EVAL); + } + } + + if (ArithEntail::check(n, zero) && ArithEntail::check(slen, n)) + { + String emptyStr(""); + if (RegExpEntail::testConstStringInRegExp(emptyStr, 0, r)) + { + return returnRewrite(node, n, Rewrite::INDEXOF_RE_EMP_RE); + } + } + } + return node; +} + Node SequencesRewriter::rewriteReplace(Node node) { Assert(node.getKind() == kind::STRING_STRREPL); |