}
}
- if (s.getKind() == SEQ_UNIT && i.isConst() && i.getConst<Rational>().isZero())
+ std::vector<Node> prefix, suffix;
+ utils::getConcat(s, suffix);
+ if ((i.isConst() && i.getConst<Rational>().isZero())
+ || d_stringsEntail.stripSymbolicLength(suffix, prefix, 1, i, true))
{
- Node ret = s[0];
- return returnRewrite(node, ret, Rewrite::SEQ_NTH_UNIT);
+ if (suffix.size() > 0 && suffix[0].getKind() == SEQ_UNIT)
+ {
+ // (seq.nth (seq.++ prefix (seq.unit x) suffix) n) ---> x
+ // if len(prefix) = n
+ Node ret = suffix[0][0];
+ return returnRewrite(node, ret, Rewrite::SEQ_NTH_EVAL_SYM);
+ }
}
return node;
}
}
+ NodeManager* nm = NodeManager::currentNM();
+ Node zero = nm->mkConstInt(0);
+ Node sLen = nm->mkNode(STRING_LENGTH, s);
+ if (d_arithEntail.check(zero, i, true) || d_arithEntail.check(i, sLen))
+ {
+ // (seq.update s i x) ---> s if x < 0 or x >= len(s)
+ Node ret = s;
+ return returnRewrite(node, ret, Rewrite::UPD_OOB);
+ }
+
+ std::vector<Node> prefix, suffix;
+ utils::getConcat(s, suffix);
+ if ((i.isConst() && i.getConst<Rational>().isZero())
+ || d_stringsEntail.stripSymbolicLength(suffix, prefix, 1, i, true))
+ {
+ Node updateLen = nm->mkNode(STRING_LENGTH, x);
+ std::vector<Node> replaced;
+ if (d_stringsEntail.stripSymbolicLength(
+ suffix, replaced, 1, updateLen, true))
+ {
+ // (seq.update (seq.++ p r s) i x) ---> (seq.++ p x s)
+ // if len(p) = i and len(r) = len(x)
+ prefix.emplace_back(x);
+ prefix.insert(prefix.end(), suffix.begin(), suffix.end());
+ Node ret = utils::mkConcat(prefix, node.getType());
+ return returnRewrite(node, ret, Rewrite::UPD_EVAL_SYM);
+ }
+ }
+
if (s.getKind() == STRING_REV && d_stringsEntail.checkLengthOne(x))
{
// str.update(str.rev(s), n, t) --->
// str.rev(str.update(s, len(s) - (n + 1), t))
- NodeManager* nm = NodeManager::currentNM();
Node idx = nm->mkNode(MINUS,
nm->mkNode(STRING_LENGTH, s),
nm->mkNode(PLUS, i, nm->mkConstInt(Rational(1))));
false));
}
+TEST_F(TestTheoryWhiteSequencesRewriter, rewrite_nth)
+{
+ TypeNode intType = d_nodeManager->integerType();
+
+ Node x = d_nodeManager->mkVar("x", intType);
+ Node y = d_nodeManager->mkVar("y", intType);
+ Node z = d_nodeManager->mkVar("z", intType);
+ Node w = d_nodeManager->mkVar("w", intType);
+ Node v = d_nodeManager->mkVar("v", intType);
+
+ Node zero = d_nodeManager->mkConstInt(0);
+ Node one = d_nodeManager->mkConstInt(1);
+
+ Node sx = d_nodeManager->mkNode(SEQ_UNIT, x);
+ Node sy = d_nodeManager->mkNode(SEQ_UNIT, y);
+ Node sz = d_nodeManager->mkNode(SEQ_UNIT, z);
+ Node sw = d_nodeManager->mkNode(SEQ_UNIT, w);
+ Node sv = d_nodeManager->mkNode(SEQ_UNIT, v);
+ Node xyz = d_nodeManager->mkNode(STRING_CONCAT, sx, sy, sz);
+ Node wv = d_nodeManager->mkNode(STRING_CONCAT, sw, sv);
+
+ {
+ // Same normal form for:
+ //
+ // (seq.nth (seq.unit x) 0)
+ //
+ // x
+ Node n = d_nodeManager->mkNode(SEQ_NTH, sx, zero);
+ sameNormalForm(n, x);
+ }
+
+ {
+ // Same normal form for:
+ //
+ // (seq.nth (seq.++ (seq.unit x) (seq.unit y) (seq.unit z)) 0)
+ //
+ // x
+ Node n = d_nodeManager->mkNode(SEQ_NTH, xyz, zero);
+ sameNormalForm(n, x);
+ }
+
+ {
+ // Same normal form for:
+ //
+ // (seq.nth (seq.++ (seq.unit x) (seq.unit y) (seq.unit z)) 0)
+ //
+ // x
+ Node n = d_nodeManager->mkNode(SEQ_NTH, xyz, one);
+ sameNormalForm(n, y);
+ }
+}
+
TEST_F(TestTheoryWhiteSequencesRewriter, rewrite_substr)
{
StringsRewriter sr(d_rewriter, nullptr);
sameNormalForm(substr, empty);
}
+TEST_F(TestTheoryWhiteSequencesRewriter, rewrite_update)
+{
+ TypeNode intType = d_nodeManager->integerType();
+
+ Node x = d_nodeManager->mkVar("x", intType);
+ Node y = d_nodeManager->mkVar("y", intType);
+ Node z = d_nodeManager->mkVar("z", intType);
+ Node w = d_nodeManager->mkVar("w", intType);
+ Node v = d_nodeManager->mkVar("v", intType);
+
+ Node negOne = d_nodeManager->mkConstInt(-1);
+ Node zero = d_nodeManager->mkConstInt(0);
+ Node one = d_nodeManager->mkConstInt(1);
+ Node three = d_nodeManager->mkConstInt(3);
+
+ Node sx = d_nodeManager->mkNode(SEQ_UNIT, x);
+ Node sy = d_nodeManager->mkNode(SEQ_UNIT, y);
+ Node sz = d_nodeManager->mkNode(SEQ_UNIT, z);
+ Node sw = d_nodeManager->mkNode(SEQ_UNIT, w);
+ Node sv = d_nodeManager->mkNode(SEQ_UNIT, v);
+ Node xyz = d_nodeManager->mkNode(STRING_CONCAT, sx, sy, sz);
+ Node wv = d_nodeManager->mkNode(STRING_CONCAT, sw, sv);
+
+ {
+ // Same normal form for:
+ //
+ // (seq.update
+ // (seq.unit x))
+ // 0
+ // (seq.unit w))
+ //
+ // (seq.unit w)
+ Node n = d_nodeManager->mkNode(STRING_UPDATE, sx, zero, sw);
+ sameNormalForm(n, sw);
+ }
+
+ {
+ // Same normal form for:
+ //
+ // (seq.update
+ // (seq.++ (seq.unit x) (seq.unit y) (seq.unit z))
+ // 0
+ // (seq.unit w))
+ //
+ // (seq.++ (seq.unit w) (seq.unit y) (seq.unit z))
+ Node n = d_nodeManager->mkNode(STRING_UPDATE, xyz, zero, sw);
+ Node wyz = d_nodeManager->mkNode(STRING_CONCAT, sw, sy, sz);
+ sameNormalForm(n, wyz);
+ }
+
+ {
+ // Same normal form for:
+ //
+ // (seq.update
+ // (seq.++ (seq.unit x) (seq.unit y) (seq.unit z))
+ // 1
+ // (seq.unit w))
+ //
+ // (seq.++ (seq.unit x) (seq.unit w) (seq.unit z))
+ Node n = d_nodeManager->mkNode(STRING_UPDATE, xyz, one, sw);
+ Node xwz = d_nodeManager->mkNode(STRING_CONCAT, sx, sw, sz);
+ sameNormalForm(n, xwz);
+ }
+
+ {
+ // Same normal form for:
+ //
+ // (seq.update
+ // (seq.++ (seq.unit x) (seq.unit y) (seq.unit z))
+ // 1
+ // (seq.++ (seq.unit w) (seq.unit v)))
+ //
+ // (seq.++ (seq.unit x) (seq.unit w) (seq.unit v))
+ Node n = d_nodeManager->mkNode(STRING_UPDATE, xyz, one, wv);
+ Node xwv = d_nodeManager->mkNode(STRING_CONCAT, sx, sw, sv);
+ sameNormalForm(n, xwv);
+ }
+
+ {
+ // Same normal form for:
+ //
+ // (seq.update
+ // (seq.++ (seq.unit x) (seq.unit y) (seq.unit z))
+ // -1
+ // (seq.++ (seq.unit w) (seq.unit v)))
+ //
+ // (seq.++ (seq.unit x) (seq.unit y) (seq.unit z))
+ Node n = d_nodeManager->mkNode(STRING_UPDATE, xyz, negOne, wv);
+ sameNormalForm(n, xyz);
+ }
+
+ {
+ // Same normal form for:
+ //
+ // (seq.update
+ // (seq.++ (seq.unit x) (seq.unit y) (seq.unit z))
+ // 3
+ // w)
+ //
+ // (seq.++ (seq.unit x) (seq.unit y) (seq.unit z))
+ Node n = d_nodeManager->mkNode(STRING_UPDATE, xyz, three, sw);
+ sameNormalForm(n, xyz);
+ }
+}
+
TEST_F(TestTheoryWhiteSequencesRewriter, rewrite_concat)
{
TypeNode intType = d_nodeManager->integerType();