summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Noetzli <andres.noetzli@gmail.com>2019-01-23 20:19:43 -0800
committerAndres Noetzli <andres.noetzli@gmail.com>2019-01-23 20:19:43 -0800
commit83d63a544d20fc73e399a9a3e29fef8a908c59d9 (patch)
treea037819889a248c4534c277a2bd8547e23d3bea5
parent8322344ae39fb9891416f0271e2772c357c8061b (diff)
parent77a9cac1975f30153c16493fba673b50e0331509 (diff)
Merge branch 'strongerContainsRew' into cav2019strings
-rw-r--r--src/theory/strings/theory_strings_rewriter.cpp42
1 files changed, 36 insertions, 6 deletions
diff --git a/src/theory/strings/theory_strings_rewriter.cpp b/src/theory/strings/theory_strings_rewriter.cpp
index 95c9df8ff..c4a6905c4 100644
--- a/src/theory/strings/theory_strings_rewriter.cpp
+++ b/src/theory/strings/theory_strings_rewriter.cpp
@@ -2286,18 +2286,48 @@ Node TheoryStringsRewriter::rewriteIndexof( Node node ) {
// past the first position in node[0] that contains node[1], we can drop
std::vector<Node> nb;
std::vector<Node> ne;
- int cc = componentContains(children0, children1, nb, ne, true, 0);
- if (cc != -1 && (!nb.empty() || !ne.empty()))
+ int cc = componentContains(children0, children1, nb, ne, true, 1);
+ if (cc != -1 && !ne.empty())
{
// For example:
// str.indexof(str.++(x,y,z),y,0) ---> str.indexof(str.++(x,y),y,0)
Node nn = mkConcat(kind::STRING_CONCAT, children0);
- Node ret = nm->mkNode(
- PLUS,
- nm->mkNode(STRING_LENGTH, mkConcat(STRING_CONCAT, nb)),
- nm->mkNode(kind::STRING_STRIDOF, nn, node[1], node[2]));
+ Node ret = nm->mkNode(kind::STRING_STRIDOF, nn, node[1], node[2]);
return returnRewrite(node, ret, "idof-def-ctn");
}
+
+ if (node[1].isConst())
+ {
+ CVC4::String t = node[1].getConst<String>();
+ if (t.size() == 1)
+ {
+ size_t i = 0;
+ std::vector<Node> children0;
+ getConcat(node[0], children0);
+ for (size_t size = children0.size(); i < size; i++)
+ {
+ Node ectn = checkEntailContains(children0[i], node[1]);
+ if (ectn.isNull() || ectn.getConst<bool>())
+ {
+ break;
+ }
+ }
+ Assert(i < children0.size());
+
+ if (i > 0)
+ {
+ std::vector<Node> pfxv(children0.begin(), children0.begin() + i);
+ children0.erase(children0.begin(), children0.begin() + i);
+ Node pfx = mkConcat(STRING_CONCAT, pfxv);
+ Node nn = mkConcat(STRING_CONCAT, children0);
+ Node ret = nm->mkNode(
+ PLUS,
+ nm->mkNode(STRING_LENGTH, pfx),
+ nm->mkNode(kind::STRING_STRIDOF, nn, node[1], node[2]));
+ return returnRewrite(node, ret, "idof-def-ctn");
+ }
+ }
+ }
}
// strip symbolic length
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback