case Rewrite::SUF_PREFIX_ELIM: return "SUF_PREFIX_ELIM";
case Rewrite::STR_LT_ELIM: return "STR_LT_ELIM";
case Rewrite::RE_RANGE_SINGLE: return "RE_RANGE_SINGLE";
+ case Rewrite::RE_RANGE_EMPTY: return "RE_RANGE_EMPTY";
case Rewrite::RE_OPT_ELIM: return "RE_OPT_ELIM";
case Rewrite::RE_PLUS_ELIM: return "RE_PLUS_ELIM";
case Rewrite::RE_DIFF_ELIM: return "RE_DIFF_ELIM";
SUF_PREFIX_ELIM,
STR_LT_ELIM,
RE_RANGE_SINGLE,
+ RE_RANGE_EMPTY,
RE_OPT_ELIM,
RE_PLUS_ELIM,
RE_DIFF_ELIM,
Node SequencesRewriter::rewriteRangeRegExp(TNode node)
{
Assert(node.getKind() == REGEXP_RANGE);
+ NodeManager* nm = NodeManager::currentNM();
if (node[0] == node[1])
{
- NodeManager* nm = NodeManager::currentNM();
Node retNode = nm->mkNode(STRING_TO_REGEXP, node[0]);
// re.range( "A", "A" ) ---> str.to_re( "A" )
return returnRewrite(node, retNode, Rewrite::RE_RANGE_SINGLE);
}
+
+ bool appliedCh = true;
+ unsigned ch[2];
+ for (size_t i = 0; i < 2; ++i)
+ {
+ if (node[i].isConst() || node[i].getConst<String>().size() != 1)
+ {
+ appliedCh = false;
+ break;
+ }
+ ch[i] = node[i].getConst<String>().front();
+ }
+ if (appliedCh && ch[0] > ch[1])
+ {
+ // re.range( "B", "A" ) ---> re.none
+ Node retNode = nm->mkNode(REGEXP_EMPTY, {});
+ return returnRewrite(node, retNode, Rewrite::RE_RANGE_EMPTY);
+ }
return node;
}
{
// (and (>= (str.indexof x y n) (- 1)) (<= (str.indexof x y n) (str.len
// x)))
- Node l = utils::mkNLength(t[0]);
+ Node l = nm->mkNode(STRING_LENGTH, t[0]);
lemma = nm->mkNode(AND,
nm->mkNode(GEQ, t, nm->mkConst(Rational(-1))),
nm->mkNode(LEQ, t, l));
{
d_hasStrCode = true;
}
+ else if (k == REGEXP_RANGE)
+ {
+ for (const Node& nc : n)
+ {
+ if (!nc.isConst())
+ {
+ throw LogicException(
+ "expecting a constant string term in regexp range");
+ }
+ if (nc.getConst<String>().size() != 1)
+ {
+ throw LogicException(
+ "expecting a single constant string term in regexp range");
+ }
+ }
+ }
registerTerm(n, 0);
TypeNode tn = n.getType();
if (tn.isRegExp() && n.isVar())
nm->integerType(), t, SkolemCache::SK_PURIFY, "iok");
Node negone = nm->mkConst(Rational(-1));
- Node krange = nm->mkNode(GEQ, skk, negone);
- // assert: indexof( x, y, n ) >= -1
- asserts.push_back(krange);
- krange = nm->mkNode(GEQ, nm->mkNode(STRING_LENGTH, x), skk);
- // assert: len( x ) >= indexof( x, y, z )
- asserts.push_back(krange);
// substr( x, n, len( x ) - n )
Node st = nm->mkNode(STRING_SUBSTR,
if (check)
{
TNode::iterator it = n.begin();
- unsigned ch[2];
-
for (int i = 0; i < 2; ++i)
{
TypeNode t = (*it).getType(check);
throw TypeCheckingExceptionPrivate(
n, "expecting a string term in regexp range");
}
- if (!(*it).isConst())
- {
- throw TypeCheckingExceptionPrivate(
- n, "expecting a constant string term in regexp range");
- }
- if ((*it).getConst<String>().size() != 1)
- {
- throw TypeCheckingExceptionPrivate(
- n, "expecting a single constant string term in regexp range");
- }
- unsigned ci = (*it).getConst<String>().front();
- ch[i] = ci;
++it;
}
- if (ch[0] > ch[1])
- {
- throw TypeCheckingExceptionPrivate(
- n,
- "expecting the first constant is less or equal to the second one in "
- "regexp range");
- }
}
return nodeManager->regExpType();
}