return returnRewrite(node, ret, "ss-non-zero-len-entails-oob");
}
+ // (str.substr s x y) --> "" if x >= 0 |= 0 >= str.len(s)
+ Node geq_zero_start =
+ Rewriter::rewrite(nm->mkNode(kind::GEQ, node[1], zero));
+ if (checkEntailArithWithAssumption(geq_zero_start, zero, tot_len, false))
+ {
+ Node ret = nm->mkConst(String(""));
+ return returnRewrite(node, ret, "ss-geq-zero-start-entails-emp-s");
+ }
+
// (str.substr s x x) ---> "" if (str.len s) <= 1
if (node[1] == node[2] && checkEntailLengthOne(node[0]))
{
{
candVars.insert(curr);
}
+ else if (curr.getKind() == kind::STRING_LENGTH)
+ {
+ candVars.insert(curr);
+ }
}
// Check if any of the candidate variables are in n
toVisit.push_back(currChild);
}
- if (curr.isVar() && Theory::theoryOf(curr) == THEORY_ARITH
- && candVars.find(curr) != candVars.end())
+ if (candVars.find(curr) != candVars.end())
{
v = curr;
break;
y = assumption[0][0];
}
- Node s = nm->mkBoundVar("s", nm->stringType());
+ Node s = nm->mkBoundVar("slackVal", nm->stringType());
Node slen = nm->mkNode(kind::STRING_LENGTH, s);
assumption = Rewriter::rewrite(
nm->mkNode(kind::EQUAL, x, nm->mkNode(kind::PLUS, y, slen)));
Node a = d_nm->mkConst(::CVC4::String("A"));
Node b = d_nm->mkConst(::CVC4::String("B"));
Node abcd = d_nm->mkConst(::CVC4::String("ABCD"));
+ Node negone = d_nm->mkConst(Rational(-1));
Node zero = d_nm->mkConst(Rational(0));
Node one = d_nm->mkConst(Rational(1));
Node two = d_nm->mkConst(Rational(2));
Node substr_itos = d_nm->mkNode(
kind::STRING_SUBSTR, d_nm->mkNode(kind::STRING_ITOS, x), x, x);
sameNormalForm(substr_itos, empty);
+
+ // (str.substr s (* (- 1) (str.len s)) 1) ---> empty
+ Node substr = d_nm->mkNode(
+ kind::STRING_SUBSTR,
+ s,
+ d_nm->mkNode(kind::MULT, negone, d_nm->mkNode(kind::STRING_LENGTH, s)),
+ one);
+ sameNormalForm(substr, empty);
}
void testRewriteConcat()