diff options
author | Andres Noetzli <andres.noetzli@gmail.com> | 2019-02-13 12:18:09 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-13 12:18:09 -0800 |
commit | 83cd4823d6bf8e0c8e7d82afbfac824744491762 (patch) | |
tree | d53c4bc47891c6c32d5eb1a1f911aad438b3893a /src/theory | |
parent | 6eb492f636d2c950a6064389dfba297baff8e08e (diff) |
Rewrite simple regexp pattern to str.contains (#2827)
Diffstat (limited to 'src/theory')
-rw-r--r-- | src/theory/strings/theory_strings_rewriter.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/theory/strings/theory_strings_rewriter.cpp b/src/theory/strings/theory_strings_rewriter.cpp index eff68ebe6..79667b9aa 100644 --- a/src/theory/strings/theory_strings_rewriter.cpp +++ b/src/theory/strings/theory_strings_rewriter.cpp @@ -1244,8 +1244,12 @@ Node TheoryStringsRewriter::rewriteMembership(TNode node) { bool allSigma = true; bool allSigmaStrict = true; unsigned allSigmaMinSize = 0; - for (const Node& rc : r) + Node constStr; + size_t constIdx = 0; + size_t nchildren = r.getNumChildren(); + for (size_t i = 0; i < nchildren; i++) { + Node rc = r[i]; Assert(rc.getKind() != kind::REGEXP_EMPTY); if (rc.getKind() == kind::REGEXP_SIGMA) { @@ -1255,6 +1259,19 @@ Node TheoryStringsRewriter::rewriteMembership(TNode node) { { allSigmaStrict = false; } + else if (rc.getKind() == STRING_TO_REGEXP) + { + if (constStr.isNull()) + { + constStr = rc[0]; + constIdx = i; + } + else + { + allSigma = false; + break; + } + } else { allSigma = false; @@ -1263,10 +1280,21 @@ Node TheoryStringsRewriter::rewriteMembership(TNode node) { } if (allSigma) { - Node num = nm->mkConst(Rational(allSigmaMinSize)); - Node lenx = nm->mkNode(STRING_LENGTH, x); - retNode = nm->mkNode(allSigmaStrict ? EQUAL : GEQ, lenx, num); - return returnRewrite(node, retNode, "re-concat-pure-allchar"); + if (constStr.isNull()) + { + // x in re.++(_*, _, _) ---> str.len(x) >= 2 + Node num = nm->mkConst(Rational(allSigmaMinSize)); + Node lenx = nm->mkNode(STRING_LENGTH, x); + retNode = nm->mkNode(allSigmaStrict ? EQUAL : GEQ, lenx, num); + return returnRewrite(node, retNode, "re-concat-pure-allchar"); + } + else if (allSigmaMinSize == 0 && nchildren >= 3 && constIdx != 0 + && constIdx != nchildren - 1) + { + // x in re.++(_*, "abc", _*) ---> str.contains(x, "abc") + retNode = nm->mkNode(STRING_STRCTN, x, constStr); + return returnRewrite(node, retNode, "re-concat-to-contains"); + } } }else if( r.getKind()==kind::REGEXP_INTER || r.getKind()==kind::REGEXP_UNION ){ std::vector< Node > mvec; |