Trace("strings-rewrite-debug")
<< "Strings::rewriteAndOrRegExp start " << node << std::endl;
std::vector<Node> node_vec;
+ std::vector<Node> polRegExp[2];
for (const Node& ni : node)
{
if (ni.getKind() == nk)
else if (std::find(node_vec.begin(), node_vec.end(), ni) == node_vec.end())
{
node_vec.push_back(ni);
+ uint32_t pindex = ni.getKind() == REGEXP_COMPLEMENT ? 1 : 0;
+ Node nia = pindex == 1 ? ni[0] : ni;
+ polRegExp[pindex].push_back(nia);
}
}
NodeManager* nm = NodeManager::currentNM();
- std::vector<Node> nvec;
+ std::vector<Node> emptyVec;
+ // use inclusion tests
+ for (const Node& negMem : polRegExp[1])
+ {
+ for (const Node& posMem : polRegExp[0])
+ {
+ Node m1 = nk == REGEXP_INTER ? negMem : posMem;
+ Node m2 = nk == REGEXP_INTER ? posMem : negMem;
+ // inclusion test for conflicting case m1 contains m2
+ // (re.inter (re.comp R1) R2) --> re.none where R1 includes R2
+ // (re.union R1 (re.comp R2)) --> (re.* re.allchar) where R1 includes R2
+ if (RegExpEntail::regExpIncludes(m1, m2))
+ {
+ Node retNode;
+ if (nk == REGEXP_INTER)
+ {
+ retNode = nm->mkNode(kind::REGEXP_EMPTY, emptyVec);
+ }
+ else
+ {
+ retNode = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA, emptyVec));
+ }
+ return returnRewrite(node, retNode, Rewrite::RE_ANDOR_INC_CONFLICT);
+ }
+ }
+ }
Node retNode;
if (node_vec.empty())
{
if (nk == REGEXP_INTER)
{
- retNode = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA, nvec));
+ retNode = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA, emptyVec));
}
else
{
- retNode = nm->mkNode(kind::REGEXP_EMPTY, nvec);
+ retNode = nm->mkNode(kind::REGEXP_EMPTY, emptyVec);
}
}
else
<< node << " to " << retNode << std::endl;
return RewriteResponse(REWRITE_AGAIN_FULL, retNode);
}
+ Trace("strings-rewrite-nf") << "No rewrites for : " << node << std::endl;
return RewriteResponse(REWRITE_DONE, retNode);
}
}
}
}
- Trace("strings-rewrite-nf") << "No rewrites for : " << node << std::endl;
return node;
}
}
}
- Trace("strings-rewrite-nf") << "No rewrites for : " << node << std::endl;
return node;
}
}
}
- Trace("strings-rewrite-nf") << "No rewrites for : " << node << std::endl;
return node;
}
// contains( t, s ) =>
// contains( replace( t, s, r ), r ) ----> true
- Trace("strings-rewrite-nf") << "No rewrites for : " << node << std::endl;
return node;
}
return rri;
}
- Trace("strings-rewrite-nf") << "No rewrites for : " << node << std::endl;
return node;
}