// (= (str.++ "A" x y) (str.++ x "AB" z)) --->
// (and (= (str.++ "A" x) (str.++ x "A")) (= y (str.++ "B" z)))
std::vector<Node> rpfxv1;
- if (StringsEntail::stripSymbolicLength(pfxv1, rpfxv1, 1, lenPfx0))
+ if (StringsEntail::stripSymbolicLength(
+ pfxv1, rpfxv1, 1, lenPfx0, true))
{
std::vector<Node> sfxv0(v0.begin() + i, v0.end());
pfxv1.insert(pfxv1.end(), v1.begin() + j, v1.end());
// (= (str.++ x "AB" z) (str.++ "A" x y)) --->
// (and (= (str.++ x "A") (str.++ "A" x)) (= (str.++ "B" z) y))
std::vector<Node> rpfxv0;
- if (StringsEntail::stripSymbolicLength(pfxv0, rpfxv0, 1, lenPfx1))
+ if (StringsEntail::stripSymbolicLength(
+ pfxv0, rpfxv0, 1, lenPfx1, true))
{
pfxv0.insert(pfxv0.end(), v0.begin() + i, v0.end());
std::vector<Node> sfxv1(v1.begin() + j, v1.end());
bool StringsEntail::stripSymbolicLength(std::vector<Node>& n1,
std::vector<Node>& nr,
int dir,
- Node& curr)
+ Node& curr,
+ bool strict)
{
Assert(dir == 1 || dir == -1);
Assert(nr.empty());
NodeManager* nm = NodeManager::currentNM();
Node zero = nm->mkConst(CVC4::Rational(0));
bool ret = false;
- bool success;
+ bool success = true;
unsigned sindex = 0;
- do
+ while (success && curr != zero && sindex < n1.size())
{
Assert(!curr.isNull());
success = false;
- if (curr != zero && sindex < n1.size())
+ unsigned sindex_use = dir == 1 ? sindex : ((n1.size() - 1) - sindex);
+ if (n1[sindex_use].isConst())
{
- unsigned sindex_use = dir == 1 ? sindex : ((n1.size() - 1) - sindex);
- if (n1[sindex_use].isConst())
+ // could strip part of a constant
+ Node lowerBound = ArithEntail::getConstantBound(Rewriter::rewrite(curr));
+ if (!lowerBound.isNull())
{
- // could strip part of a constant
- Node lowerBound =
- ArithEntail::getConstantBound(Rewriter::rewrite(curr));
- if (!lowerBound.isNull())
+ Assert(lowerBound.isConst());
+ Rational lbr = lowerBound.getConst<Rational>();
+ if (lbr.sgn() > 0)
{
- Assert(lowerBound.isConst());
- Rational lbr = lowerBound.getConst<Rational>();
- if (lbr.sgn() > 0)
+ Assert(ArithEntail::check(curr, true));
+ Node s = n1[sindex_use];
+ size_t slen = Word::getLength(s);
+ Node ncl = nm->mkConst(CVC4::Rational(slen));
+ Node next_s = nm->mkNode(MINUS, lowerBound, ncl);
+ next_s = Rewriter::rewrite(next_s);
+ Assert(next_s.isConst());
+ // we can remove the entire constant
+ if (next_s.getConst<Rational>().sgn() >= 0)
{
- Assert(ArithEntail::check(curr, true));
- Node s = n1[sindex_use];
- size_t slen = Word::getLength(s);
- Node ncl = nm->mkConst(CVC4::Rational(slen));
- Node next_s = nm->mkNode(MINUS, lowerBound, ncl);
- next_s = Rewriter::rewrite(next_s);
- Assert(next_s.isConst());
- // we can remove the entire constant
- if (next_s.getConst<Rational>().sgn() >= 0)
+ curr = Rewriter::rewrite(nm->mkNode(MINUS, curr, ncl));
+ success = true;
+ sindex++;
+ }
+ else
+ {
+ // we can remove part of the constant
+ // lower bound minus the length of a concrete string is negative,
+ // hence lowerBound cannot be larger than long max
+ Assert(lbr < Rational(String::maxSize()));
+ curr = Rewriter::rewrite(nm->mkNode(MINUS, curr, lowerBound));
+ uint32_t lbsize = lbr.getNumerator().toUnsignedInt();
+ Assert(lbsize < slen);
+ if (dir == 1)
{
- curr = Rewriter::rewrite(nm->mkNode(MINUS, curr, ncl));
- success = true;
- sindex++;
+ // strip partially from the front
+ nr.push_back(Word::prefix(s, lbsize));
+ n1[sindex_use] = Word::suffix(s, slen - lbsize);
}
else
{
- // we can remove part of the constant
- // lower bound minus the length of a concrete string is negative,
- // hence lowerBound cannot be larger than long max
- Assert(lbr < Rational(String::maxSize()));
- curr = Rewriter::rewrite(nm->mkNode(MINUS, curr, lowerBound));
- uint32_t lbsize = lbr.getNumerator().toUnsignedInt();
- Assert(lbsize < slen);
- if (dir == 1)
- {
- // strip partially from the front
- nr.push_back(Word::prefix(s, lbsize));
- n1[sindex_use] = Word::suffix(s, slen - lbsize);
- }
- else
- {
- // strip partially from the back
- nr.push_back(Word::suffix(s, lbsize));
- n1[sindex_use] = Word::prefix(s, slen - lbsize);
- }
- ret = true;
+ // strip partially from the back
+ nr.push_back(Word::suffix(s, lbsize));
+ n1[sindex_use] = Word::prefix(s, slen - lbsize);
}
- Assert(ArithEntail::check(curr));
- }
- else
- {
- // we cannot remove the constant
+ ret = true;
}
+ Assert(ArithEntail::check(curr));
}
- }
- else
- {
- Node next_s = NodeManager::currentNM()->mkNode(
- MINUS,
- curr,
- NodeManager::currentNM()->mkNode(STRING_LENGTH, n1[sindex_use]));
- next_s = Rewriter::rewrite(next_s);
- if (ArithEntail::check(next_s))
+ else
{
- success = true;
- curr = next_s;
- sindex++;
+ // we cannot remove the constant
}
}
}
- } while (success);
- if (sindex > 0)
+ else
+ {
+ Node next_s = NodeManager::currentNM()->mkNode(
+ MINUS,
+ curr,
+ NodeManager::currentNM()->mkNode(STRING_LENGTH, n1[sindex_use]));
+ next_s = Rewriter::rewrite(next_s);
+ if (ArithEntail::check(next_s))
+ {
+ success = true;
+ curr = next_s;
+ sindex++;
+ }
+ }
+ }
+ if (sindex > 0 && (!strict || curr == zero))
{
if (dir == 1)
{
--- /dev/null
+; COMMAND-LINE: --strings-exp --incremental
+(set-logic QF_S)
+(declare-const Str0 String)
+(declare-const Str1 String)
+(declare-const Str2 String)
+(declare-const Str3 String)
+(declare-const Str4 String)
+(declare-const Str5 String)
+(declare-const Str6 String)
+(declare-const Str7 String)
+(declare-const Str8 String)
+(declare-const Str9 String)
+(declare-const Str10 String)
+(declare-const Str11 String)
+(declare-const Str12 String)
+(declare-const Str13 String)
+(declare-const Str14 String)
+(declare-const Str15 String)
+(declare-const Str16 String)
+(declare-const Str17 String)
+(declare-const Str18 String)
+(declare-const Str19 String)
+(assert (str.in_re Str19(re.opt (str.to_re Str10))))
+(assert (str.in_re Str9(re.opt (str.to_re Str18))))
+(assert (str.in_re (str.replace Str12 "jkngjj" Str14)(re.opt (str.to_re (str.++ Str13 "spifluyxzmbznnejkmfajdisgnyfeogvtwxuclzmrlmjmmwhly" Str5 Str19 "rsjusudbyjoyfpwbpasemhhxoayzouhoaekszsvhbsmnysbcih")))))
+(assert (str.in_re Str13(re.opt (str.to_re Str3))))
+(push 1)
+(assert (str.in_re (str.++ Str12 (str.++ Str5 Str16 Str13) (str.++ Str5 "tqckdn" "hvhftx" (str.replace Str12 "jkngjj" Str14)) "trcuij" "ovnscketrkugxyqewkvuvondgahkfzwczexnyiziwhyqlomqie")(re.opt (str.to_re Str8))))
+(push 1)
+(assert (str.in_re (str.++ Str13 (str.++ Str5 Str16 Str13))(re.++ (str.to_re (str.++ Str5 Str16 Str13)) (str.to_re "cjyfqapanogtdznjbtqlfrmmfauwjdpvnhfpfhzsxaarlfvlvs" ))))
+(set-info :status sat)
+(check-sat)