}
}
Node RegExpOpr::intersectInternal2( Node r1, Node r2, std::map< PairNodes, Node > cache, bool &spflag, unsigned cnt ) {
- Trace("regexp-intersect") << "Starting INTERSECT:\n "<< mkString(r1) << ",\n " << mkString(r2) << std::endl;
+ //(checkConstRegExp(r1) && checkConstRegExp(r2))
+ Trace("regexp-intersect") << "Starting INTERSECT(" << cnt << "):\n "<< mkString(r1) << ",\n " << mkString(r2) << std::endl;
//if(Trace.isOn("regexp-debug")) {
// Trace("regexp-debug") << "... with cache:\n";
// for(std::map< PairNodes, Node >::const_iterator itr=cache.begin();
std::pair < Node, Node > p(r1, r2);
std::map < std::pair< Node, Node >, Node >::const_iterator itr = d_inter_cache.find(p);
Node rNode;
- if(itr != d_inter_cache.end()) {
- rNode = itr->second;
- } else {
+// if(itr != d_inter_cache.end()) {
+// rNode = itr->second;
+// } else {
if(r1 == d_emptyRegexp || r2 == d_emptyRegexp) {
rNode = d_emptyRegexp;
} else if(r1 == d_emptySingleton || r2 == d_emptySingleton) {
if(itrcache != cache.end()) {
rNode = itrcache->second;
} else {
- if(checkConstRegExp(r1) && checkConstRegExp(r2)) {
- std::vector< unsigned > cset;
- std::set< unsigned > cset1, cset2;
- std::set< Node > vset1, vset2;
- firstChars(r1, cset1, vset1);
- firstChars(r2, cset2, vset2);
- std::set_intersection(cset1.begin(), cset1.end(), cset2.begin(), cset1.end(),
- std::inserter(cset, cset.begin()));
- std::vector< Node > vec_nodes;
- Node delta_exp;
- int flag = delta(r1, delta_exp);
- int flag2 = delta(r2, delta_exp);
- if(flag != 2 && flag2 != 2) {
- if(flag == 1 && flag2 == 1) {
- vec_nodes.push_back(d_emptySingleton);
- } else {
- //TODO
- spflag = true;
- }
- }
- if(Trace.isOn("regexp-debug")) {
- Trace("regexp-debug") << "Try CSET( " << cset.size() << " ) = ";
- for(std::vector<unsigned>::const_iterator itr = cset.begin();
- itr != cset.end(); itr++) {
- CVC4::String c( CVC4::String::convertUnsignedIntToChar(*itr) );
- Trace("regexp-debug") << c << ", ";
- }
- Trace("regexp-debug") << std::endl;
+ std::vector< unsigned > cset;
+ std::set< unsigned > cset1, cset2;
+ std::set< Node > vset1, vset2;
+ firstChars(r1, cset1, vset1);
+ firstChars(r2, cset2, vset2);
+ std::set_intersection(cset1.begin(), cset1.end(), cset2.begin(), cset1.end(),
+ std::inserter(cset, cset.begin()));
+ std::vector< Node > vec_nodes;
+ Node delta_exp;
+ int flag = delta(r1, delta_exp);
+ int flag2 = delta(r2, delta_exp);
+ if(flag != 2 && flag2 != 2) {
+ if(flag == 1 && flag2 == 1) {
+ vec_nodes.push_back(d_emptySingleton);
+ } else {
+ //TODO
+ spflag = true;
}
+ }
+ if(Trace.isOn("regexp-debug")) {
+ Trace("regexp-debug") << "Try CSET( " << cset.size() << " ) = ";
for(std::vector<unsigned>::const_iterator itr = cset.begin();
itr != cset.end(); itr++) {
CVC4::String c( CVC4::String::convertUnsignedIntToChar(*itr) );
- Node r1l = derivativeSingle(r1, c);
- Node r2l = derivativeSingle(r2, c);
- std::map< PairNodes, Node > cache2(cache);
- PairNodes p(r1, r2);
- cache2[ p ] = NodeManager::currentNM()->mkNode(kind::REGEXP_RV, NodeManager::currentNM()->mkConst(CVC4::Rational(cnt)));
- Node rt = intersectInternal2(r1l, r2l, cache2, spflag, cnt+1);
- if(spflag) {
- //TODO:
- return Node::null();
- }
- rt = Rewriter::rewrite( NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT,
- NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(c)), rt) );
- vec_nodes.push_back(rt);
+ Trace("regexp-debug") << c << ", ";
}
- rNode = vec_nodes.size()==0 ? d_emptyRegexp : vec_nodes.size()==1 ? vec_nodes[0] :
- NodeManager::currentNM()->mkNode(kind::REGEXP_UNION, vec_nodes);
- rNode = Rewriter::rewrite( rNode );
- rNode = convert1(cnt, rNode);
- rNode = Rewriter::rewrite( rNode );
- } else {
- //TODO: non-empty var set
- spflag = true;
+ Trace("regexp-debug") << std::endl;
}
+ for(std::vector<unsigned>::const_iterator itr = cset.begin();
+ itr != cset.end(); itr++) {
+ CVC4::String c( CVC4::String::convertUnsignedIntToChar(*itr) );
+ Node r1l = derivativeSingle(r1, c);
+ Node r2l = derivativeSingle(r2, c);
+ std::map< PairNodes, Node > cache2(cache);
+ PairNodes p(r1, r2);
+ cache2[ p ] = NodeManager::currentNM()->mkNode(kind::REGEXP_RV, NodeManager::currentNM()->mkConst(CVC4::Rational(cnt)));
+ Node rt = intersectInternal2(r1l, r2l, cache2, spflag, cnt+1);
+ //if(spflag) {
+ //return Node::null();
+ //}
+ rt = Rewriter::rewrite( NodeManager::currentNM()->mkNode(kind::REGEXP_CONCAT,
+ NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP, NodeManager::currentNM()->mkConst(c)), rt) );
+ vec_nodes.push_back(rt);
+ }
+ rNode = vec_nodes.size()==0 ? d_emptyRegexp : vec_nodes.size()==1 ? vec_nodes[0] :
+ NodeManager::currentNM()->mkNode(kind::REGEXP_UNION, vec_nodes);
+ rNode = Rewriter::rewrite( rNode );
+ rNode = convert1(cnt, rNode);
+ rNode = Rewriter::rewrite( rNode );
}
}
- d_inter_cache[p] = rNode;
- }
- Trace("regexp-intersect") << "End of INTERSECT( " << mkString(r1) << ", " << mkString(r2) << " ) = " << mkString(rNode) << std::endl;
+// d_inter_cache[p] = rNode;
+// }
+ Trace("regexp-intersect") << "End(" << cnt << ") of INTERSECT( " << mkString(r1) << ", " << mkString(r2) << " ) = " << mkString(rNode) << std::endl;
return rNode;
}
if(tmpNode.getKind() == kind::REGEXP_UNION) {
for(unsigned int j=0; j<tmpNode.getNumChildren(); ++j) {
if(std::find(node_vec.begin(), node_vec.end(), tmpNode[j]) == node_vec.end()) {
- node_vec.push_back( tmpNode[j] );
+ if(std::find(node_vec.begin(), node_vec.end(), tmpNode[j]) == node_vec.end()) {
+ node_vec.push_back( tmpNode[j] );
+ }
}
}
} else if(tmpNode.getKind() == kind::REGEXP_EMPTY) {
retNode = node[i];
break;
} else {
- node_vec.push_back( node[i] );
+ if(std::find(node_vec.begin(), node_vec.end(), node[i]) == node_vec.end()) {
+ node_vec.push_back( node[i] );
+ }
}
}
if(!allflag) {
} else if(node[i].getKind() == kind::REGEXP_STAR && node[i][0].getKind() == kind::REGEXP_SIGMA) {
//allNode = node[i];
} else {
- node_vec.push_back( node[i] );
+ if(std::find(node_vec.begin(), node_vec.end(), node[i]) == node_vec.end()) {
+ node_vec.push_back( node[i] );
+ }
}
}
if(!emptyflag) {
return RewriteResponse(orig==retNode ? REWRITE_DONE : REWRITE_AGAIN_FULL, retNode);
}
+bool TheoryStringsRewriter::hasEpsilonNode(TNode node) {
+ for(unsigned int i=0; i<node.getNumChildren(); i++) {
+ if(node[i].getKind() == kind::STRING_TO_REGEXP && node[i][0].getKind() == kind::CONST_STRING && node[i][0].getConst<String>().isEmptyString()) {
+ return true;
+ }
+ }
+ return false;
+}
+
RewriteResponse TheoryStringsRewriter::preRewrite(TNode node) {
Node retNode = node;
Node orig = retNode;
retNode = node[0];
} else if(node[0].getKind() == kind::STRING_TO_REGEXP && node[0][0].getKind() == kind::CONST_STRING && node[0][0].getConst<String>().isEmptyString()) {
retNode = node[0];
+ } else if(node[0].getKind() == kind::REGEXP_EMPTY) {
+ retNode = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,
+ NodeManager::currentNM()->mkConst( ::CVC4::String("") ) );
+ } else if(node[0].getKind() == kind::REGEXP_UNION) {
+ Node tmpNode = prerewriteOrRegExp(node[0]);
+ if(tmpNode.getKind() == kind::REGEXP_UNION) {
+ if(hasEpsilonNode(node[0])) {
+ std::vector< Node > node_vec;
+ for(unsigned int i=0; i<node[0].getNumChildren(); i++) {
+ if(node[0][i].getKind() == kind::STRING_TO_REGEXP && node[0][i][0].getKind() == kind::CONST_STRING && node[0][i][0].getConst<String>().isEmptyString()) {
+ //return true;
+ } else {
+ node_vec.push_back(node[0][i]);
+ }
+ }
+ retNode = node_vec.size()==1 ? node_vec[0] : NodeManager::currentNM()->mkNode(kind::REGEXP_UNION, node_vec);
+ retNode = NodeManager::currentNM()->mkNode(kind::REGEXP_STAR, retNode);
+ }
+ } else if(tmpNode.getKind() == kind::STRING_TO_REGEXP && tmpNode[0].getKind() == kind::CONST_STRING && tmpNode[0].getConst<String>().isEmptyString()) {
+ retNode = tmpNode;
+ } else {
+ retNode = NodeManager::currentNM()->mkNode(kind::REGEXP_STAR, tmpNode);
+ }
}
} else if(node.getKind() == kind::REGEXP_PLUS) {
retNode = NodeManager::currentNM()->mkNode( kind::REGEXP_CONCAT, node[0],