bug fix
authorTianyi Liang <tianyi-liang@uiowa.edu>
Wed, 6 Nov 2013 23:18:31 +0000 (17:18 -0600)
committerTianyi Liang <tianyi-liang@uiowa.edu>
Wed, 6 Nov 2013 23:20:04 +0000 (17:20 -0600)
src/theory/strings/regexp_operation.cpp
src/theory/strings/theory_strings.cpp

index 0a7701862bb521aa7e6bb9fa3a3cfa8837cb3f00..fa686dd9f3f11eb0a086fec713e803c25c0fff40 100644 (file)
@@ -31,6 +31,7 @@ RegExpOpr::RegExpOpr() {
 }\r
 \r
 bool RegExpOpr::checkConstRegExp( Node r ) {\r
+       Trace("strings-regexp-cstre") << "RegExp-CheckConstRegExp starts with " << mkString( r ) << std::endl;\r
        bool ret = true;\r
        if( d_cstre_cache.find( r ) != d_cstre_cache.end() ) {\r
                ret = d_cstre_cache[r];\r
@@ -159,7 +160,7 @@ int RegExpOpr::delta( Node r ) {
 //null - no solution\r
 Node RegExpOpr::derivativeSingle( Node r, CVC4::String c ) {\r
        Assert( c.size() < 2 );\r
-       Trace("strings-regexp-derivative") << "RegExp-derivative starts with " << mkString( r ) << ", c=" << c << std::endl;\r
+       Trace("strings-regexp-derivative") << "RegExp-derivative starts with R{ " << mkString( r ) << " }, c=" << c << std::endl;\r
        Node retNode = Node::null();\r
        PairDvStr dv = std::make_pair( r, c );\r
        if( d_dv_cache.find( dv ) != d_dv_cache.end() ) {\r
@@ -236,7 +237,7 @@ Node RegExpOpr::derivativeSingle( Node r, CVC4::String c ) {
                                                        vec_nodes.push_back( dc );\r
                                                }\r
                                        }\r
-\r
+                                       Trace("strings-regexp-derivative") << "RegExp-derivative OR R[" << i << "]{ " << mkString(r[i]) << " returns " << (dc.isNull() ?  "NULL" : mkString(dc) ) << std::endl;\r
                                }\r
                                retNode = vec_nodes.size() == 0 ? Node::null() :\r
                                                        ( vec_nodes.size()==1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::REGEXP_OR, vec_nodes ) );\r
@@ -296,16 +297,16 @@ Node RegExpOpr::derivativeSingle( Node r, CVC4::String c ) {
                                break;\r
                        case kind::REGEXP_OPT:\r
                        {\r
-                               return derivativeSingle(r[0], c);\r
+                               retNode = derivativeSingle(r[0], c);\r
                        }\r
                                break;\r
                        case kind::REGEXP_RANGE:\r
                        {\r
                                char ch = c.getFirstChar();\r
                                if (ch >= r[0].getConst< CVC4::String >().getFirstChar() && ch <= r[1].getConst< CVC4::String >().getFirstChar() ) {\r
-                                       return d_emptyString;\r
+                                       retNode = d_emptyString;\r
                                } else {\r
-                                       return Node::null();\r
+                                       retNode = Node::null();\r
                                }\r
                        }\r
                                break;\r
@@ -315,6 +316,9 @@ Node RegExpOpr::derivativeSingle( Node r, CVC4::String c ) {
                                //AlwaysAssert( false );\r
                                //return Node::null();\r
                }\r
+               if(!retNode.isNull()) {\r
+                       retNode = Rewriter::rewrite( retNode );\r
+               }\r
                d_dv_cache[dv] = retNode;\r
        }\r
        Trace("strings-regexp-derivative") << "RegExp-derivative returns : " << ( retNode.isNull() ? "NULL" : mkString( retNode ) )  << std::endl;\r
index e5ce2d6d3fb29e0756f70ced637c8c612758ebef..fc4b3ba9c161648d9c7b0ca54a5c6bcd2bd8a9d9 100644 (file)
@@ -1017,17 +1017,19 @@ bool TheoryStrings::normalizeEquivalenceClass( Node eqc, std::vector< Node > & v
                                                                                        //d_pending_req_phase[ x_empty ] = true;
                                                                                        if( !areDisequal( normal_forms[loop_n_index][loop_index], d_emptyString ) ){
                                                                                                //try to make normal_forms[loop_n_index][loop_index] equal to empty to avoid loop
-                                                                                               sendSplit( normal_forms[loop_n_index][loop_index], d_emptyString, "Loop Empty" );
+                                                                                               sendSplit( normal_forms[loop_n_index][loop_index], d_emptyString, "Loop Empty x" );
                                                                                                return true;
-                                                                                       } else if( !areDisequal( t_yz, d_emptyString ) ) {
+                                                                                       } else if( !areDisequal( t_yz, d_emptyString ) && t_yz.getKind()!=kind::CONST_STRING  ) {
                                                                                                //TODO...........
                                                                                                //try to make normal_forms[loop_n_index][loop_index] equal to empty to avoid loop
-                                                                                               sendSplit( t_yz, d_emptyString, "Loop Empty" );
+                                                                                               sendSplit( t_yz, d_emptyString, "Loop Empty yz" );
                                                                                                return true;
                                                                                        } else {
                                                                                                //need to break
                                                                                                antec.push_back( normal_forms[loop_n_index][loop_index].eqNode( d_emptyString ).negate() );
-                                                                                               antec.push_back( t_yz.eqNode( d_emptyString ).negate() );
+                                                                                               if( t_yz.getKind()!=kind::CONST_STRING ){
+                                                                                                       antec.push_back( t_yz.eqNode( d_emptyString ).negate() );
+                                                                                               }
                                                                                                Node ant = mkExplain( antec, antec_new_lits );
                                                                                                Node str_in_re;
                                                                                                if( s_zy == t_yz &&
@@ -1977,7 +1979,6 @@ bool TheoryStrings::checkMemberships() {
                                Assert( atom.getKind()==kind::STRING_IN_REGEXP );
                                Node x = atom[0];
                                Node r = atom[1];
-                               //TODO
                                Assert( r.getKind()==kind::REGEXP_STAR );
                                if( !areEqual( x, d_emptyString ) ){
                                        //if(splitRegExp( x, r, atom )) {
@@ -2039,11 +2040,11 @@ bool TheoryStrings::checkMemberships() {
 }
 
 CVC4::String TheoryStrings::getHeadConst( Node x ) {
-       if( x.isConst() && x != d_emptyString ) {
+       if( x.isConst() ) {
                return x.getConst< String >();
        } else if( x.getKind() == kind::STRING_CONCAT ) {
-               if( x[0].isConst() && x[0] != d_emptyString ) {
-                       return x.getConst< String >();
+               if( x[0].isConst() ) {
+                       return x[0].getConst< String >();
                } else {
                        return d_emptyString.getConst< String >();
                }
@@ -2053,47 +2054,65 @@ CVC4::String TheoryStrings::getHeadConst( Node x ) {
 }
 
 bool TheoryStrings::splitRegExp( Node x, Node r, Node ant ) {
-       x =  Rewriter::rewrite( x );
-       if(x == d_emptyString) {
-               if(d_regexp_opr.delta( r ) == 1) {
-               }
-               return false;
-       } else {
-               CVC4::String s = getHeadConst( x );
-               if( !s.isEmptyString() && d_regexp_opr.checkConstRegExp( r ) ) {
-                       Node conc = Node::null();
-                       Node dc = r;
-                       bool flag = true;
-                       for(unsigned i=0; i<s.size(); ++i) {
-                               CVC4::String c = s.substr(i, 1);
-                               dc = d_regexp_opr.derivativeSingle(dc, c);
-                               if(dc.isNull()) {
-                                       // CONFLICT
-                                       flag = false;
-                                       break;
-                               }
+       // TODO cstr in vre
+       Assert(x != d_emptyString);
+       Trace("strings-regexp-split") << "TheoryStrings::splitRegExp: x=" << x << ", r= " << r << std::endl;
+       CVC4::String s = getHeadConst( x );
+       if( !s.isEmptyString() && d_regexp_opr.checkConstRegExp( r ) ) {
+               Node conc = Node::null();
+               Node dc = r;
+               bool flag = true;
+               for(unsigned i=0; i<s.size(); ++i) {
+                       CVC4::String c = s.substr(i, 1);
+                       dc = d_regexp_opr.derivativeSingle(dc, c);
+                       if(dc.isNull()) {
+                               // CONFLICT
+                               flag = false;
+                               break;
                        }
-                       // send lemma
-                       if(flag) {
-                               Node left = Node::null();
-                               if(x.isConst()) {
-                                       left = d_emptyString;
-                                       if(d_regexp_opr.delta(dc)) {
-                                               //TODO yes
-                                       } else {
-                                               // TODO conflict
-                                       }
+               }
+               // send lemma
+               if(flag) {
+                       if(x.isConst()) {
+                               /*
+                               left = d_emptyString;
+                               if(d_regexp_opr.delta(dc) == 1) {
+                                       //TODO yes possible?
+                               } else if(d_regexp_opr.delta(dc) == 0) {
+                                       //TODO possible?
                                } else {
-                                       //TODO find x rest
-                                       conc = NodeManager::currentNM()->mkNode( kind::STRING_IN_REGEXP, x, dc );
+                                       // TODO conflict possible?
+                               }*/
+                               Assert(false, "Impossible: TheoryStrings::splitRegExp: const string in const regular expression.");
+                               return false;
+                       } else {
+                               Assert( x.getKind() == kind::STRING_CONCAT );
+                               std::vector< Node > vec_nodes;
+                               for(unsigned int i=1; i<x.getNumChildren(); ++i ) {
+                                       vec_nodes.push_back( x[i] );
                                }
+                               Node left = vec_nodes.size() == 1 ? vec_nodes[0] : NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, vec_nodes );
+                               left = Rewriter::rewrite( left );
+                               conc = NodeManager::currentNM()->mkNode( kind::STRING_IN_REGEXP, left, dc );
+
+                               std::vector< Node > sdc;
+                               sdc.push_back( conc );
+
+                               StringsPreprocess spp;
+                               spp.simplify( sdc );
+                               for( unsigned i=1; i<sdc.size(); i++ ){
+                                       //add the others as lemmas
+                                       sendLemma( d_true, sdc[i], "RegExp Definition");
+                               }
+                               
+                               conc = sdc[0];
                        }
-                       sendLemma(ant, conc, "RegExp Const Split");
-               } else {
-                       return false;
                }
+               sendLemma(ant, conc, "RegExp Const Split");
+               return true;
+       } else {
+               return false;
        }
-       return false;
 }
 
 Node TheoryStrings::getNextDecisionRequest() {