Refactoring of conjecture generator. Determine subgoals are non-canonical based...
authorajreynol <andrew.j.reynolds@gmail.com>
Tue, 16 Sep 2014 14:56:10 +0000 (16:56 +0200)
committerajreynol <andrew.j.reynolds@gmail.com>
Tue, 16 Sep 2014 14:56:10 +0000 (16:56 +0200)
src/smt/smt_engine.cpp
src/theory/quantifiers/conjecture_generator.cpp [changed mode: 0644->0755]
src/theory/quantifiers/conjecture_generator.h [changed mode: 0644->0755]
src/theory/quantifiers/options
src/theory/quantifiers/term_database.cpp
src/theory/quantifiers/term_database.h

index cd3a7943ef619a91895abf3589a58f0e3bb22cc5..caa757426a4816c991245133f6c7392e79540713 100644 (file)
@@ -1310,6 +1310,17 @@ void SmtEngine::setDefaults() {
       options::purifyTriggers.set( true );
     }
   }
+  if( options::conjectureNoFilter() ){
+    if( !options::conjectureFilterActiveTerms.wasSetByUser() ){
+      options::conjectureFilterActiveTerms.set( false );
+    }
+    if( !options::conjectureFilterCanonical.wasSetByUser() ){
+      options::conjectureFilterCanonical.set( false );
+    }
+    if( !options::conjectureFilterModel.wasSetByUser() ){
+      options::conjectureFilterModel.set( false );
+    }
+  }
 
   //until bugs 371,431 are fixed
   if( ! options::minisatUseElim.wasSetByUser()){
old mode 100644 (file)
new mode 100755 (executable)
index 0b8e0e4..0184604
@@ -103,6 +103,7 @@ void ConjectureGenerator::eqNotifyPreMerge(TNode t1, TNode t2) {
   }\r
   Trace("thm-ee-debug") << "UEE : equality holds : " << t1 << " == " << t2 << std::endl;\r
   Trace("thm-ee-debug") << "      ureps : " << rt1 << " == " << rt2 << std::endl;\r
+  Trace("thm-ee-debug") << "      relevant : " << d_pattern_is_relevant[rt1] << " " << d_pattern_is_relevant[rt2] << std::endl;\r
   Trace("thm-ee-debug") << "      normal : " << d_pattern_is_normal[rt1] << " " << d_pattern_is_normal[rt2] << std::endl;\r
   Trace("thm-ee-debug") << "      size :   " << d_pattern_fun_sum[rt1] << " " << d_pattern_fun_sum[rt2] << std::endl;\r
 \r
@@ -145,60 +146,6 @@ ConjectureGenerator::EqcInfo* ConjectureGenerator::getOrMakeEqcInfo( TNode n, bo
   }\r
 }\r
 \r
-void ConjectureGenerator::doPendingAddUniversalTerms() {\r
-  //merge all pending equalities\r
-  while( !d_upendingAdds.empty() ){\r
-    Trace("sg-pending") << "Add " << d_upendingAdds.size() << " pending terms..." << std::endl;\r
-    std::vector< Node > pending;\r
-    pending.insert( pending.end(), d_upendingAdds.begin(), d_upendingAdds.end() );\r
-    d_upendingAdds.clear();\r
-    for( unsigned i=0; i<pending.size(); i++ ){\r
-      Node t = pending[i];\r
-      TypeNode tn = t.getType();\r
-      Trace("thm-ee-add") << "UEE : Add universal term " << t << std::endl;\r
-      //get all equivalent terms based on theorem database\r
-      std::vector< Node > eq_terms;\r
-      d_thm_index.getEquivalentTerms( t, eq_terms );\r
-      if( !eq_terms.empty() ){\r
-        Trace("thm-ee-add") << "UEE : Based on theorem database, it is equivalent to " << eq_terms.size() << " terms : " << std::endl;\r
-        //add equivalent terms as equalities to universal engine\r
-        for( unsigned i=0; i<eq_terms.size(); i++ ){\r
-          Trace("thm-ee-add") << "  " << eq_terms[i] << std::endl;\r
-          //if( d_urelevant_terms.find( eq_terms[i] )!=d_urelevant_terms.end() ){\r
-          bool assertEq = false;\r
-          if( d_urelevant_terms.find( eq_terms[i] )!=d_urelevant_terms.end() ){\r
-            assertEq = true;\r
-          }else{\r
-            Assert( eq_terms[i].getType()==tn );\r
-            registerPattern( eq_terms[i], tn );\r
-            if( isUniversalLessThan( eq_terms[i], t ) ){\r
-              setUniversalRelevant( eq_terms[i] );\r
-              assertEq = true;\r
-            }\r
-          }\r
-          if( assertEq ){\r
-            Node exp;\r
-            d_uequalityEngine.assertEquality( t.eqNode( eq_terms[i] ), true, exp );\r
-          }\r
-        }\r
-      }else{\r
-        Trace("thm-ee-add") << "UEE : No equivalent terms." << std::endl;\r
-      }\r
-      //if occurs at ground level, merge with representative of ground equality engine\r
-      /*\r
-      eq::EqualityEngine * ee = getEqualityEngine();\r
-      if( ee->hasTerm( t ) ){\r
-        TNode grt = ee->getRepresentative( t );\r
-        if( t!=grt ){\r
-          Node exp;\r
-          d_uequalityEngine.assertEquality( t.eqNode( grt ), true, exp );\r
-        }\r
-      }\r
-      */\r
-    }\r
-  }\r
-}\r
-\r
 void ConjectureGenerator::setUniversalRelevant( TNode n ) {\r
   //add pattern information\r
   registerPattern( n, n.getType() );\r
@@ -210,22 +157,29 @@ void ConjectureGenerator::setUniversalRelevant( TNode n ) {
 \r
 bool ConjectureGenerator::isUniversalLessThan( TNode rt1, TNode rt2 ) {\r
   //prefer the one that is (normal, smaller) lexographically\r
+  Assert( d_pattern_is_relevant.find( rt1 )!=d_pattern_is_relevant.end() );\r
+  Assert( d_pattern_is_relevant.find( rt2 )!=d_pattern_is_relevant.end() );\r
   Assert( d_pattern_is_normal.find( rt1 )!=d_pattern_is_normal.end() );\r
   Assert( d_pattern_is_normal.find( rt2 )!=d_pattern_is_normal.end() );\r
   Assert( d_pattern_fun_sum.find( rt1 )!=d_pattern_fun_sum.end() );\r
   Assert( d_pattern_fun_sum.find( rt2 )!=d_pattern_fun_sum.end() );\r
 \r
-  if( d_pattern_is_normal[rt1] && !d_pattern_is_normal[rt2] ){\r
-    Trace("thm-ee-debug") << "UEE : LT due to normal." << std::endl;\r
+  if( d_pattern_is_relevant[rt1] && !d_pattern_is_relevant[rt2] ){\r
+    Trace("thm-ee-debug") << "UEE : LT due to relevant." << std::endl;\r
     return true;\r
-  }else if( d_pattern_is_normal[rt1]==d_pattern_is_normal[rt2] ){\r
-    if( d_pattern_fun_sum[rt1]<d_pattern_fun_sum[rt2] ){\r
-      Trace("thm-ee-debug") << "UEE : LT due to size." << std::endl;\r
-      //decide which representative to use : based on size of the term\r
+  }else if( d_pattern_is_relevant[rt1]==d_pattern_is_relevant[rt2] ){\r
+    if( d_pattern_is_normal[rt1] && !d_pattern_is_normal[rt2] ){\r
+      Trace("thm-ee-debug") << "UEE : LT due to normal." << std::endl;\r
       return true;\r
-    }else if( d_pattern_fun_sum[rt1]==d_pattern_fun_sum[rt2] ){\r
-      //same size : tie goes to term that has already been reported\r
-      return isReportedCanon( rt1 ) && !isReportedCanon( rt2 );\r
+    }else if( d_pattern_is_normal[rt1]==d_pattern_is_normal[rt2] ){\r
+      if( d_pattern_fun_sum[rt1]<d_pattern_fun_sum[rt2] ){\r
+        Trace("thm-ee-debug") << "UEE : LT due to size." << std::endl;\r
+        //decide which representative to use : based on size of the term\r
+        return true;\r
+      }else if( d_pattern_fun_sum[rt1]==d_pattern_fun_sum[rt2] ){\r
+        //same size : tie goes to term that has already been reported\r
+        return isReportedCanon( rt1 ) && !isReportedCanon( rt2 );\r
+      }\r
     }\r
   }\r
   return false;\r
@@ -256,10 +210,56 @@ TNode ConjectureGenerator::getUniversalRepresentative( TNode n, bool add ) {
       setUniversalRelevant( n );\r
       //add term to universal equality engine\r
       d_uequalityEngine.addTerm( n );\r
-      Trace("thm-ee-debug") << "Merge equivalence classes based on terms..." << std::endl;\r
-      doPendingAddUniversalTerms();\r
+      // addding this term to equality engine will lead to a set of new terms (the new subterms of n)\r
+      // now, do instantiation-based merging for each of these terms\r
+      Trace("thm-ee-debug") << "Merge equivalence classes based on instantiations of terms..." << std::endl;\r
+      //merge all pending equalities\r
+      while( !d_upendingAdds.empty() ){\r
+        Trace("sg-pending") << "Add " << d_upendingAdds.size() << " pending terms..." << std::endl;\r
+        std::vector< Node > pending;\r
+        pending.insert( pending.end(), d_upendingAdds.begin(), d_upendingAdds.end() );\r
+        d_upendingAdds.clear();\r
+        for( unsigned i=0; i<pending.size(); i++ ){\r
+          Node t = pending[i];\r
+          TypeNode tn = t.getType();\r
+          Trace("thm-ee-add") << "UEE : Add universal term " << t << std::endl;\r
+          std::vector< Node > eq_terms;\r
+          //if occurs modulo equality at ground level, it is equivalent to representative of ground equality engine\r
+          TNode gt = getTermDatabase()->evaluateTerm( t );\r
+          if( !gt.isNull() && gt!=t ){\r
+            eq_terms.push_back( gt );\r
+          }\r
+          //get all equivalent terms based on theorem database\r
+          d_thm_index.getEquivalentTerms( t, eq_terms );\r
+          if( !eq_terms.empty() ){\r
+            Trace("thm-ee-add") << "UEE : Based on ground EE/theorem DB, it is equivalent to " << eq_terms.size() << " terms : " << std::endl;\r
+            //add equivalent terms as equalities to universal engine\r
+            for( unsigned i=0; i<eq_terms.size(); i++ ){\r
+              Trace("thm-ee-add") << "  " << eq_terms[i] << std::endl;\r
+              bool assertEq = false;\r
+              if( d_urelevant_terms.find( eq_terms[i] )!=d_urelevant_terms.end() ){\r
+                assertEq = true;\r
+              }else{\r
+                Assert( eq_terms[i].getType()==tn );\r
+                registerPattern( eq_terms[i], tn );\r
+                if( isUniversalLessThan( eq_terms[i], t ) ){\r
+                  setUniversalRelevant( eq_terms[i] );\r
+                  assertEq = true;\r
+                }\r
+              }\r
+              if( assertEq ){\r
+                Node exp;\r
+                d_uequalityEngine.assertEquality( t.eqNode( eq_terms[i] ), true, exp );\r
+              }\r
+            }\r
+          }else{\r
+            Trace("thm-ee-add") << "UEE : No equivalent terms." << std::endl;\r
+          }\r
+        }\r
+      }\r
     }\r
   }\r
+  \r
   if( d_uequalityEngine.hasTerm( n ) ){\r
     Node r = d_uequalityEngine.getRepresentative( n );\r
     EqcInfo * ei = getOrMakeEqcInfo( r );\r
@@ -335,7 +335,7 @@ Node ConjectureGenerator::getCanonicalTerm( TNode n, std::map< TypeNode, unsigne
     if( n.getKind()!=EQUAL ){\r
       if( n.hasOperator() ){\r
         TNode op = n.getOperator();\r
-        if( std::find( d_funcs.begin(), d_funcs.end(), op )==d_funcs.end() ){\r
+        if( !isRelevantFunc( op ) ){\r
           return Node::null();\r
         }\r
         children.push_back( op );\r
@@ -372,6 +372,10 @@ bool ConjectureGenerator::isGroundTerm( TNode n ) {
   return std::find( d_ground_terms.begin(), d_ground_terms.end(), n )!=d_ground_terms.end();\r
 }\r
 \r
+bool ConjectureGenerator::isRelevantFunc( Node f ) {\r
+  return std::find( d_funcs.begin(), d_funcs.end(), f )!=d_funcs.end();\r
+}\r
+\r
 bool ConjectureGenerator::needsCheck( Theory::Effort e ) {\r
   return e==Theory::EFFORT_FULL;\r
 }\r
@@ -657,6 +661,7 @@ void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
       d_pattern_var_id.clear();\r
       d_pattern_var_duplicate.clear();\r
       d_pattern_is_normal.clear();\r
+      d_pattern_is_relevant.clear();\r
       d_pattern_fun_id.clear();\r
       d_pattern_fun_sum.clear();\r
       d_rel_patterns.clear();\r
@@ -668,44 +673,40 @@ void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
       //d_gen_lat_parent.clear();\r
       //d_gen_depth.clear();\r
 \r
-      //the following generates a set of relevant terms\r
-      d_use_ccand_eqc = true;\r
-      for( unsigned i=0; i<2; i++ ){\r
-        d_ccand_eqc[i].clear();\r
-        d_ccand_eqc[i].push_back( d_relevant_eqc[i] );\r
-      }\r
-      d_rel_term_count = 0;\r
-      //consider all functions\r
+      unsigned rel_term_count = 0;\r
+      //consider all functions from relevant signature\r
       d_typ_tg_funcs.clear();\r
       for( std::map< TypeNode, std::vector< TNode > >::iterator it = d_typ_funcs.begin(); it != d_typ_funcs.end(); ++it ){\r
         d_typ_tg_funcs[it->first].insert( d_typ_tg_funcs[it->first].end(), it->second.begin(), it->second.end() );\r
       }\r
       std::map< TypeNode, unsigned > rt_var_max;\r
       std::vector< TypeNode > rt_types;\r
-      std::map< int, std::vector< Node > > conj_lhs;\r
-      std::map< int, std::vector< Node > > conj_rhs;\r
-      //map from generalization depth to maximum depth\r
-      //std::map< unsigned, unsigned > gdepth_to_tdepth;\r
-      for( unsigned depth=1; depth<3; depth++ ){\r
+      std::map< TypeNode, std::map< int, std::vector< Node > > > conj_lhs;\r
+      for( unsigned depth=1; depth<=3; depth++ ){\r
         Assert( d_tg_alloc.empty() );\r
-        Trace("sg-proc") << "Generate terms at depth " << depth << "..." << std::endl;\r
+        Trace("sg-proc") << "Generate relevant LHS at depth " << depth << "..." << std::endl;\r
         Trace("sg-rel-term") << "Relevant terms of depth " << depth << " : " << std::endl;\r
         //set up environment\r
+        for( unsigned i=0; i<2; i++ ){\r
+          d_ccand_eqc[i].clear();\r
+          d_ccand_eqc[i].push_back( d_relevant_eqc[i] );\r
+        }\r
         d_var_id.clear();\r
         d_var_limit.clear();\r
         d_tg_id = 0;\r
         d_tg_gdepth = 0;\r
         d_tg_gdepth_limit = depth;\r
+        d_gen_relevant_terms = true;        \r
         //consider all types\r
         d_tg_alloc[0].reset( this, TypeNode::null() );\r
         while( d_tg_alloc[0].getNextTerm( this, depth ) ){\r
-          Assert( d_tg_alloc[0].getGeneralizationDepth( this )==d_tg_gdepth );\r
+          //Assert( d_tg_alloc[0].getGeneralizationDepth( this )==d_tg_gdepth );\r
           //if( d_tg_alloc[0].getDepth( this )==depth ){\r
-          if( (int)d_tg_gdepth==d_tg_gdepth_limit ){\r
+          if( d_tg_alloc[0].getGeneralizationDepth( this )==depth ){\r
             //construct term\r
             Node nn = d_tg_alloc[0].getTerm( this );\r
             if( getUniversalRepresentative( nn )==nn ){\r
-              d_rel_term_count++;\r
+              rel_term_count++;\r
               Trace("sg-rel-term") << "*** Relevant term : ";\r
               d_tg_alloc[0].debugPrint( this, "sg-rel-term", "sg-rel-term-debug2" );\r
               Trace("sg-rel-term") << std::endl;\r
@@ -720,7 +721,7 @@ void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
               }\r
               TypeNode tnn = nn.getType();\r
               Trace("sg-gen-tg-debug") << "...term is " << nn << std::endl;\r
-              conj_lhs[depth].push_back( nn );\r
+              conj_lhs[tnn][depth].push_back( nn );\r
 \r
               //add information about pattern\r
               Trace("sg-gen-tg-debug") << "Collect pattern information..." << std::endl;\r
@@ -805,104 +806,143 @@ void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
           }\r
         }\r
         Trace("sg-proc") << "...done generate terms at depth " << depth << std::endl;\r
-\r
+        Trace("sg-stats") << "--------> Total LHS of depth : " << rel_term_count << std::endl;\r
+        //Trace("conjecture-count") << "Total LHS of depth " << depth << " : " << conj_lhs[depth].size() << std::endl;\r
         //now generate right hand sides\r
 \r
-\r
-      }\r
-      Trace("sg-stats") << "--------> Total relevant patterns : " << d_rel_term_count << std::endl;\r
-\r
-      Trace("sg-proc") << "Generate properties..." << std::endl;\r
-      //set up environment\r
-      d_use_ccand_eqc = false;\r
-      d_var_id.clear();\r
-      d_var_limit.clear();\r
-      for( std::map< TypeNode, unsigned >::iterator it = rt_var_max.begin(); it != rt_var_max.end(); ++it ){\r
-        d_var_id[ it->first ] = it->second;\r
-        d_var_limit[ it->first ] = it->second;\r
-      }\r
-      //set up environment for candidate conjectures\r
-      //d_cconj_at_depth.clear();\r
-      //for( unsigned i=0; i<2; i++ ){\r
-      //  d_cconj[i].clear();\r
-      //}\r
-      //d_cconj_rhs_paired.clear();\r
-      unsigned totalCount = 0;\r
-      for( unsigned depth=0; depth<5; depth++ ){\r
         //consider types from relevant terms\r
-        std::random_shuffle( rt_types.begin(), rt_types.end() );\r
-        for( unsigned i=0; i<rt_types.size(); i++ ){\r
-          Assert( d_tg_alloc.empty() );\r
-          Trace("sg-proc") << "Generate relevant RHS terms of type " << rt_types[i] << " at depth " << depth << "..." << std::endl;\r
-          d_tg_id = 0;\r
-          d_tg_gdepth = 0;\r
-          d_tg_gdepth_limit = -1;\r
-          d_tg_alloc[0].reset( this, rt_types[i] );\r
-          while( d_tg_alloc[0].getNextTerm( this, depth ) && totalCount<100 ){\r
-            if( d_tg_alloc[0].getDepth( this )==depth ){\r
-              Node rhs = d_tg_alloc[0].getTerm( this );\r
-              Trace("sg-rel-prop") << "Relevant RHS : " << rhs << std::endl;\r
-              conj_rhs[depth].push_back( rhs );\r
-              //register pattern\r
-              Assert( rhs.getType()==rt_types[i] );\r
-              registerPattern( rhs, rt_types[i] );\r
-              totalCount++;\r
+        for( unsigned rdepth=0; rdepth<=depth; rdepth++ ){\r
+          //set up environment\r
+          d_gen_relevant_terms = false;\r
+          d_var_id.clear();\r
+          d_var_limit.clear();\r
+          for( std::map< TypeNode, unsigned >::iterator it = rt_var_max.begin(); it != rt_var_max.end(); ++it ){\r
+            d_var_id[ it->first ] = it->second;\r
+            d_var_limit[ it->first ] = it->second;\r
+          }\r
+          std::random_shuffle( rt_types.begin(), rt_types.end() );\r
+          std::map< TypeNode, std::vector< Node > > conj_rhs;\r
+          for( unsigned i=0; i<rt_types.size(); i++ ){\r
+            Assert( d_tg_alloc.empty() );\r
+            Trace("sg-proc") << "Generate relevant RHS terms of type " << rt_types[i] << " at depth " << rdepth << "..." << std::endl;\r
+            d_tg_id = 0;\r
+            d_tg_gdepth = 0;\r
+            d_tg_gdepth_limit = rdepth;\r
+            d_tg_alloc[0].reset( this, rt_types[i] );\r
+            while( d_tg_alloc[0].getNextTerm( this, rdepth ) ){\r
+              if( d_tg_alloc[0].getGeneralizationDepth( this )==rdepth ){\r
+                Node rhs = d_tg_alloc[0].getTerm( this );\r
+                Trace("sg-rel-prop") << "Relevant RHS : " << rhs << std::endl;\r
+                //register pattern\r
+                Assert( rhs.getType()==rt_types[i] );\r
+                registerPattern( rhs, rt_types[i] );\r
+                if( rdepth<depth ){\r
+                  //consider against all LHS at depth\r
+                  for( unsigned j=0; j<conj_lhs[rt_types[i]][depth].size(); j++ ){\r
+                    processCandidateConjecture( conj_lhs[rt_types[i]][depth][j], rhs, depth, rdepth );\r
+                  }\r
+                }else{\r
+                  conj_rhs[rt_types[i]].push_back( rhs );\r
+                }\r
+              }\r
             }\r
+            //could have been partial, we must clear\r
+            //REMOVE_THIS?\r
+            d_tg_alloc.clear();\r
           }\r
-          //could have been partial, we must clear\r
-          d_tg_alloc.clear();\r
-        }\r
-        Trace("sg-proc") << "Process candidate conjectures up to RHS term depth " << depth << "..." << std::endl;\r
-        for( int rhs_d=depth; rhs_d>=0; rhs_d-- ){\r
-          int lhs_d = (depth-rhs_d)+1;\r
-          for( unsigned i=0; i<conj_rhs[rhs_d].size(); i++ ){\r
-            for( unsigned j=0; j<conj_lhs[lhs_d].size(); j++ ){\r
-              processCandidateConjecture( conj_lhs[lhs_d][j], conj_rhs[rhs_d][i], lhs_d, rhs_d );\r
+          //consider against all LHS up to depth\r
+          if( rdepth==depth ){\r
+            for( unsigned lhs_depth = 1; lhs_depth<=depth; lhs_depth++ ){\r
+              if( !optStatsOnly() && d_waiting_conjectures_lhs.size()>=optFullCheckConjectures() ){\r
+                break;\r
+              }\r
+              Trace("sg-proc") << "Consider conjectures at depth (" << lhs_depth << ", " << rdepth << ")..." << std::endl;\r
+              for( std::map< TypeNode, std::vector< Node > >::iterator it = conj_rhs.begin(); it != conj_rhs.end(); ++it ){\r
+                for( unsigned j=0; j<it->second.size(); j++ ){\r
+                  for( unsigned k=0; k<conj_lhs[it->first][lhs_depth].size(); k++ ){\r
+                    processCandidateConjecture( conj_lhs[it->first][lhs_depth][k], it->second[j], lhs_depth, rdepth );\r
+                  }\r
+                }\r
+              }\r
             }\r
           }\r
         }\r
-        Trace("sg-proc") << "...done process candidate conjectures at RHS term depth " << depth << std::endl;\r
+        if( optStatsOnly() ){\r
+          Trace("conjecture-count") << "Generated " << d_waiting_conjectures_lhs.size() << " conjectures for depth " << depth << "." << std::endl;\r
+          d_waiting_conjectures_lhs.clear();\r
+          d_waiting_conjectures_rhs.clear();\r
+        }else if( d_waiting_conjectures_lhs.size()>=optFullCheckConjectures() ){\r
+          break;\r
+        }\r
       }\r
-      Trace("sg-proc") << "...done generate properties" << std::endl;\r
-\r
-      if( !d_waiting_conjectures.empty() ){\r
-        Trace("sg-proc") << "Generated " << d_waiting_conjectures.size() << " conjectures." << std::endl;\r
-        d_conjectures.insert( d_conjectures.end(), d_waiting_conjectures.begin(), d_waiting_conjectures.end() );\r
-        for( unsigned i=0; i<d_waiting_conjectures.size(); i++ ){\r
-          Assert( d_waiting_conjectures[i].getKind()==FORALL );\r
-          Node lem = NodeManager::currentNM()->mkNode( OR, d_waiting_conjectures[i].negate(), d_waiting_conjectures[i] );\r
-          d_quantEngine->addLemma( lem, false );\r
-          d_quantEngine->addRequirePhase( d_waiting_conjectures[i], false );\r
+\r
+      if( !d_waiting_conjectures_lhs.empty() ){\r
+        Trace("sg-proc") << "Generated " << d_waiting_conjectures_lhs.size() << " conjectures." << std::endl;\r
+        //TODO: prune conjectures in a smart way\r
+        for( unsigned i=0; i<d_waiting_conjectures_lhs.size(); i++ ){\r
+          if( i>optFullCheckConjectures() ){\r
+            break;\r
+          }else{\r
+            //we have determined a relevant subgoal\r
+            Node lhs = d_waiting_conjectures_lhs[i];\r
+            Node rhs = d_waiting_conjectures_rhs[i];\r
+            std::vector< Node > bvs;\r
+            for( std::map< TypeNode, unsigned >::iterator it = d_pattern_var_id[lhs].begin(); it != d_pattern_var_id[lhs].end(); ++it ){\r
+              for( unsigned i=0; i<=it->second; i++ ){\r
+                bvs.push_back( getFreeVar( it->first, i ) );\r
+              }\r
+            }\r
+            Node rsg;\r
+            if( !bvs.empty() ){\r
+              Node bvl = NodeManager::currentNM()->mkNode( BOUND_VAR_LIST, bvs );\r
+              rsg = NodeManager::currentNM()->mkNode( FORALL, bvl, lhs.eqNode( rhs ) );\r
+            }else{\r
+              rsg = lhs.eqNode( rhs );\r
+            }\r
+            rsg = Rewriter::rewrite( rsg );\r
+            Trace("sg-lemma") << "Constructed : " << rsg << std::endl;\r
+            d_conjectures.push_back( rsg );\r
+            d_eq_conjectures[lhs].push_back( rhs );\r
+            d_eq_conjectures[rhs].push_back( lhs );\r
+\r
+            Node lem = NodeManager::currentNM()->mkNode( OR, rsg.negate(), rsg );\r
+            d_quantEngine->addLemma( lem, false );\r
+            d_quantEngine->addRequirePhase( rsg, false );\r
+          }\r
         }\r
+        d_waiting_conjectures_lhs.clear();\r
+        d_waiting_conjectures_rhs.clear();\r
         d_waiting_conjectures.clear();\r
       }\r
 \r
-      Trace("thm-ee") << "Universal equality engine is : " << std::endl;\r
-      eq::EqClassesIterator ueqcs_i = eq::EqClassesIterator( &d_uequalityEngine );\r
-      while( !ueqcs_i.isFinished() ){\r
-        TNode r = (*ueqcs_i);\r
-        bool firstTime = true;\r
-        TNode rr = getUniversalRepresentative( r );\r
-        Trace("thm-ee") << "  " << r;\r
-        if( rr!=r ){ Trace("thm-ee") << " [" << rr << "]"; }\r
-        Trace("thm-ee") << " : { ";\r
-        eq::EqClassIterator ueqc_i = eq::EqClassIterator( r, &d_uequalityEngine );\r
-        while( !ueqc_i.isFinished() ){\r
-          TNode n = (*ueqc_i);\r
-          if( r!=n ){\r
-            if( firstTime ){\r
-              Trace("thm-ee") << std::endl;\r
-              firstTime = false;\r
+      if( Trace.isOn("thm-ee") ){\r
+        Trace("thm-ee") << "Universal equality engine is : " << std::endl;\r
+        eq::EqClassesIterator ueqcs_i = eq::EqClassesIterator( &d_uequalityEngine );\r
+        while( !ueqcs_i.isFinished() ){\r
+          TNode r = (*ueqcs_i);\r
+          bool firstTime = true;\r
+          TNode rr = getUniversalRepresentative( r );\r
+          Trace("thm-ee") << "  " << r;\r
+          if( rr!=r ){ Trace("thm-ee") << " [" << rr << "]"; }\r
+          Trace("thm-ee") << " : { ";\r
+          eq::EqClassIterator ueqc_i = eq::EqClassIterator( r, &d_uequalityEngine );\r
+          while( !ueqc_i.isFinished() ){\r
+            TNode n = (*ueqc_i);\r
+            if( r!=n ){\r
+              if( firstTime ){\r
+                Trace("thm-ee") << std::endl;\r
+                firstTime = false;\r
+              }\r
+              Trace("thm-ee") << "    " << n << std::endl;\r
             }\r
-            Trace("thm-ee") << "    " << n << std::endl;\r
+            ++ueqc_i;\r
           }\r
-          ++ueqc_i;\r
+          if( !firstTime ){ Trace("thm-ee") << "  "; }\r
+          Trace("thm-ee") << "}" << std::endl;\r
+          ++ueqcs_i;\r
         }\r
-        if( !firstTime ){ Trace("thm-ee") << "  "; }\r
-        Trace("thm-ee") << "}" << std::endl;\r
-        ++ueqcs_i;\r
+        Trace("thm-ee") << std::endl;\r
       }\r
-      Trace("thm-ee") << std::endl;\r
     }\r
   }\r
 }\r
@@ -960,9 +1000,7 @@ bool ConjectureGenerator::considerCurrentTerm() {
   Trace("sg-gen-tg-debug") << "?  curr term size = " << d_tg_alloc.size() << ", last status = " << d_tg_alloc[i-1].d_status;\r
   Trace("sg-gen-tg-debug") << std::endl;\r
 \r
-  Assert( d_tg_alloc[0].getGeneralizationDepth( this )==d_tg_gdepth );\r
-\r
-  if( d_tg_gdepth_limit>=0 && d_tg_gdepth>(unsigned)d_tg_gdepth_limit ){\r
+  if( d_tg_gdepth_limit>=0 && d_tg_alloc[0].getGeneralizationDepth( this )>(unsigned)d_tg_gdepth_limit ){\r
     Trace("sg-gen-consider-term") << "-> generalization depth of ";\r
     d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-tg-debug" );\r
     Trace("sg-gen-consider-term") << " is too high " << d_tg_gdepth << " " << d_tg_alloc[0].getGeneralizationDepth( this ) << ", do not consider." << std::endl;\r
@@ -970,6 +1008,7 @@ bool ConjectureGenerator::considerCurrentTerm() {
   }\r
 \r
   //----optimizations\r
+  /*\r
   if( d_tg_alloc[i-1].d_status==1 ){\r
   }else if( d_tg_alloc[i-1].d_status==2 ){\r
   }else if( d_tg_alloc[i-1].d_status==5 ){\r
@@ -977,12 +1016,13 @@ bool ConjectureGenerator::considerCurrentTerm() {
     Trace("sg-gen-tg-debug") << "Bad tg: " << &d_tg_alloc[i-1] << std::endl;\r
     Assert( false );\r
   }\r
+  */\r
   //if equated two variables, first check if context-independent TODO\r
   //----end optimizations\r
 \r
 \r
   //check based on which candidate equivalence classes match\r
-  if( d_use_ccand_eqc ){\r
+  if( d_gen_relevant_terms ){\r
     Trace("sg-gen-tg-debug") << "Filter based on relevant ground EQC";\r
     Trace("sg-gen-tg-debug") << ", #eqc to try = " << d_ccand_eqc[0][i-1].size() << "/" << d_ccand_eqc[1][i-1].size() << std::endl;\r
 \r
@@ -1019,13 +1059,13 @@ bool ConjectureGenerator::considerCurrentTerm() {
       }\r
       Trace("sg-gen-tg-debug") << std::endl;\r
     }\r
-    if( d_ccand_eqc[0][i].empty() ){\r
+    if( options::conjectureFilterActiveTerms() && d_ccand_eqc[0][i].empty() ){\r
       Trace("sg-gen-consider-term") << "Do not consider term of form ";\r
       d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-consider-term-debug" );\r
       Trace("sg-gen-consider-term") << " since no relevant EQC matches it." << std::endl;\r
       return false;\r
     }\r
-    if( d_ccand_eqc[1][i].empty() && optFilterConfirmation() ){\r
+    if( options::conjectureFilterModel() && d_ccand_eqc[1][i].empty() && optFilterConfirmation() ){\r
       Trace("sg-gen-consider-term") << "Do not consider term of form ";\r
       d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-consider-term-debug" );\r
       Trace("sg-gen-consider-term") << " since no ground EQC matches it." << std::endl;\r
@@ -1039,33 +1079,35 @@ bool ConjectureGenerator::considerCurrentTerm() {
   return true;\r
 }\r
 \r
-bool ConjectureGenerator::considerTermCanon( unsigned tg_id ){\r
+bool ConjectureGenerator::considerCurrentTermCanon( unsigned tg_id ){\r
   Assert( tg_id<d_tg_alloc.size() );\r
-  //check based on a canonicity of the term (if there is one)\r
-  Trace("sg-gen-tg-debug") << "Consider term canon ";\r
-  d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
-  Trace("sg-gen-tg-debug") << ", tg is [" << tg_id << "]..." << std::endl;\r
-\r
-  Node ln = d_tg_alloc[tg_id].getTerm( this );\r
-  Trace("sg-gen-tg-debug") << "Term is " << ln << std::endl;\r
-  if( !ln.isNull() ){\r
-    //do not consider if it is non-canonical, and either:\r
-    //  (1) we are not filtering based on matching candidate eqc, or\r
-    //  (2) its canonical form is a generalization.\r
-    TNode lnr = getUniversalRepresentative( ln, true );\r
-    if( lnr==ln ){\r
-      markReportedCanon( ln );\r
-    }else if( !d_use_ccand_eqc || isGeneralization( lnr, ln ) ){\r
-      Trace("sg-gen-consider-term") << "Do not consider term of form ";\r
-      d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-consider-term-debug" );\r
-      Trace("sg-gen-consider-term") << " since sub-term " << ln << " is not canonical representation (which is " << lnr << ")." << std::endl;\r
-      return false;\r
+  if( options::conjectureFilterCanonical() ){\r
+    //check based on a canonicity of the term (if there is one)\r
+    Trace("sg-gen-tg-debug") << "Consider term canon ";\r
+    d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
+    Trace("sg-gen-tg-debug") << ", tg is [" << tg_id << "]..." << std::endl;\r
+\r
+    Node ln = d_tg_alloc[tg_id].getTerm( this );\r
+    Trace("sg-gen-tg-debug") << "Term is " << ln << std::endl;\r
+    if( !ln.isNull() ){\r
+      //do not consider if it is non-canonical, and either:\r
+      //  (1) we are not generating relevant terms, or\r
+      //  (2) its canonical form is a generalization.\r
+      TNode lnr = getUniversalRepresentative( ln, true );\r
+      if( lnr==ln ){\r
+        markReportedCanon( ln );\r
+      }else if( !d_gen_relevant_terms || isGeneralization( lnr, ln ) ){\r
+        Trace("sg-gen-consider-term") << "Do not consider term of form ";\r
+        d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-consider-term-debug" );\r
+        Trace("sg-gen-consider-term") << " since sub-term " << ln << " is not canonical representation (which is " << lnr << ")." << std::endl;\r
+        return false;\r
+      }\r
     }\r
+    Trace("sg-gen-tg-debug") << "Will consider term canon ";\r
+    d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
+    Trace("sg-gen-tg-debug") << std::endl;\r
+    Trace("sg-gen-consider-term-debug") << std::endl;\r
   }\r
-  Trace("sg-gen-tg-debug") << "Will consider term canon ";\r
-  d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
-  Trace("sg-gen-tg-debug") << std::endl;\r
-  Trace("sg-gen-consider-term-debug") << std::endl;\r
   return true;\r
 }\r
 \r
@@ -1089,6 +1131,9 @@ unsigned ConjectureGenerator::collectFunctions( TNode opat, TNode pat, std::map<
                                              std::map< TypeNode, unsigned >& mnvn, std::map< TypeNode, unsigned >& mxvn ){\r
   if( pat.hasOperator() ){\r
     funcs[pat.getOperator()]++;\r
+    if( !isRelevantFunc( pat.getOperator() ) ){\r
+      d_pattern_is_relevant[opat] = false;\r
+    }\r
     unsigned sum = 1;\r
     for( unsigned i=0; i<pat.getNumChildren(); i++ ){\r
       sum += collectFunctions( opat, pat[i], funcs, mnvn, mxvn );\r
@@ -1123,6 +1168,8 @@ unsigned ConjectureGenerator::collectFunctions( TNode opat, TNode pat, std::map<
           mxvn[tn] = vn;\r
         }\r
       }\r
+    }else{\r
+      d_pattern_is_relevant[opat] = false;\r
     }\r
     return 1;\r
   }\r
@@ -1142,6 +1189,9 @@ void ConjectureGenerator::registerPattern( Node pat, TypeNode tpat ) {
     if( d_pattern_is_normal.find( pat )==d_pattern_is_normal.end() ){\r
       d_pattern_is_normal[pat] = true;\r
     }\r
+    if( d_pattern_is_relevant.find( pat )==d_pattern_is_relevant.end() ){\r
+      d_pattern_is_relevant[pat] = true;\r
+    }\r
   }\r
 }\r
 \r
@@ -1170,10 +1220,24 @@ bool ConjectureGenerator::isGeneralization( TNode patg, TNode pat, std::map< TNo
   }\r
 }\r
 \r
-void ConjectureGenerator::processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth ) {\r
-  if( d_waiting_conjectures.size()>=optFullCheckConjectures() ){\r
-    return;\r
+int ConjectureGenerator::calculateGeneralizationDepth( TNode n, std::vector< TNode >& fv ) {\r
+  if( n.getKind()==BOUND_VARIABLE ){\r
+    if( std::find( fv.begin(), fv.end(), n )==fv.end() ){\r
+      fv.push_back( n );\r
+      return 0;\r
+    }else{\r
+      return 1;\r
+    }\r
+  }else{\r
+    int depth = 1;\r
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+      depth += calculateGeneralizationDepth( n[i], fv );\r
+    }\r
+    return depth;\r
   }\r
+}\r
+\r
+void ConjectureGenerator::processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth ) {\r
   if( considerCandidateConjecture( lhs, rhs ) ){\r
     Trace("sg-conjecture") << "* Candidate conjecture : " << lhs << " == " << rhs << std::endl;\r
     Trace("sg-conjecture-debug") << "     LHS, RHS generalization depth : " << lhs_depth << ", " << rhs_depth << std::endl;\r
@@ -1194,26 +1258,19 @@ void ConjectureGenerator::processCandidateConjecture( TNode lhs, TNode rhs, unsi
       Trace("sg-conjecture-debug") << std::endl;\r
       Trace("sg-conjecture-debug") << "     unknown = " << d_subs_unkCount << std::endl;\r
     }\r
-    Assert( getUniversalRepresentative( rhs )==rhs );\r
-    Assert( getUniversalRepresentative( lhs )==lhs );\r
-    //make universal quantified formula\r
-    Assert( std::find( d_eq_conjectures[lhs].begin(), d_eq_conjectures[lhs].end(), rhs )==d_eq_conjectures[lhs].end() );\r
-    d_eq_conjectures[lhs].push_back( rhs );\r
-    d_eq_conjectures[rhs].push_back( lhs );\r
-    std::vector< Node > bvs;\r
-    for( std::map< TypeNode, unsigned >::iterator it = d_pattern_var_id[lhs].begin(); it != d_pattern_var_id[lhs].end(); ++it ){\r
-      for( unsigned i=0; i<=it->second; i++ ){\r
-        bvs.push_back( getFreeVar( it->first, i ) );\r
-      }\r
-    }\r
-    Node bvl = NodeManager::currentNM()->mkNode( BOUND_VAR_LIST, bvs );\r
-    Node conj = NodeManager::currentNM()->mkNode( FORALL, bvl, lhs.eqNode( rhs ) );\r
-    conj = Rewriter::rewrite( conj );\r
-    d_waiting_conjectures.push_back( conj );\r
+    //Assert( getUniversalRepresentative( rhs )==rhs );\r
+    //Assert( getUniversalRepresentative( lhs )==lhs );\r
+    d_waiting_conjectures_lhs.push_back( lhs );\r
+    d_waiting_conjectures_rhs.push_back( rhs );\r
+    d_waiting_conjectures[lhs].push_back( rhs );\r
+    d_waiting_conjectures[rhs].push_back( lhs );\r
   }\r
 }\r
 \r
 bool ConjectureGenerator::considerCandidateConjecture( TNode lhs, TNode rhs ) {\r
+  if( lhs.getType()!=rhs.getType() ){\r
+    std::cout << "BAD TYPE" << std::endl;\r
+  }\r
   Trace("sg-cconj-debug") << "Consider candidate conjecture : " << lhs << " == " << rhs << "?" << std::endl;\r
   if( lhs==rhs ){\r
     Trace("sg-cconj-debug") << "  -> trivial." << std::endl;\r
@@ -1238,17 +1295,28 @@ bool ConjectureGenerator::considerCandidateConjecture( TNode lhs, TNode rhs ) {
         return false;\r
       }\r
     }\r
+\r
     //currently active conjecture?\r
     std::map< Node, std::vector< Node > >::iterator iteq = d_eq_conjectures.find( lhs );\r
     if( iteq!=d_eq_conjectures.end() ){\r
       if( std::find( iteq->second.begin(), iteq->second.end(), rhs )!=iteq->second.end() ){\r
+        Trace("sg-cconj-debug") << "  -> this conjecture is already active." << std::endl;\r
+        return false;\r
+      }\r
+    }\r
+    //current a waiting conjecture?\r
+    std::map< Node, std::vector< Node > >::iterator itw = d_waiting_conjectures.find( lhs );\r
+    if( itw!=d_waiting_conjectures.end() ){\r
+      if( std::find( itw->second.begin(), itw->second.end(), rhs )!=itw->second.end() ){\r
         Trace("sg-cconj-debug") << "  -> already are considering this conjecture." << std::endl;\r
         return false;\r
       }\r
     }\r
+\r
+\r
     Trace("sg-cconj") << "Consider possible candidate conjecture : " << lhs << " == " << rhs << "?" << std::endl;\r
     //find witness for counterexample, if possible\r
-    if( optFilterConfirmation() || optFilterFalsification() ){\r
+    if( options::conjectureFilterModel() && ( optFilterConfirmation() || optFilterFalsification() ) ){\r
       Assert( d_rel_pattern_var_sum.find( lhs )!=d_rel_pattern_var_sum.end() );\r
       Trace("sg-cconj-debug") << "Notify substitutions over " << d_rel_pattern_var_sum[lhs] << " variables." << std::endl;\r
       std::map< TNode, TNode > subs;\r
@@ -1266,12 +1334,12 @@ bool ConjectureGenerator::considerCandidateConjecture( TNode lhs, TNode rhs ) {
           return false;\r
         }\r
       }\r
-      if( optFilterConfirmationDomain() ){\r
+      if( optFilterConfirmationDomainThreshold()>0 ){\r
         std::vector< TNode > vars;\r
         std::vector< TNode > subs;\r
         for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){\r
           Assert( d_pattern_fun_id[lhs].find( it->first )!=d_pattern_fun_id[lhs].end() );\r
-          unsigned req = d_pattern_fun_id[lhs][it->first];\r
+          unsigned req = optFilterConfirmationDomainThreshold() + (d_pattern_fun_id[lhs][it->first]-1);\r
           std::map< TNode, unsigned >::iterator itrf = d_pattern_fun_id[rhs].find( it->first );\r
           if( itrf!=d_pattern_fun_id[rhs].end() ){\r
             req = itrf->second>req ? itrf->second : req;\r
@@ -1285,43 +1353,18 @@ bool ConjectureGenerator::considerCandidateConjecture( TNode lhs, TNode rhs ) {
             subs.push_back( it->second[0] );\r
           }\r
         }\r
-        if( optFilterConfirmationNonCanonical() && !vars.empty() ){\r
-          Node slhs = lhs.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );\r
-          Node srhs = rhs.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );\r
-          TNode slhsr = getUniversalRepresentative( slhs, true );\r
-          TNode srhsr = getUniversalRepresentative( srhs, true );\r
-          if( areUniversalEqual( slhsr, srhsr ) ){\r
-            Trace("sg-cconj") << "  -> all ground witnesses can be proven by other theorems." << std::endl;\r
-            return false;\r
-          }else{\r
-            Trace("sg-cconj-debug") << "Checked if " << slhsr << " and " << srhsr << " were equal." << std::endl;\r
-          }\r
-        }\r
       }\r
-    }\r
-\r
-    Trace("sg-cconj") << "  -> SUCCESS." << std::endl;\r
-    if( optFilterConfirmation() || optFilterFalsification() ){\r
+      Trace("sg-cconj") << "  -> SUCCESS." << std::endl;\r
       Trace("sg-cconj") << "     confirmed = " << d_subs_confirmCount << ", #witnesses range = " << d_subs_confirmWitnessRange.size() << "." << std::endl;\r
       for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){\r
         Trace("sg-cconj") << "     #witnesses for " << it->first << " : " << it->second.size() << std::endl;\r
       }\r
     }\r
 \r
-    /*\r
-    if( getUniversalRepresentative( lhs )!=lhs ){\r
-      std::cout << "bad universal representative LHS : " << lhs << " " << getUniversalRepresentative( lhs ) << std::endl;\r
-      exit(0);\r
-    }\r
-    if( getUniversalRepresentative( rhs )!=rhs ){\r
-      std::cout << "bad universal representative RHS : " << rhs << " " << getUniversalRepresentative( rhs ) << std::endl;\r
-      exit(0);\r
-    }\r
-    */\r
-\r
     //check if still canonical representation (should be, but for efficiency this is not guarenteed)\r
-    if( getUniversalRepresentative( lhs )!=lhs || getUniversalRepresentative( rhs )!=rhs ){\r
+    if( options::conjectureFilterCanonical() && ( getUniversalRepresentative( lhs )!=lhs || getUniversalRepresentative( rhs )!=rhs ) ){\r
       Trace("sg-cconj") << "  -> after processing, not canonical." << std::endl;\r
+      return false;\r
     }\r
 \r
     return true;\r
@@ -1360,20 +1403,13 @@ bool ConjectureGenerator::notifySubstitution( TNode glhs, std::map< TNode, TNode
             }else{\r
               d_subs_unkCount++;\r
               if( optFilterUnknown() ){\r
+                Trace("sg-cconj-debug") << "...ground substitution giving terms that are neither equal nor disequal." << std::endl;\r
                 return false;\r
               }\r
             }\r
           }\r
         }\r
       }\r
-        /*\r
-      if( getEqualityEngine()->areDisequal( glhs, grhs, false ) ){\r
-        Trace("sg-cconj-debug") << "..." << glhs << " and " << grhs << " are disequal." << std::endl;\r
-        return false;\r
-      }else{\r
-        Trace("sg-cconj-debug") << "..." << glhs << " and " << grhs << " are not disequal." << std::endl;\r
-      }\r
-      */\r
     }else{\r
       Trace("sg-cconj-witness") << "  Witnessed " << glhs << " == " << grhs << ", substutition is : " << std::endl;\r
       for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
@@ -1432,7 +1468,9 @@ bool TermGenerator::getNextTerm( ConjectureGenerator * s, unsigned depth ) {
         //check allocating new variable\r
         d_status++;\r
         d_status_num = -1;\r
-        s->d_tg_gdepth++;\r
+        if( s->d_gen_relevant_terms ){\r
+          s->d_tg_gdepth++;\r
+        }\r
         return getNextTerm( s, depth );\r
       }\r
     }else{\r
@@ -1453,7 +1491,9 @@ bool TermGenerator::getNextTerm( ConjectureGenerator * s, unsigned depth ) {
       Trace("sg-gen-tg-debug2") << this << "...consider other var #" << d_status_num << std::endl;\r
       return s->considerCurrentTerm() ? true : getNextTerm( s, depth );\r
     }else{\r
-      s->d_tg_gdepth--;\r
+      if( s->d_gen_relevant_terms ){\r
+        s->d_tg_gdepth--;\r
+      }\r
       d_status++;\r
       return getNextTerm( s, depth );\r
     }\r
@@ -1487,7 +1527,7 @@ bool TermGenerator::getNextTerm( ConjectureGenerator * s, unsigned depth ) {
       return getNextTerm( s, depth );\r
     }else if( d_status_child_num==(int)s->d_func_args[f].size() ){\r
       d_status_child_num--;\r
-      return s->considerTermCanon( d_id ) ? true : getNextTerm( s, depth );\r
+      return s->considerCurrentTermCanon( d_id ) ? true : getNextTerm( s, depth );\r
       //return true;\r
     }else{\r
       Assert( d_status_child_num<(int)s->d_func_args[f].size() );\r
@@ -1695,21 +1735,35 @@ unsigned TermGenerator::getDepth( ConjectureGenerator * s ) {
   }\r
 }\r
 \r
-unsigned TermGenerator::getGeneralizationDepth( ConjectureGenerator * s ) {\r
+unsigned TermGenerator::calculateGeneralizationDepth( ConjectureGenerator * s, std::map< TypeNode, std::vector< int > >& fvs ) {\r
   if( d_status==5 ){\r
     unsigned sum = 1;\r
     for( unsigned i=0; i<d_children.size(); i++ ){\r
-      sum += s->d_tg_alloc[d_children[i]].getGeneralizationDepth( s );\r
+      sum += s->d_tg_alloc[d_children[i]].calculateGeneralizationDepth( s, fvs );\r
     }\r
     return sum;\r
-  }else if( d_status==2 ){\r
-    return 1;\r
   }else{\r
-    Assert( d_status==1 );\r
+    Assert( d_status==2 || d_status==1 );\r
+    std::map< TypeNode, std::vector< int > >::iterator it = fvs.find( d_typ );\r
+    if( it!=fvs.end() ){\r
+      if( std::find( it->second.begin(), it->second.end(), d_status_num )!=it->second.end() ){\r
+        return 1;\r
+      }\r
+    }\r
+    fvs[d_typ].push_back( d_status_num );\r
     return 0;\r
   }\r
 }\r
 \r
+unsigned TermGenerator::getGeneralizationDepth( ConjectureGenerator * s ) {\r
+  //if( s->d_gen_relevant_terms ){\r
+  //  return s->d_tg_gdepth;\r
+  //}else{\r
+    std::map< TypeNode, std::vector< int > > fvs;\r
+    return calculateGeneralizationDepth( s, fvs );\r
+  //}\r
+}\r
+\r
 Node TermGenerator::getTerm( ConjectureGenerator * s ) {\r
   if( d_status==1 || d_status==2 ){\r
     Assert( !d_typ.isNull() );\r
@@ -1811,8 +1865,9 @@ void TheoremIndex::addTheoremNode( TNode curr, std::vector< TNode >& lhs_v, std:
     d_children[curr.getOperator()].addTheorem( lhs_v, lhs_arg, rhs );\r
   }else{\r
     Assert( curr.getKind()==kind::BOUND_VARIABLE );\r
-    Assert( d_var.isNull() || d_var==curr );\r
-    d_var = curr;\r
+    TypeNode tn = curr.getType();\r
+    Assert( d_var[tn].isNull() || d_var[tn]==curr );\r
+    d_var[tn] = curr;\r
     d_children[curr].addTheorem( lhs_v, lhs_arg, rhs );\r
   }\r
 }\r
@@ -1855,26 +1910,27 @@ void TheoremIndex::getEquivalentTermsNode( Node curr, std::vector< TNode >& n_v,
     }\r
     Trace("thm-db-debug") << "...done check based on operator" << std::endl;\r
   }\r
-  if( !d_var.isNull() ){\r
-    Trace("thm-db-debug") << "Check for substitution with " << d_var << "..." << std::endl;\r
-    if( curr.getType()==d_var.getType() ){\r
-      //add to substitution if possible\r
-      bool success = false;\r
-      std::map< TNode, TNode >::iterator it = smap.find( d_var );\r
-      if( it==smap.end() ){\r
-        smap[d_var] = curr;\r
-        vars.push_back( d_var );\r
-        subs.push_back( curr );\r
-        success = true;\r
-      }else if( it->second==curr ){\r
-        success = true;\r
-      }else{\r
-        //also check modulo equality (in universal equality engine)\r
-      }\r
-      Trace("thm-db-debug") << "...check for substitution with " << d_var << ", success = " << success << "." << std::endl;\r
-      if( success ){\r
-        d_children[d_var].getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );\r
-      }\r
+  TypeNode tn = curr.getType();\r
+  std::map< TypeNode, TNode >::iterator itt = d_var.find( tn );\r
+  if( itt!=d_var.end() ){\r
+    Trace("thm-db-debug") << "Check for substitution with " << itt->second << "..." << std::endl;\r
+    Assert( curr.getType()==itt->second.getType() );\r
+    //add to substitution if possible\r
+    bool success = false;\r
+    std::map< TNode, TNode >::iterator it = smap.find( itt->second );\r
+    if( it==smap.end() ){\r
+      smap[itt->second] = curr;\r
+      vars.push_back( itt->second );\r
+      subs.push_back( curr );\r
+      success = true;\r
+    }else if( it->second==curr ){\r
+      success = true;\r
+    }else{\r
+      //also check modulo equality (in universal equality engine)\r
+    }\r
+    Trace("thm-db-debug") << "...check for substitution with " << itt->second << ", success = " << success << "." << std::endl;\r
+    if( success ){\r
+      d_children[itt->second].getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );\r
     }\r
   }\r
 }\r
@@ -1903,12 +1959,14 @@ bool ConjectureGenerator::optReqDistinctVarPatterns() { return false; }
 bool ConjectureGenerator::optFilterFalsification() { return true; }\r
 bool ConjectureGenerator::optFilterUnknown() { return true; }  //may change\r
 bool ConjectureGenerator::optFilterConfirmation() { return true; }\r
-bool ConjectureGenerator::optFilterConfirmationDomain() { return true; }\r
-bool ConjectureGenerator::optFilterConfirmationOnlyGround() { return true; }//false; }\r
-bool ConjectureGenerator::optFilterConfirmationNonCanonical() { return false; }//true; }\r
+unsigned ConjectureGenerator::optFilterConfirmationDomainThreshold() { return 1; }\r
+bool ConjectureGenerator::optFilterConfirmationOnlyGround() { return true; }\r
+bool ConjectureGenerator::optFilterConfirmationNonCanonical() { return false; }\r
 unsigned ConjectureGenerator::optFullCheckFrequency() { return 1; }\r
 unsigned ConjectureGenerator::optFullCheckConjectures() { return options::conjectureGenPerRound(); }\r
 \r
+bool ConjectureGenerator::optStatsOnly() { return false; }\r
+\r
 }\r
 \r
 \r
old mode 100644 (file)
new mode 100755 (executable)
index 93cda73..9e63255
@@ -68,6 +68,8 @@ public:
 \r
 class TermGenerator\r
 {\r
+private:\r
+  unsigned calculateGeneralizationDepth( ConjectureGenerator * s, std::map< TypeNode, std::vector< int > >& fvs );\r
 public:\r
   TermGenerator(){}\r
   TypeNode d_typ;\r
@@ -119,7 +121,7 @@ private:
                                std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,\r
                                std::vector< Node >& terms );\r
 public:\r
-  TNode d_var;\r
+  std::map< TypeNode, TNode > d_var;\r
   std::map< TNode, TheoremIndex > d_children;\r
   std::vector< Node > d_terms;\r
 \r
@@ -137,7 +139,7 @@ public:
     getEquivalentTermsNode( n, nv, na, smap, vars, subs, terms );\r
   }\r
   void clear(){\r
-    d_var = Node::null();\r
+    d_var.clear();\r
     d_children.clear();\r
     d_terms.clear();\r
   }\r
@@ -199,8 +201,6 @@ private:
   void eqNotifyPostMerge(TNode t1, TNode t2);\r
   /** called when two equivalence classes are made disequal */\r
   void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);\r
-  /** add pending universal terms, merge equivalence classes */\r
-  void doPendingAddUniversalTerms();\r
   /** are universal equal */\r
   bool areUniversalEqual( TNode n1, TNode n2 );\r
   /** are universal disequal */\r
@@ -223,7 +223,10 @@ private:  //information regarding the conjectures
   /** list of all conjectures */\r
   std::vector< Node > d_conjectures;\r
   /** list of all waiting conjectures */\r
-  std::vector< Node > d_waiting_conjectures;\r
+  std::vector< Node > d_waiting_conjectures_lhs;\r
+  std::vector< Node > d_waiting_conjectures_rhs;\r
+  /** map of currently considered equality conjectures */\r
+  std::map< Node, std::vector< Node > > d_waiting_conjectures;\r
   /** map of equality conjectures */\r
   std::map< Node, std::vector< Node > > d_eq_conjectures;\r
   /** currently existing conjectures in equality engine */\r
@@ -267,7 +270,8 @@ private:  //information regarding the terms
   // # duplicated variables\r
   std::map< TNode, unsigned > d_pattern_var_duplicate;\r
   // is normal pattern?  (variables allocated in canonical way left to right)\r
-  std::map< TNode, bool > d_pattern_is_normal;\r
+  std::map< TNode, int > d_pattern_is_normal;\r
+  std::map< TNode, int > d_pattern_is_relevant;\r
   // patterns to a count of # operators (variables and functions)\r
   std::map< TNode, std::map< TNode, unsigned > > d_pattern_fun_id;\r
   // term size\r
@@ -278,7 +282,6 @@ private:  //information regarding the terms
   // add pattern\r
   void registerPattern( Node pat, TypeNode tpat );\r
 private: //for debugging\r
-  unsigned d_rel_term_count;\r
   std::map< TNode, unsigned > d_em;\r
 public:  //environment for term enumeration\r
   //the current number of enumerated variables per type\r
@@ -288,7 +291,7 @@ public:  //environment for term enumeration
   //the functions we can currently generate\r
   std::map< TypeNode, std::vector< TNode > > d_typ_tg_funcs;\r
   //the equivalence classes (if applicable) that match the currently generated term\r
-  bool d_use_ccand_eqc;\r
+  bool d_gen_relevant_terms;\r
   std::vector< std::vector< TNode > > d_ccand_eqc[2];\r
   //the term generation objects\r
   unsigned d_tg_id;\r
@@ -303,7 +306,7 @@ public:  //environment for term enumeration
   unsigned getNumTgFuncs( TypeNode tn );\r
   TNode getTgFunc( TypeNode tn, unsigned i );\r
   bool considerCurrentTerm();\r
-  bool considerTermCanon( unsigned tg_id );\r
+  bool considerCurrentTermCanon( unsigned tg_id );\r
   void changeContext( bool add );\r
 public:  //for generalization\r
   //generalizations\r
@@ -312,6 +315,8 @@ public:  //for generalization
     return isGeneralization( patg, pat, subs );\r
   }\r
   bool isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs );\r
+  // get generalization depth\r
+  int calculateGeneralizationDepth( TNode n, std::vector< TNode >& fv );\r
 public:  //for property enumeration\r
   //process this candidate conjecture\r
   void processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth );\r
@@ -344,6 +349,7 @@ private:  //information about ground equivalence classes
   Node getGroundEqc( TNode r );\r
   bool isGroundEqc( TNode r );\r
   bool isGroundTerm( TNode n );\r
+  bool isRelevantFunc( Node f );\r
   // count of full effort checks\r
   unsigned d_fullEffortCount;\r
 public:\r
@@ -366,11 +372,13 @@ private:
   bool optFilterFalsification();\r
   bool optFilterUnknown();\r
   bool optFilterConfirmation();\r
-  bool optFilterConfirmationDomain();\r
+  unsigned optFilterConfirmationDomainThreshold();\r
   bool optFilterConfirmationOnlyGround();\r
   bool optFilterConfirmationNonCanonical();   //filter if all ground confirmations are non-canonical\r
   unsigned optFullCheckFrequency();\r
   unsigned optFullCheckConjectures();\r
+  \r
+  bool optStatsOnly();\r
 };\r
 \r
 \r
index d30e5de4a326cb0c21ffcc2ec1bf085402baf006..efe1b109834d656b58653fb79e988dfcbbc4a327 100644 (file)
@@ -160,6 +160,13 @@ option conjectureGen --conjecture-gen bool :read-write :default false
  generate candidate conjectures for inductive proofs
  
 option conjectureGenPerRound --conjecture-gen-per-round=N int :default 1
- number of conjectures to generate per instantiation round
-
+ number of conjectures to generate per instantiation round 
+option conjectureNoFilter --conjecture-no-filter bool :default false
+ do not filter conjectures
+option conjectureFilterActiveTerms --conjecture-filter-active-terms bool :read-write :default true
+ filter based on active terms
+option conjectureFilterCanonical --conjecture-filter-canonical bool :read-write :default true
+ filter based on canonicity
+option conjectureFilterModel --conjecture-filter-model bool :read-write :default true
+ filter based on model
 endmodule
index cf68c198eaf985209fa508b8cba25ac2ce8e9614..0d85eae8331a5231f04bf47c6a4be2046c01fc4a 100644 (file)
@@ -227,6 +227,36 @@ TNode TermDb::evaluateTerm( TNode n, std::map< TNode, TNode >& subs, bool subsRe
   }
 }
 
+TNode TermDb::evaluateTerm( TNode n ) {
+  eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+  if( ee->hasTerm( n ) ){
+    return ee->getRepresentative( n );
+  }else if( n.getKind()!=BOUND_VARIABLE ){
+    if( n.hasOperator() ){
+      TNode f = getOperator( n );
+      if( !f.isNull() ){
+        std::vector< TNode > args;
+        for( unsigned i=0; i<n.getNumChildren(); i++ ){
+          TNode c = evaluateTerm( n[i] );
+          if( c.isNull() ){
+            return TNode::null();
+          }
+          args.push_back( c );
+        }
+        TNode nn = d_func_map_trie[f].existsTerm( args );
+        if( !nn.isNull() ){
+          if( ee->hasTerm( nn ) ){
+            return ee->getRepresentative( nn );
+          }else{
+            //Assert( false );
+          }
+        }
+      }
+    }
+  }
+  return TNode::null();
+}
+
 bool TermDb::isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool pol ) {
   Trace("term-db-eval") << "Check entailed : " << n << ", pol = " << pol << std::endl;
   Assert( n.getType().isBoolean() );
index 504ecd6671984f374da397ec48ed8fa64a2ba745..91ad0135be8d6034d7eaf7a974186012c77f0cd9 100644 (file)
@@ -145,6 +145,8 @@ public:
    * subsRep is whether subs contains only representatives
    */
   TNode evaluateTerm( TNode n, std::map< TNode, TNode >& subs, bool subsRep );
+  /** same as above, but without substitution */
+  TNode evaluateTerm( TNode n );
   /** is entailed (incomplete check) */
   bool isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool pol );
 public: