summaryrefslogtreecommitdiff
path: root/src/theory/strings/sequences_rewriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/strings/sequences_rewriter.cpp')
-rw-r--r--src/theory/strings/sequences_rewriter.cpp62
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);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback