New module for generating candidate equality conjectures used in inductive proofs...
authorajreynol <andrew.j.reynolds@gmail.com>
Thu, 31 Jul 2014 10:49:28 +0000 (12:49 +0200)
committerajreynol <andrew.j.reynolds@gmail.com>
Thu, 31 Jul 2014 10:49:28 +0000 (12:49 +0200)
17 files changed:
src/Makefile.am
src/theory/quantifiers/conjecture_generator.cpp [new file with mode: 0644]
src/theory/quantifiers/conjecture_generator.h [new file with mode: 0644]
src/theory/quantifiers/first_order_model.cpp
src/theory/quantifiers/first_order_model.h
src/theory/quantifiers/inst_match_generator.cpp
src/theory/quantifiers/instantiation_engine.cpp
src/theory/quantifiers/modes.h
src/theory/quantifiers/options
src/theory/quantifiers/options_handlers.h
src/theory/quantifiers/quant_conflict_find.cpp [changed mode: 0644->0755]
src/theory/quantifiers/quant_conflict_find.h [changed mode: 0644->0755]
src/theory/quantifiers/quantifiers_rewriter.cpp
src/theory/quantifiers/term_database.cpp
src/theory/quantifiers/term_database.h
src/theory/quantifiers_engine.cpp
src/theory/quantifiers_engine.h

index 805ed6cb7f404c586cbe6bbb7883e4e5ea198736..908e3de6cedf4b53fc17d797888ddc78660346de 100644 (file)
@@ -327,6 +327,8 @@ libcvc4_la_SOURCES = \
        theory/quantifiers/ambqi_builder.cpp \
        theory/quantifiers/quant_conflict_find.h \
        theory/quantifiers/quant_conflict_find.cpp \
+       theory/quantifiers/conjecture_generator.h \
+       theory/quantifiers/conjecture_generator.cpp \
        theory/quantifiers/options_handlers.h \
        theory/arith/theory_arith_type_rules.h \
        theory/arith/type_enumerator.h \
diff --git a/src/theory/quantifiers/conjecture_generator.cpp b/src/theory/quantifiers/conjecture_generator.cpp
new file mode 100644 (file)
index 0000000..462738c
--- /dev/null
@@ -0,0 +1,2009 @@
+/*********************                                                        */\r
+/*! \file subgoal_generator.cpp\r
+ ** \verbatim\r
+ ** Original author: Andrew Reynolds\r
+ ** Major contributors: none\r
+ ** Minor contributors (to current version): none\r
+ ** This file is part of the CVC4 project.\r
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
+ ** See the file COPYING in the top-level source directory for licensing\r
+ ** information.\endverbatim\r
+ **\r
+ ** \brief conjecture generator class\r
+ **\r
+ **/\r
+\r
+#include "theory/quantifiers/conjecture_generator.h"\r
+#include "theory/theory_engine.h"\r
+#include "theory/quantifiers/options.h"\r
+#include "theory/quantifiers/term_database.h"\r
+#include "theory/quantifiers/trigger.h"\r
+#include "theory/quantifiers/first_order_model.h"\r
+\r
+using namespace CVC4;\r
+using namespace CVC4::kind;\r
+using namespace CVC4::theory;\r
+using namespace CVC4::theory::quantifiers;\r
+using namespace std;\r
+\r
+\r
+namespace CVC4 {\r
+\r
+void OpArgIndex::addTerm( ConjectureGenerator * s, TNode n, unsigned index ){\r
+  if( index==n.getNumChildren() ){\r
+    Assert( n.hasOperator() );\r
+    if( std::find( d_ops.begin(), d_ops.end(), n.getOperator() )==d_ops.end() ){\r
+      d_ops.push_back( n.getOperator() );\r
+      d_op_terms.push_back( n );\r
+    }\r
+  }else{\r
+    d_child[s->getTermDatabase()->d_arg_reps[n][index]].addTerm( s, n, index+1 );\r
+  }\r
+}\r
+\r
+Node OpArgIndex::getGroundTerm( ConjectureGenerator * s, std::vector< TNode >& args ) {\r
+  if( d_ops.empty() ){\r
+    for( std::map< TNode, OpArgIndex >::iterator it = d_child.begin(); it != d_child.end(); ++it ){\r
+      std::map< TNode, Node >::iterator itf = s->d_ground_eqc_map.find( it->first );\r
+      if( itf!=s->d_ground_eqc_map.end() ){\r
+        args.push_back( itf->second );\r
+        Node n = it->second.getGroundTerm( s, args );\r
+        args.pop_back();\r
+        if( !n.isNull() ){\r
+          return n;\r
+        }\r
+      }\r
+    }\r
+    return Node::null();\r
+  }else{\r
+    std::vector< TNode > args2;\r
+    args2.push_back( d_ops[0] );\r
+    args2.insert( args2.end(), args.begin(), args.end() );\r
+    return NodeManager::currentNM()->mkNode( d_op_terms[0].getKind(), args2 );\r
+  }\r
+}\r
+\r
+void OpArgIndex::getGroundTerms( ConjectureGenerator * s, std::vector< TNode >& terms ) {\r
+  terms.insert( terms.end(), d_op_terms.begin(), d_op_terms.end() );\r
+  for( std::map< TNode, OpArgIndex >::iterator it = d_child.begin(); it != d_child.end(); ++it ){\r
+    if( s->isGroundEqc( it->first ) ){\r
+      it->second.getGroundTerms( s, terms );\r
+    }\r
+  }\r
+}\r
+\r
+\r
+\r
+ConjectureGenerator::ConjectureGenerator( QuantifiersEngine * qe, context::Context* c ) : QuantifiersModule( qe ),\r
+d_notify( *this ),\r
+d_uequalityEngine(d_notify, c, "ConjectureGenerator::ee"),\r
+d_ee_conjectures( c ){\r
+  d_fullEffortCount = 0;\r
+  d_uequalityEngine.addFunctionKind( kind::APPLY_UF );\r
+  d_uequalityEngine.addFunctionKind( kind::APPLY_CONSTRUCTOR );\r
+  \r
+}\r
+\r
+void ConjectureGenerator::eqNotifyNewClass( TNode t ){\r
+  Trace("thm-ee-debug") << "UEE : new equivalence class " << t << std::endl;\r
+  d_upendingAdds.push_back( t );\r
+}\r
+\r
+void ConjectureGenerator::eqNotifyPreMerge(TNode t1, TNode t2) {\r
+  //get maintained representatives\r
+  TNode rt1 = t1;\r
+  TNode rt2 = t2;\r
+  std::map< Node, EqcInfo* >::iterator it1 = d_eqc_info.find( t1 );\r
+  if( it1!=d_eqc_info.end() && !it1->second->d_rep.get().isNull() ){\r
+    rt1 = it1->second->d_rep.get();\r
+  }\r
+  std::map< Node, EqcInfo* >::iterator it2 = d_eqc_info.find( t2 );\r
+  if( it2!=d_eqc_info.end() && !it2->second->d_rep.get().isNull() ){\r
+    rt2 = it2->second->d_rep.get();\r
+  }\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") << "      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
+  if( isUniversalLessThan( rt2, rt1 ) ){\r
+    EqcInfo * ei;\r
+    if( it1==d_eqc_info.end() ){\r
+      ei = getOrMakeEqcInfo( t1, true );\r
+    }else{\r
+      ei = it1->second;\r
+    }\r
+    ei->d_rep = t2;\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::eqNotifyPostMerge(TNode t1, TNode t2) {\r
+\r
+}\r
+\r
+void ConjectureGenerator::eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {\r
+  Trace("thm-ee-debug") << "UEE : disequality holds : " << t1 << " != " << t2 << std::endl;\r
+\r
+}\r
+\r
+\r
+ConjectureGenerator::EqcInfo::EqcInfo( context::Context* c ) : d_rep( c, Node::null() ){\r
+\r
+}\r
+\r
+ConjectureGenerator::EqcInfo* ConjectureGenerator::getOrMakeEqcInfo( TNode n, bool doMake ) {\r
+  //Assert( getUniversalRepresentative( n )==n );\r
+  std::map< Node, EqcInfo* >::iterator eqc_i = d_eqc_info.find( n );\r
+  if( eqc_i!=d_eqc_info.end() ){\r
+    return eqc_i->second;\r
+  }else if( doMake ){\r
+    EqcInfo* ei = new EqcInfo( d_quantEngine->getSatContext() );\r
+    d_eqc_info[n] = ei;\r
+    return ei;\r
+  }else{\r
+    return NULL;\r
+  }\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 from conjecture 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
+    }\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::setUniversalRelevant( TNode n ) {\r
+  //add pattern information\r
+  registerPattern( n, n.getType() );\r
+  d_urelevant_terms[n] = true;\r
+  for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+    setUniversalRelevant( n[i] );\r
+  }\r
+}\r
+\r
+bool ConjectureGenerator::isUniversalLessThan( TNode rt1, TNode rt2 ) {\r
+  //prefer the one that is (normal, smaller) lexographically\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
+    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
+      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
+  return false;\r
+}\r
+\r
+\r
+bool ConjectureGenerator::isReportedCanon( TNode n ) { \r
+  return std::find( d_ue_canon.begin(), d_ue_canon.end(), n )==d_ue_canon.end(); \r
+}\r
+\r
+void ConjectureGenerator::markReportedCanon( TNode n ) {\r
+  if( !isReportedCanon( n ) ){\r
+    d_ue_canon.push_back( n );\r
+  }\r
+}\r
+\r
+bool ConjectureGenerator::areUniversalEqual( TNode n1, TNode n2 ) {\r
+  return n1==n2 || ( d_uequalityEngine.hasTerm( n1 ) && d_uequalityEngine.hasTerm( n2 ) && d_uequalityEngine.areEqual( n1, n2 ) );\r
+}\r
+\r
+bool ConjectureGenerator::areUniversalDisequal( TNode n1, TNode n2 ) {\r
+  return n1!=n2 && d_uequalityEngine.hasTerm( n1 ) && d_uequalityEngine.hasTerm( n2 ) && d_uequalityEngine.areDisequal( n1, n2, false );\r
+}\r
+\r
+TNode ConjectureGenerator::getUniversalRepresentative( TNode n, bool add ) {\r
+  if( add ){\r
+    if( d_urelevant_terms.find( n )==d_urelevant_terms.end() ){\r
+      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
+    }\r
+  }\r
+  if( d_uequalityEngine.hasTerm( n ) ){\r
+    Node r = d_uequalityEngine.getRepresentative( n );\r
+    EqcInfo * ei = getOrMakeEqcInfo( r );\r
+    if( ei && !ei->d_rep.get().isNull() ){\r
+      return ei->d_rep.get();\r
+    }else{\r
+      return r;\r
+    }\r
+  }else{\r
+    return n;\r
+  }\r
+}\r
+\r
+eq::EqualityEngine * ConjectureGenerator::getEqualityEngine() {\r
+  return d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();\r
+}\r
+\r
+bool ConjectureGenerator::areEqual( TNode n1, TNode n2 ) {\r
+  eq::EqualityEngine * ee = getEqualityEngine();\r
+  return n1==n2 || ( ee->hasTerm( n1 ) && ee->hasTerm( n2 ) && ee->areEqual( n1, n2 ) );\r
+}\r
+\r
+bool ConjectureGenerator::areDisequal( TNode n1, TNode n2 ) {\r
+  eq::EqualityEngine * ee = getEqualityEngine();\r
+  return n1!=n2 && ee->hasTerm( n1 ) && ee->hasTerm( n2 ) && ee->areDisequal( n1, n2, false );\r
+}\r
+\r
+TNode ConjectureGenerator::getRepresentative( TNode n ) {\r
+  eq::EqualityEngine * ee = getEqualityEngine();\r
+  if( ee->hasTerm( n ) ){\r
+    return ee->getRepresentative( n );\r
+  }else{\r
+    return n;\r
+  }\r
+}\r
+\r
+TermDb * ConjectureGenerator::getTermDatabase() {\r
+  return d_quantEngine->getTermDatabase();\r
+}\r
+\r
+bool ConjectureGenerator::needsCheck( Theory::Effort e ) {\r
+  if( e==Theory::EFFORT_FULL ){\r
+    //d_fullEffortCount++;\r
+    return d_fullEffortCount%optFullCheckFrequency()==0;\r
+  }else{\r
+    return false;\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::reset_round( Theory::Effort e ) {\r
+\r
+}\r
+\r
+Node ConjectureGenerator::getFreeVar( TypeNode tn, unsigned i ) {\r
+  Assert( !tn.isNull() );\r
+  while( d_free_var[tn].size()<=i ){\r
+    std::stringstream oss;\r
+    oss << tn;\r
+    std::stringstream os;\r
+    os << oss.str()[0] << i;\r
+    Node x = NodeManager::currentNM()->mkBoundVar( os.str().c_str(), tn );\r
+    d_free_var_num[x] = d_free_var[tn].size();\r
+    d_free_var[tn].push_back( x );\r
+  }\r
+  return d_free_var[tn][i];\r
+}\r
+\r
+\r
+\r
+Node ConjectureGenerator::getCanonicalTerm( TNode n, std::map< TypeNode, unsigned >& var_count, std::map< TNode, TNode >& subs ) {\r
+  Trace("ajr-temp") << "get canonical term " << n << " " << n.getKind() << " " << n.hasOperator() << std::endl;\r
+  if( n.getKind()==BOUND_VARIABLE ){\r
+    std::map< TNode, TNode >::iterator it = subs.find( n );\r
+    if( it==subs.end() ){\r
+      TypeNode tn = n.getType();\r
+      //allocate variable\r
+      unsigned vn = var_count[tn];\r
+      var_count[tn]++;\r
+      subs[n] = getFreeVar( tn, vn );\r
+      return subs[n];\r
+    }else{\r
+      return it->second;\r
+    }\r
+  }else{\r
+    std::vector< Node > children;\r
+    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
+          return Node::null();\r
+        }\r
+        children.push_back( op );\r
+      }else{\r
+        return Node::null();\r
+      }\r
+    }\r
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+      Node cn = getCanonicalTerm( n[i], var_count, subs );\r
+      if( cn.isNull() ){\r
+        return Node::null();\r
+      }else{\r
+        children.push_back( cn );\r
+      }\r
+    }\r
+    return NodeManager::currentNM()->mkNode( n.getKind(), children );\r
+  }\r
+}\r
+\r
+bool ConjectureGenerator::isHandledTerm( TNode n ){\r
+  return !n.getAttribute(NoMatchAttribute()) && inst::Trigger::isAtomicTrigger( n ) && ( n.getKind()!=APPLY_UF || n.getOperator().getKind()!=SKOLEM );\r
+}\r
+\r
+Node ConjectureGenerator::getGroundEqc( TNode r ) {\r
+  std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );\r
+  return it!=d_ground_eqc_map.end() ? it->second : Node::null();\r
+}\r
+\r
+bool ConjectureGenerator::isGroundEqc( TNode r ) {\r
+  return d_ground_eqc_map.find( r )!=d_ground_eqc_map.end();\r
+}\r
+\r
+bool ConjectureGenerator::isGroundTerm( TNode n ) {\r
+  return std::find( d_ground_terms.begin(), d_ground_terms.end(), n )!=d_ground_terms.end();\r
+}\r
+\r
+void ConjectureGenerator::check( Theory::Effort e ) {\r
+  if( e==Theory::EFFORT_FULL ){\r
+    bool doCheck = d_fullEffortCount%optFullCheckFrequency()==0;\r
+    if( d_quantEngine->hasAddedLemma() ){\r
+     doCheck = false;\r
+    }else{\r
+      d_fullEffortCount++;\r
+    }\r
+    if( doCheck ){\r
+      Trace("sg-engine") << "---Subgoal engine, effort = " << e << "--- " << std::endl;\r
+      eq::EqualityEngine * ee = getEqualityEngine();\r
+\r
+      Trace("sg-proc") << "Get eq classes..." << std::endl;\r
+      d_op_arg_index.clear();\r
+      d_ground_eqc_map.clear();\r
+      d_bool_eqc[0] = Node::null();\r
+      d_bool_eqc[1] = Node::null();\r
+      std::vector< TNode > eqcs;\r
+      d_em.clear();\r
+      eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( ee );\r
+      while( !eqcs_i.isFinished() ){\r
+        TNode r = (*eqcs_i);\r
+        eqcs.push_back( r );\r
+        if( r.getType().isBoolean() ){\r
+          if( areEqual( r, getTermDatabase()->d_true ) ){\r
+            d_ground_eqc_map[r] = getTermDatabase()->d_true;\r
+            d_bool_eqc[0] = r;\r
+          }else if( areEqual( r, getTermDatabase()->d_false ) ){\r
+            d_ground_eqc_map[r] = getTermDatabase()->d_false;\r
+            d_bool_eqc[1] = r;\r
+          }\r
+        }\r
+        d_em[r] = eqcs.size();\r
+        eq::EqClassIterator ieqc_i = eq::EqClassIterator( r, ee );\r
+        while( !ieqc_i.isFinished() ){\r
+          TNode n = (*ieqc_i);\r
+          if( isHandledTerm( n ) ){\r
+            d_op_arg_index[r].addTerm( this, n );\r
+          }\r
+          ++ieqc_i;\r
+        }\r
+        ++eqcs_i;\r
+      }\r
+      Assert( !d_bool_eqc[0].isNull() );\r
+      Assert( !d_bool_eqc[1].isNull() );\r
+      d_urelevant_terms.clear();\r
+      Trace("sg-proc") << "...done get eq classes" << std::endl;\r
+\r
+      Trace("sg-proc") << "Determine ground EQC..." << std::endl;\r
+      bool success;\r
+      do{\r
+        success = false;\r
+        for( unsigned i=0; i<eqcs.size(); i++ ){\r
+          TNode r = eqcs[i];\r
+          if( d_ground_eqc_map.find( r )==d_ground_eqc_map.end() ){\r
+            std::vector< TNode > args;\r
+            Trace("sg-pat-debug") << "******* Get ground term for " << r << std::endl;\r
+            Node n;\r
+            if( getTermDatabase()->isInductionTerm( r ) ){\r
+              n = d_op_arg_index[r].getGroundTerm( this, args );\r
+            }else{\r
+              n = r;\r
+            }\r
+            if( !n.isNull() ){\r
+              Trace("sg-pat") << "Ground term for eqc " << r << " : " << std::endl;\r
+              Trace("sg-pat") << "   " << n << std::endl;\r
+              d_ground_eqc_map[r] = n;\r
+              success = true;\r
+            }else{\r
+              Trace("sg-pat-debug") << "...could not find ground term." << std::endl;\r
+            }\r
+          }\r
+        }\r
+      }while( success );\r
+      //also get ground terms\r
+      d_ground_terms.clear();\r
+      for( unsigned i=0; i<eqcs.size(); i++ ){\r
+        TNode r = eqcs[i];\r
+        d_op_arg_index[r].getGroundTerms( this, d_ground_terms );\r
+      }\r
+      Trace("sg-proc") << "...done determine ground EQC" << std::endl;\r
+\r
+      //debug printing\r
+      if( Trace.isOn("sg-gen-eqc") ){\r
+        for( unsigned i=0; i<eqcs.size(); i++ ){\r
+          TNode r = eqcs[i];\r
+          //print out members\r
+          bool firstTime = true;\r
+          bool isFalse = areEqual( r, getTermDatabase()->d_false );\r
+          eq::EqClassIterator eqc_i = eq::EqClassIterator( r, ee );\r
+          while( !eqc_i.isFinished() ){\r
+            TNode n = (*eqc_i);\r
+            if( !n.getAttribute(NoMatchAttribute()) && ( n.getKind()!=EQUAL || isFalse ) ){\r
+              if( firstTime ){\r
+                Trace("sg-gen-eqc") << "e" << d_em[r] << " : { " << std::endl;\r
+                firstTime = false;\r
+              }\r
+              if( n.hasOperator() ){\r
+                Trace("sg-gen-eqc") << "   (" << n.getOperator();\r
+                getTermDatabase()->computeArgReps( n );\r
+                for( unsigned i=0; i<getTermDatabase()->d_arg_reps[n].size(); i++ ){\r
+                  Trace("sg-gen-eqc") << " e" << d_em[getTermDatabase()->d_arg_reps[n][i]];\r
+                }\r
+                Trace("sg-gen-eqc") << ") :: " << n << std::endl;\r
+              }else{\r
+                Trace("sg-gen-eqc") << "   " << n << std::endl;\r
+              }\r
+            }\r
+            ++eqc_i;\r
+          }\r
+          if( !firstTime ){\r
+            Trace("sg-gen-eqc") << "}" << std::endl;\r
+            //print out ground term\r
+            std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );\r
+            if( it!=d_ground_eqc_map.end() ){\r
+              Trace("sg-gen-eqc") << "- Ground term : " << it->second << std::endl;\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      Trace("sg-proc") << "Compute relevant eqc..." << std::endl;\r
+      d_relevant_eqc[0].clear();\r
+      d_relevant_eqc[1].clear();\r
+      for( unsigned i=0; i<eqcs.size(); i++ ){\r
+        TNode r = eqcs[i];\r
+        std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );\r
+        unsigned index = 1;\r
+        if( it==d_ground_eqc_map.end() ){\r
+          index = 0;\r
+        }\r
+        //based on unproven conjectures? TODO\r
+        d_relevant_eqc[index].push_back( r );\r
+      }\r
+      Trace("sg-gen-tg-debug") << "Initial relevant eqc : ";\r
+      for( unsigned i=0; i<d_relevant_eqc[0].size(); i++ ){\r
+        Trace("sg-gen-tg-debug") << "e" << d_em[d_relevant_eqc[0][i]] << " ";\r
+      }\r
+      Trace("sg-gen-tg-debug") << std::endl;\r
+      Trace("sg-proc") << "...done compute relevant eqc" << std::endl;\r
+\r
+\r
+      Trace("sg-proc") << "Collect signature information..." << std::endl;\r
+      d_funcs.clear();\r
+      d_typ_funcs.clear();\r
+      d_func_kind.clear();\r
+      d_func_args.clear();\r
+      TypeNode tnull;\r
+      for( std::map< Node, TermArgTrie >::iterator it = getTermDatabase()->d_func_map_trie.begin(); it != getTermDatabase()->d_func_map_trie.end(); ++it ){\r
+        if( !getTermDatabase()->d_op_map[it->first].empty() ){\r
+          Node nn = getTermDatabase()->d_op_map[it->first][0];\r
+          if( isHandledTerm( nn ) && nn.getKind()!=APPLY_SELECTOR_TOTAL && !nn.getType().isBoolean() ){\r
+            d_funcs.push_back( it->first );\r
+            d_typ_funcs[tnull].push_back( it->first );\r
+            d_typ_funcs[nn.getType()].push_back( it->first );\r
+            for( unsigned i=0; i<nn.getNumChildren(); i++ ){\r
+              d_func_args[it->first].push_back( nn[i].getType() );\r
+            }\r
+            d_func_kind[it->first] = nn.getKind();\r
+            Trace("sg-rel-sig") << "Will enumerate function applications of : " << it->first << ", #args = " << d_func_args[it->first].size() << ", kind = " << nn.getKind() << std::endl;\r
+            getTermDatabase()->computeUfEqcTerms( it->first );\r
+          }\r
+        }\r
+      }\r
+      //shuffle functions\r
+      for( std::map< TypeNode, std::vector< TNode > >::iterator it = d_typ_funcs.begin(); it !=d_typ_funcs.end(); ++it ){\r
+        std::random_shuffle( it->second.begin(), it->second.end() );\r
+        if( it->first.isNull() ){\r
+          Trace("sg-gen-tg-debug") << "In this order : ";\r
+          for( unsigned i=0; i<it->second.size(); i++ ){\r
+            Trace("sg-gen-tg-debug") << it->second[i] << " ";            \r
+          }\r
+          Trace("sg-gen-tg-debug") << std::endl;\r
+        }\r
+      }\r
+      Trace("sg-proc") << "...done collect signature information" << std::endl;\r
+\r
+\r
+      Trace("sg-proc") << "Build theorem index..." << std::endl;\r
+      d_ue_canon.clear();\r
+      d_thm_index.clear();\r
+      std::vector< Node > provenConj;\r
+      quantifiers::FirstOrderModel* m = d_quantEngine->getModel();\r
+      for( int i=0; i<m->getNumAssertedQuantifiers(); i++ ){\r
+        Node q = m->getAssertedQuantifier( i );\r
+        Trace("sg-conjecture-debug") << "Is " << q << " a relevant theorem?" << std::endl;\r
+        Node conjEq;\r
+        if( q[1].getKind()==EQUAL ){\r
+          bool isSubsume = false;\r
+          bool inEe = false;\r
+          for( unsigned r=0; r<2; r++ ){\r
+            TNode nl = q[1][r==0 ? 0 : 1];\r
+            TNode nr = q[1][r==0 ? 1 : 0];\r
+            Node eq = nl.eqNode( nr );\r
+            if( r==1 || std::find( d_conjectures.begin(), d_conjectures.end(), q )==d_conjectures.end() ){\r
+              //must make it canonical\r
+              std::map< TypeNode, unsigned > var_count;\r
+              std::map< TNode, TNode > subs;\r
+              Trace("sg-proc-debug") << "get canonical " << eq << std::endl;\r
+              eq = getCanonicalTerm( eq, var_count, subs );\r
+            }\r
+            if( !eq.isNull() ){\r
+              if( r==0 ){\r
+                inEe = d_ee_conjectures.find( q[1] )!=d_ee_conjectures.end();\r
+                if( !inEe ){\r
+                  //add to universal equality engine\r
+                  Node nl = getUniversalRepresentative( eq[0], true );\r
+                  Node nr = getUniversalRepresentative( eq[1], true );\r
+                  if( areUniversalEqual( nl, nr ) ){\r
+                    isSubsume = true;\r
+                    //set inactive (will be ignored by other modules)\r
+                    d_quantEngine->getModel()->setQuantifierActive( q, false );\r
+                  }else{\r
+                    Node exp;\r
+                    d_ee_conjectures[q[1]] = true;\r
+                    d_uequalityEngine.assertEquality( nl.eqNode( nr ), true, exp );\r
+                  }\r
+                }\r
+                Trace("sg-conjecture") << "*** CONJECTURE : currently proven" << (isSubsume ? " and subsumed" : "");\r
+                Trace("sg-conjecture") << " : " << q[1] << std::endl;\r
+                provenConj.push_back( q );\r
+              }\r
+              if( !isSubsume ){\r
+                Trace("thm-db-debug") << "Adding theorem to database " << eq[0] << " == " << eq[1] << std::endl;\r
+                d_thm_index.addTheorem( eq[0], eq[1] );\r
+              }else{\r
+                break;\r
+              }\r
+            }else{\r
+              break;\r
+            }\r
+          }\r
+        }\r
+      }\r
+      //examine status of other conjectures\r
+      for( unsigned i=0; i<d_conjectures.size(); i++ ){\r
+        Node q = d_conjectures[i];\r
+        if( std::find( provenConj.begin(), provenConj.end(), q )==provenConj.end() ){\r
+          //check each skolem variable\r
+          bool disproven = true;\r
+          std::vector< Node > sk;\r
+          getTermDatabase()->getSkolemConstants( q, sk, true );\r
+          Trace("sg-conjecture") << "    CONJECTURE : ";\r
+          std::vector< Node > ce;\r
+          for( unsigned j=0; j<sk.size(); j++ ){\r
+            TNode k = sk[j];\r
+            TNode rk = getRepresentative( k );\r
+            std::map< TNode, Node >::iterator git = d_ground_eqc_map.find( rk );\r
+            //check if it is a ground term\r
+            if( git==d_ground_eqc_map.end() ){\r
+              Trace("sg-conjecture") << "ACTIVE : " << q;\r
+              if( Trace.isOn("sg-gen-eqc") ){\r
+                Trace("sg-conjecture") << " { ";\r
+                for( unsigned k=0; k<sk.size(); k++ ){ Trace("sg-conjecture") << sk[k] << ( j==k ? "*" : "" ) << " "; }\r
+                Trace("sg-conjecture") << "}";\r
+              }\r
+              Trace("sg-conjecture") << std::endl;\r
+              disproven = false;\r
+              break;\r
+            }else{\r
+              ce.push_back( git->second );\r
+            }\r
+          }\r
+          if( disproven ){\r
+            Trace("sg-conjecture") << "disproven : " << q << " : ";\r
+            for( unsigned i=0; i<ce.size(); i++ ){\r
+              Trace("sg-conjecture") << q[0][i] << " -> " << ce[i] << " ";\r
+            }\r
+            Trace("sg-conjecture") << std::endl;\r
+          }\r
+        }\r
+      }\r
+      Trace("thm-db") << "Theorem database is : " << std::endl;\r
+      d_thm_index.debugPrint( "thm-db" );\r
+      Trace("thm-db") << std::endl;\r
+      Trace("sg-proc") << "...done build theorem index" << std::endl;\r
+\r
+      //clear patterns\r
+      d_patterns.clear();\r
+      d_pattern_var_id.clear();\r
+      d_pattern_var_duplicate.clear();\r
+      d_pattern_is_normal.clear();\r
+      d_pattern_fun_id.clear();\r
+      d_pattern_fun_sum.clear();\r
+      d_rel_patterns.clear();\r
+      d_rel_pattern_var_sum.clear();\r
+      d_rel_pattern_typ_index.clear();\r
+      d_rel_pattern_subs_index.clear();\r
+      d_gen_lat_maximal.clear();\r
+      d_gen_lat_child.clear();\r
+      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
+      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
+      //map from generalization depth to maximum depth\r
+      //std::map< unsigned, unsigned > gdepth_to_tdepth;\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-rel-term") << "Relevant terms of depth " << depth << " : " << std::endl;\r
+        //set up environment\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 = -1;\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
+          if( d_tg_alloc[0].getDepth( 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
+              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
+\r
+              for( unsigned r=0; r<2; r++ ){\r
+                Trace("sg-gen-tg-eqc") << "...from equivalence classes (" << r << ") : ";\r
+                int index = d_ccand_eqc[r].size()-1;\r
+                for( unsigned j=0; j<d_ccand_eqc[r][index].size(); j++ ){\r
+                  Trace("sg-gen-tg-eqc") << "e" << d_em[d_ccand_eqc[r][index][j]] << " ";\r
+                }\r
+                Trace("sg-gen-tg-eqc") << std::endl;\r
+              }\r
+              TypeNode tnn = nn.getType();\r
+              Trace("sg-gen-tg-debug") << "...term is " << nn << std::endl;\r
+              Assert( getUniversalRepresentative( nn )==nn );\r
+\r
+              //add information about pattern\r
+              Trace("sg-gen-tg-debug") << "Collect pattern information..." << std::endl;\r
+              Assert( std::find( d_rel_patterns[tnn].begin(), d_rel_patterns[tnn].end(), nn )==d_rel_patterns[tnn].end() );\r
+              d_rel_patterns[tnn].push_back( nn );\r
+              //build information concerning the variables in this pattern\r
+              unsigned sum = 0;\r
+              std::map< TypeNode, unsigned > typ_to_subs_index;\r
+              std::vector< TNode > gsubs_vars;\r
+              for( std::map< TypeNode, unsigned >::iterator it = d_var_id.begin(); it != d_var_id.end(); ++it ){\r
+                if( it->second>0 ){\r
+                  typ_to_subs_index[it->first] = sum;\r
+                  sum += it->second;\r
+                  for( unsigned i=0; i<it->second; i++ ){\r
+                    gsubs_vars.push_back( getFreeVar( it->first, i ) );\r
+                  }\r
+                }\r
+              }\r
+              d_rel_pattern_var_sum[nn] = sum;\r
+              //register the pattern\r
+              registerPattern( nn, tnn );\r
+              Assert( d_pattern_is_normal[nn] );\r
+              Trace("sg-gen-tg-debug") << "...done collect pattern information" << std::endl;\r
+\r
+              //compute generalization relation\r
+              Trace("sg-gen-tg-debug") << "Build generalization information..." << std::endl;\r
+              std::map< TNode, bool > patProc;\r
+              int maxGenDepth = -1;\r
+              unsigned i = d_rel_patterns[tnn].size()-1;\r
+              for( int j=(int)(i-1); j>=0; j-- ){\r
+                TNode np = d_rel_patterns[tnn][j];\r
+                if( patProc.find( np )==patProc.end() ){\r
+                  Trace("sg-gen-tg-debug2") << "Check if generalized by " << np << "..." << std::endl;\r
+                  if( isGeneralization( np, nn ) ){\r
+                    Trace("sg-rel-terms-debug") << "  is generalized by : " << np << std::endl;\r
+                    d_gen_lat_child[np].push_back( nn );\r
+                    d_gen_lat_parent[nn].push_back( np );\r
+                    if( d_gen_depth[np]>maxGenDepth ){\r
+                      maxGenDepth = d_gen_depth[np];\r
+                    }\r
+                    //don't consider the transitive closure of generalizes\r
+                    Trace("sg-gen-tg-debug2") << "Add generalizations" << std::endl;\r
+                    addGeneralizationsOf( np, patProc );\r
+                    Trace("sg-gen-tg-debug2") << "Done add generalizations" << std::endl;\r
+                  }else{\r
+                    Trace("sg-gen-tg-debug2") << "  is not generalized by : " << np << std::endl;\r
+                  }\r
+                }\r
+              }\r
+              if( d_gen_lat_parent[nn].empty() ){\r
+                d_gen_lat_maximal[tnn].push_back( nn );\r
+              }\r
+              d_gen_depth[nn] = maxGenDepth+1;\r
+              Trace("sg-rel-term-debug") << "  -> generalization depth is " << d_gen_depth[nn] << " <> " << depth << std::endl;\r
+              Trace("sg-gen-tg-debug") << "...done build generalization information" << std::endl;\r
+\r
+              //record information about types\r
+              Trace("sg-gen-tg-debug") << "Collect type information..." << std::endl;\r
+              PatternTypIndex * pti = &d_rel_pattern_typ_index;\r
+              for( std::map< TypeNode, unsigned >::iterator it = d_var_id.begin(); it != d_var_id.end(); ++it ){\r
+                pti = &pti->d_children[it->first][it->second];\r
+                //record maximum\r
+                if( rt_var_max.find( it->first )==rt_var_max.end() || it->second>rt_var_max[it->first] ){\r
+                  rt_var_max[it->first] = it->second;\r
+                }\r
+              }\r
+              if( std::find( rt_types.begin(), rt_types.end(), tnn )==rt_types.end() ){\r
+                rt_types.push_back( tnn );\r
+              }\r
+              pti->d_terms.push_back( nn );\r
+              Trace("sg-gen-tg-debug") << "...done collect type information" << std::endl;\r
+\r
+              Trace("sg-gen-tg-debug") << "Build substitutions for ground EQC..." << std::endl;\r
+              std::vector< TNode > gsubs_terms;\r
+              gsubs_terms.resize( gsubs_vars.size() );\r
+              int index = d_ccand_eqc[1].size()-1;\r
+              for( unsigned j=0; j<d_ccand_eqc[1][index].size(); j++ ){\r
+                TNode r = d_ccand_eqc[1][index][j];\r
+                Trace("sg-gen-tg-eqc") << "  Matches for e" << d_em[r] << ", which is ground term " << d_ground_eqc_map[r] << ":" << std::endl;\r
+                std::map< TypeNode, std::map< unsigned, TNode > > subs;\r
+                std::map< TNode, bool > rev_subs;\r
+                //only get ground terms\r
+                unsigned mode = optFilterConfirmationOnlyGround() ? 2 : 0;\r
+                d_tg_alloc[0].resetMatching( this, r, mode );\r
+                while( d_tg_alloc[0].getNextMatch( this, r, subs, rev_subs ) ){\r
+                  //we will be building substitutions\r
+                  bool firstTime = true;\r
+                  for( std::map< TypeNode, std::map< unsigned, TNode > >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
+                    unsigned tindex = typ_to_subs_index[it->first];\r
+                    for( std::map< unsigned, TNode >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){\r
+                      if( !firstTime ){\r
+                        Trace("sg-gen-tg-eqc") << ", ";\r
+                      }else{\r
+                        firstTime = false;\r
+                        Trace("sg-gen-tg-eqc") << "    ";\r
+                      }\r
+                      Trace("sg-gen-tg-eqc") << it->first << ":x" << it2->first << " -> " << it2->second;\r
+                      Assert( tindex+it2->first<gsubs_terms.size() );\r
+                      gsubs_terms[tindex+it2->first] = it2->second;\r
+                    }\r
+                  }\r
+                  Trace("sg-gen-tg-eqc") << std::endl;\r
+                  d_rel_pattern_subs_index[nn].addSubstitution( r, gsubs_vars, gsubs_terms );\r
+                }\r
+              }\r
+              Trace("sg-gen-tg-debug") << "...done build substitutions for ground EQC" << std::endl;\r
+            }else{\r
+              Trace("sg-gen-tg-debug") << "> not canonical : " << nn << std::endl;\r
+            }\r
+          }else{\r
+            Trace("sg-gen-tg-debug") << "> produced term at previous depth : ";\r
+            d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
+            Trace("sg-gen-tg-debug") << std::endl;\r
+          }\r
+        }\r
+        Trace("sg-proc") << "...done generate terms at depth " << depth << std::endl;\r
+    \r
+        \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_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
+              //register pattern\r
+              Assert( rhs.getType()==rt_types[i] );\r
+              registerPattern( rhs, rt_types[i] );\r
+              //for each maximal node of type rt_types[i] in generalization lattice\r
+              for( unsigned j=0; j<d_gen_lat_maximal[rt_types[i]].size(); j++ ){\r
+                //add candidate conjecture\r
+                addCandidateConjecture( d_gen_lat_maximal[rt_types[i]][j], rhs, 0 );\r
+              }\r
+              totalCount++;\r
+            }\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( unsigned conj_depth=0; conj_depth<depth; conj_depth++ ){\r
+          //process all conjectures waiting at depth\r
+          unsigned sz = d_cconj_at_depth[conj_depth].size();\r
+          for( int i=(int)(sz-1); i>=0; i-- ){\r
+            processCandidateConjecture( d_cconj_at_depth[conj_depth][i], conj_depth );\r
+          }\r
+          Assert( d_cconj_at_depth[conj_depth].size()==sz );\r
+          d_cconj_at_depth[conj_depth].clear();\r
+        }\r
+        Trace("sg-proc") << "...done process candidate conjectures at RHS term depth " << depth << std::endl;\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->getOutputChannel().lemma( lem );\r
+          d_quantEngine->getOutputChannel().requirePhase( d_waiting_conjectures[i], false );\r
+        }\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
+            }\r
+            Trace("thm-ee") << "    " << n << std::endl;\r
+          }\r
+          ++ueqc_i;\r
+        }\r
+        if( !firstTime ){ Trace("thm-ee") << "  "; }\r
+        Trace("thm-ee") << "}" << std::endl;\r
+        ++ueqcs_i;\r
+      }\r
+      Trace("thm-ee") << std::endl;\r
+    }\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::registerQuantifier( Node q ) {\r
+\r
+}\r
+\r
+void ConjectureGenerator::assertNode( Node n ) {\r
+\r
+}\r
+\r
+\r
+unsigned ConjectureGenerator::getNumTgVars( TypeNode tn ) {\r
+  //return d_var_tg.size();\r
+  return d_var_id[tn];\r
+}\r
+\r
+bool ConjectureGenerator::allowVar( TypeNode tn ) {\r
+  std::map< TypeNode, unsigned >::iterator it = d_var_limit.find( tn );\r
+  if( it==d_var_limit.end() ){\r
+    return true;\r
+  }else{\r
+    return d_var_id[tn]<it->second;\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::addVar( TypeNode tn ) {\r
+  //d_var_tg.push_back( v );\r
+  d_var_id[tn]++;\r
+  //d_var_eq_tg.push_back( std::vector< unsigned >() );\r
+}\r
+\r
+void ConjectureGenerator::removeVar( TypeNode tn ) {\r
+  d_var_id[tn]--;\r
+  //d_var_eq_tg.pop_back();\r
+  //d_var_tg.pop_back();\r
+}\r
+\r
+unsigned ConjectureGenerator::getNumTgFuncs( TypeNode tn ) {\r
+  return d_typ_tg_funcs[tn].size();\r
+}\r
+\r
+TNode ConjectureGenerator::getTgFunc( TypeNode tn, unsigned i ) {\r
+  return d_typ_tg_funcs[tn][i];\r
+}\r
+\r
+bool ConjectureGenerator::considerCurrentTerm() {\r
+  Assert( !d_tg_alloc.empty() );\r
+  \r
+  //if generalization depth is too large, don't consider it\r
+  unsigned i = d_tg_alloc.size();\r
+  Trace("sg-gen-tg-debug") << "Consider term ";\r
+  d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
+  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
+    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
+    return false;\r
+  }\r
+  \r
+  //----optimizations\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
+  }else{\r
+    Trace("sg-gen-tg-debug") << "Bad tg: " << &d_tg_alloc[i-1] << std::endl;\r
+    Assert( false );\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
+    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
+    Assert( d_ccand_eqc[0].size()>=2 );\r
+    Assert( d_ccand_eqc[0].size()==d_ccand_eqc[1].size() );\r
+    Assert( d_ccand_eqc[0].size()==d_tg_id+1 );\r
+    Assert( d_tg_id==d_tg_alloc.size() );\r
+    for( unsigned r=0; r<2; r++ ){\r
+      d_ccand_eqc[r][i].clear();\r
+    }\r
+\r
+    //re-check feasibility of EQC\r
+    for( unsigned r=0; r<2; r++ ){\r
+      for( unsigned j=0; j<d_ccand_eqc[r][i-1].size(); j++ ){\r
+        std::map< TypeNode, std::map< unsigned, TNode > > subs;\r
+        std::map< TNode, bool > rev_subs;\r
+        unsigned mode;\r
+        if( r==0 ){\r
+          mode = optReqDistinctVarPatterns() ? 1 : 0;\r
+        }else{\r
+          mode = (optFilterConfirmation() && optFilterConfirmationOnlyGround() ) ? 2 : 0;\r
+        }\r
+        d_tg_alloc[0].resetMatching( this, d_ccand_eqc[r][i-1][j], mode );\r
+        if( d_tg_alloc[0].getNextMatch( this, d_ccand_eqc[r][i-1][j], subs, rev_subs ) ){\r
+          d_ccand_eqc[r][i].push_back( d_ccand_eqc[r][i-1][j] );\r
+        }\r
+      }\r
+    }\r
+    for( unsigned r=0; r<2; r++ ){\r
+      Trace("sg-gen-tg-debug") << "Current eqc of type " << r << " : ";\r
+      for( unsigned j=0; j<d_ccand_eqc[r][i].size(); j++ ){\r
+        Trace("sg-gen-tg-debug") << "e" << d_em[d_ccand_eqc[r][i][j]] << " ";\r
+      }\r
+      Trace("sg-gen-tg-debug") << std::endl;\r
+    }\r
+    if( 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
+      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
+      return false;\r
+    }\r
+  }\r
+  Trace("sg-gen-tg-debug") << "Will consider term ";\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
+bool ConjectureGenerator::considerTermCanon( 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
+    }\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
+void ConjectureGenerator::changeContext( bool add ) {\r
+  if( add ){\r
+    for( unsigned r=0; r<2; r++ ){\r
+      d_ccand_eqc[r].push_back( std::vector< TNode >() );\r
+    }\r
+    d_tg_id++;\r
+  }else{\r
+    for( unsigned r=0; r<2; r++ ){\r
+      d_ccand_eqc[r].pop_back();\r
+    }\r
+    d_tg_id--;\r
+    Assert( d_tg_alloc.find( d_tg_id )!=d_tg_alloc.end() );\r
+    d_tg_alloc.erase( d_tg_id );\r
+  }\r
+}\r
+\r
+unsigned ConjectureGenerator::collectFunctions( TNode opat, TNode pat, std::map< TNode, unsigned >& funcs,\r
+                                             std::map< TypeNode, unsigned >& mnvn, std::map< TypeNode, unsigned >& mxvn ){\r
+  if( pat.hasOperator() ){\r
+    funcs[pat.getOperator()]++;\r
+    unsigned sum = 1;\r
+    for( unsigned i=0; i<pat.getNumChildren(); i++ ){\r
+      sum += collectFunctions( opat, pat[i], funcs, mnvn, mxvn );\r
+    }\r
+    return sum;\r
+  }else{\r
+    Assert( pat.getNumChildren()==0 );\r
+    funcs[pat]++;\r
+    //for variables\r
+    if( pat.getKind()==BOUND_VARIABLE ){\r
+      if( funcs[pat]>1 ){\r
+        //duplicate variable\r
+        d_pattern_var_duplicate[opat]++;\r
+      }else{\r
+        //check for max/min\r
+        TypeNode tn = pat.getType();\r
+        unsigned vn = d_free_var_num[pat];\r
+        std::map< TypeNode, unsigned >::iterator it = mnvn.find( tn );\r
+        if( it!=mnvn.end() ){\r
+          if( vn<it->second ){\r
+            d_pattern_is_normal[opat] = false;\r
+            mnvn[tn] = vn;\r
+          }else if( vn>mxvn[tn] ){\r
+            if( vn!=mxvn[tn]+1 ){\r
+              d_pattern_is_normal[opat] = false;\r
+            }\r
+            mxvn[tn] = vn;\r
+          }\r
+        }else{\r
+          //first variable of this type\r
+          mnvn[tn] = vn;\r
+          mxvn[tn] = vn;\r
+        }\r
+      }\r
+    }\r
+    return 1;\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::registerPattern( Node pat, TypeNode tpat ) {\r
+  if( std::find( d_patterns[tpat].begin(), d_patterns[tpat].end(), pat )==d_patterns[tpat].end() ){\r
+    d_patterns[TypeNode::null()].push_back( pat );\r
+    d_patterns[tpat].push_back( pat );\r
+\r
+    Assert( d_pattern_fun_id.find( pat )==d_pattern_fun_id.end() );\r
+    Assert( d_pattern_var_id.find( pat )==d_pattern_var_id.end() );\r
+\r
+    //collect functions\r
+    std::map< TypeNode, unsigned > mnvn;\r
+    d_pattern_fun_sum[pat] = collectFunctions( pat, pat, d_pattern_fun_id[pat], mnvn, d_pattern_var_id[pat] );\r
+    if( d_pattern_is_normal.find( pat )==d_pattern_is_normal.end() ){\r
+      d_pattern_is_normal[pat] = true;\r
+    }\r
+  }\r
+}\r
+\r
+bool ConjectureGenerator::isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs ) {\r
+  if( patg.getKind()==BOUND_VARIABLE ){\r
+    std::map< TNode, TNode >::iterator it = subs.find( patg );\r
+    if( it!=subs.end() ){\r
+      return it->second==pat;\r
+    }else{\r
+      subs[patg] = pat;\r
+      return true;\r
+    }\r
+  }else{\r
+    Assert( patg.hasOperator() );\r
+    if( !pat.hasOperator() || patg.getOperator()!=pat.getOperator() ){\r
+      return false;\r
+    }else{\r
+      Assert( patg.getNumChildren()==pat.getNumChildren() );\r
+      for( unsigned i=0; i<patg.getNumChildren(); i++ ){\r
+        if( !isGeneralization( patg[i], pat[i], subs ) ){\r
+          return false;\r
+        }\r
+      }\r
+      return true;\r
+    }\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::addGeneralizationsOf( TNode pat, std::map< TNode, bool >& patProc ) {\r
+  patProc[pat] = true;\r
+  for( unsigned k=0; k<d_gen_lat_parent[pat].size(); k++ ){\r
+    addGeneralizationsOf( d_gen_lat_parent[pat][k], patProc );\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::addCandidateConjecture( TNode lhs, TNode rhs, unsigned depth ) {\r
+  if( std::find( d_cconj_rhs_paired[rhs].begin(), d_cconj_rhs_paired[rhs].end(), lhs )==d_cconj_rhs_paired[rhs].end() ){\r
+    //add conjecture to list to process\r
+    d_cconj_at_depth[depth].push_back( d_cconj[0].size() );\r
+    //define conjecture\r
+    d_cconj[0].push_back( lhs );\r
+    d_cconj[1].push_back( rhs );\r
+    d_cconj_rhs_paired[rhs].push_back( lhs );\r
+  }\r
+}\r
+\r
+void ConjectureGenerator::processCandidateConjecture( unsigned cid, unsigned depth ) {\r
+  if( d_waiting_conjectures.size()>=optFullCheckConjectures() ){\r
+    return;\r
+  }\r
+  TNode lhs = d_cconj[0][cid];\r
+  TNode rhs = d_cconj[1][cid];\r
+  if( !considerCandidateConjecture( lhs, rhs ) ){\r
+    //push to children of generalization lattice\r
+    for( unsigned i=0; i<d_gen_lat_child[lhs].size(); i++ ){\r
+      if( d_gen_depth[lhs]+1==d_gen_depth[d_gen_lat_child[lhs][i]] ){\r
+        addCandidateConjecture( d_gen_lat_child[lhs][i], rhs, depth+1 );\r
+      }\r
+    }\r
+  }else{\r
+    Trace("sg-conjecture") << "* Candidate conjecture : " << lhs << " == " << rhs << std::endl;\r
+    Trace("sg-conjecture-debug") << "     LHS generalization depth : " << d_gen_depth[lhs] << std::endl;\r
+    if( optFilterConfirmation() || optFilterFalsification() ){\r
+      Trace("sg-conjecture-debug") << "     confirmed = " << d_subs_confirmCount << ", #witnesses range = " << d_subs_confirmWitnessRange.size() << "." << std::endl;\r
+      Trace("sg-conjecture-debug") << "     #witnesses for ";\r
+      bool firstTime = true;\r
+      for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){\r
+        if( !firstTime ){\r
+          Trace("sg-conjecture-debug") << ", ";\r
+        }\r
+        Trace("sg-conjecture-debug") << it->first << " : " << it->second.size() << "/" << d_pattern_fun_id[lhs][it->first];\r
+        firstTime = false;\r
+      }\r
+      Trace("sg-conjecture-debug") << std::endl;\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
+    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
+    Trace("sg-conjecture-debug") << "   formula is : " << conj << std::endl;\r
+    d_waiting_conjectures.push_back( conj );\r
+  }\r
+}\r
+\r
+bool ConjectureGenerator::considerCandidateConjecture( TNode lhs, TNode rhs ) {\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
+    return false;\r
+  }else{\r
+    if( lhs.getKind()==APPLY_CONSTRUCTOR && rhs.getKind()==APPLY_CONSTRUCTOR ){\r
+      Trace("sg-cconj-debug") << "  -> irrelevant by syntactic analysis." << std::endl;\r
+      return false;\r
+    }\r
+    //variables of LHS must subsume variables of RHS\r
+    for( std::map< TypeNode, unsigned >::iterator it = d_pattern_var_id[rhs].begin(); it != d_pattern_var_id[rhs].end(); ++it ){\r
+      std::map< TypeNode, unsigned >::iterator itl = d_pattern_var_id[lhs].find( it->first );\r
+      if( itl!=d_pattern_var_id[lhs].end() ){\r
+        if( itl->second<it->second ){\r
+          Trace("sg-cconj-debug") << "  -> variables of sort " << it->first << " are not subsumed." << std::endl;\r
+          return false;\r
+        }else{\r
+          Trace("sg-cconj-debug2") << "  variables of sort " << it->first << " are : " << itl->second << " vs " << it->second << std::endl;\r
+        }\r
+      }else{\r
+        Trace("sg-cconj-debug") << "  -> has no variables of sort " << it->first << "." << std::endl;\r
+        return false;\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") << "  -> already are considering this conjecture." << std::endl;\r
+        return false;\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
+      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
+      d_subs_confirmCount = 0;\r
+      d_subs_confirmWitnessRange.clear();\r
+      d_subs_confirmWitnessDomain.clear();\r
+      if( !d_rel_pattern_subs_index[lhs].notifySubstitutions( this, subs, rhs, d_rel_pattern_var_sum[lhs] ) ){\r
+        Trace("sg-cconj") << "  -> found witness that falsifies the conjecture." << std::endl;\r
+        return false;\r
+      }\r
+      if( optFilterConfirmation() ){\r
+        if( d_subs_confirmCount==0 ){\r
+          Trace("sg-cconj") << "  -> not confirmed by a ground substitutions." << std::endl;\r
+          return false;\r
+        }\r
+      }\r
+      if( optFilterConfirmationDomain() ){\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
+          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
+          }\r
+          if( it->second.size()<req ){\r
+            Trace("sg-cconj") << "  -> did not find at least " << d_pattern_fun_id[lhs][it->first] << " different values in ground substitutions for variable " << it->first << "." << std::endl;\r
+            return false;\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    Trace("sg-cconj") << "  -> SUCCESS." << std::endl;\r
+    if( optFilterConfirmation() || optFilterFalsification() ){\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
+    return true;\r
+  }\r
+}\r
+\r
+\r
+\r
+bool ConjectureGenerator::processCandidateConjecture2( TNode rhs, TypeNode tn, unsigned depth ) {\r
+  for( unsigned j=0; j<d_rel_patterns_at_depth[tn][depth].size(); j++ ){\r
+    if( processCandidateConjecture2( d_rel_patterns_at_depth[tn][depth][j], rhs ) ){\r
+      return true;\r
+    }\r
+  }\r
+  return false;\r
+}\r
+\r
+bool ConjectureGenerator::processCandidateConjecture2( TNode lhs, TNode rhs ) {\r
+  if( !considerCandidateConjecture( lhs, rhs ) ){\r
+    return false;\r
+  }else{\r
+    Trace("sg-conjecture") << "* Candidate conjecture : " << lhs << " == " << rhs << std::endl;\r
+    Trace("sg-conjecture-debug") << "     LHS generalization depth : " << d_gen_depth[lhs] << std::endl;\r
+    if( optFilterConfirmation() || optFilterFalsification() ){\r
+      Trace("sg-conjecture-debug") << "     confirmed = " << d_subs_confirmCount << ", #witnesses range = " << d_subs_confirmWitnessRange.size() << "." << std::endl;\r
+      Trace("sg-conjecture-debug") << "     #witnesses for ";\r
+      bool firstTime = true;\r
+      for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){\r
+        if( !firstTime ){\r
+          Trace("sg-conjecture-debug") << ", ";\r
+        }\r
+        Trace("sg-conjecture-debug") << it->first << " : " << it->second.size() << "/" << d_pattern_fun_id[lhs][it->first];\r
+        firstTime = false;\r
+      }\r
+      Trace("sg-conjecture-debug") << std::endl;\r
+    }\r
+    if( getUniversalRepresentative( lhs )!=lhs ){\r
+      Trace("ajr-temp") << "bad universal representative : " << lhs << " " << getUniversalRepresentative( lhs ) << 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
+    Trace("sg-conjecture-debug") << "   formula is : " << conj << std::endl;\r
+    d_waiting_conjectures.push_back( conj );\r
+    return true;\r
+  }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+bool ConjectureGenerator::notifySubstitution( TNode glhs, std::map< TNode, TNode >& subs, TNode rhs ) {\r
+  if( Trace.isOn("sg-cconj-debug") ){\r
+    Trace("sg-cconj-debug") << "Ground eqc for LHS : " << glhs << ", based on substituion: " << std::endl;\r
+    for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
+      Assert( getRepresentative( it->second )==it->second );\r
+      Trace("sg-cconj-debug") << "  " << it->first << " -> " << it->second << std::endl;\r
+    }\r
+  }\r
+  Trace("sg-cconj-debug") << "Evaluate RHS : : " << rhs << std::endl;\r
+  //get the representative of rhs with substitution subs\r
+  TNode grhs = getTermDatabase()->evaluateTerm( rhs, subs, true );\r
+  Trace("sg-cconj-debug") << "...done evaluating term, got : " << grhs << std::endl;\r
+  if( !grhs.isNull() ){\r
+    if( glhs!=grhs ){\r
+      if( optFilterFalsification() ){\r
+        Trace("sg-cconj-debug") << "Ground eqc for RHS : " << grhs << std::endl;\r
+        //check based on ground terms\r
+        std::map< TNode, Node >::iterator itl = d_ground_eqc_map.find( glhs );\r
+        if( itl!=d_ground_eqc_map.end() ){\r
+          std::map< TNode, Node >::iterator itr = d_ground_eqc_map.find( grhs );\r
+          if( itr!=d_ground_eqc_map.end() ){\r
+            Trace("sg-cconj-debug") << "We have ground terms " << itl->second << " and " << itr->second << "." << std::endl;\r
+            if( itl->second.isConst() && itr->second.isConst() ){\r
+              Trace("sg-cconj-debug") << "...disequal constants." << std::endl;\r
+              Trace("sg-cconj-witness") << "  Witness of falsification : " << itl->second << " != " << itr->second << ", substutition is : " << std::endl;\r
+              for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
+                Trace("sg-cconj-witness") << "    " << it->first << " -> " << it->second << std::endl;\r
+              }\r
+              return false;\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
+        Trace("sg-cconj-witness") << "    " << it->first << " -> " << it->second << std::endl;\r
+        if( std::find( d_subs_confirmWitnessDomain[it->first].begin(), d_subs_confirmWitnessDomain[it->first].end(), it->second )==d_subs_confirmWitnessDomain[it->first].end() ){\r
+          d_subs_confirmWitnessDomain[it->first].push_back( it->second );\r
+        }\r
+      }\r
+      d_subs_confirmCount++;\r
+      if( std::find( d_subs_confirmWitnessRange.begin(), d_subs_confirmWitnessRange.end(), glhs )==d_subs_confirmWitnessRange.end() ){\r
+        d_subs_confirmWitnessRange.push_back( glhs );\r
+      }\r
+      Trace("sg-cconj-debug") << "RHS is identical." << std::endl;\r
+    }\r
+  }else{\r
+    Trace("sg-cconj-debug") << "(could not ground eqc for RHS)." << std::endl;\r
+  }\r
+  return true;\r
+}\r
+\r
+\r
+void TermGenerator::reset( ConjectureGenerator * s, TypeNode tn ) {\r
+  Assert( d_children.empty() );\r
+  d_typ = tn;\r
+  d_status = 0;\r
+  d_status_num = 0;\r
+  d_children.clear();\r
+  Trace("sg-gen-tg-debug2") << "...add to context " << this << std::endl;\r
+  d_id = s->d_tg_id;\r
+  s->changeContext( true );\r
+}\r
+\r
+bool TermGenerator::getNextTerm( ConjectureGenerator * s, unsigned depth ) {\r
+  if( Trace.isOn("sg-gen-tg-debug2") ){\r
+    Trace("sg-gen-tg-debug2") << this << " getNextTerm depth " << depth << " : status = " << d_status << ", num = " << d_status_num;\r
+    if( d_status==5 ){\r
+      TNode f = s->getTgFunc( d_typ, d_status_num );\r
+      Trace("sg-gen-tg-debug2") << ", f = " << f;\r
+      Trace("sg-gen-tg-debug2") << ", #args = " << s->d_func_args[f].size();\r
+      Trace("sg-gen-tg-debug2") << ", childNum = " << d_status_child_num;\r
+      Trace("sg-gen-tg-debug2") << ", #children = " << d_children.size();\r
+    }\r
+    Trace("sg-gen-tg-debug2") << std::endl;\r
+  }\r
+\r
+  if( d_status==0 ){\r
+    d_status++;\r
+    if( !d_typ.isNull() ){\r
+      if( s->allowVar( d_typ ) ){\r
+        //allocate variable\r
+        d_status_num = s->d_var_id[d_typ];\r
+        s->addVar( d_typ );\r
+        Trace("sg-gen-tg-debug2") << this << " ...return unique var #" << d_status_num << std::endl;\r
+        return s->considerCurrentTerm() ? true : getNextTerm( s, depth );\r
+      }else{\r
+        //check allocating new variable\r
+        d_status++;\r
+        d_status_num = -1;\r
+        s->d_tg_gdepth++;\r
+        return getNextTerm( s, depth );\r
+      }\r
+    }else{\r
+      d_status = 4;\r
+      d_status_num = -1;\r
+      return getNextTerm( s, depth );\r
+    }\r
+  }else if( d_status==2 ){\r
+    //cleanup previous information\r
+    //if( d_status_num>=0 ){\r
+    //  s->d_var_eq_tg[d_status_num].pop_back();\r
+    //}\r
+    //check if there is another variable\r
+    if( (d_status_num+1)<(int)s->getNumTgVars( d_typ ) ){\r
+      d_status_num++;\r
+      //we have equated two variables\r
+      //s->d_var_eq_tg[d_status_num].push_back( d_id );\r
+      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
+      d_status++;\r
+      return getNextTerm( s, depth );\r
+    }\r
+  }else if( d_status==4 ){\r
+    d_status++;\r
+    if( depth>0 && (d_status_num+1)<(int)s->getNumTgFuncs( d_typ ) ){\r
+      d_status_num++;\r
+      d_status_child_num = 0;\r
+      Trace("sg-gen-tg-debug2") << this << "...consider function " << s->getTgFunc( d_typ, d_status_num ) << std::endl;\r
+      s->d_tg_gdepth++;\r
+      if( !s->considerCurrentTerm() ){\r
+        s->d_tg_gdepth--;\r
+        //don't consider this function\r
+        d_status--;\r
+      }else{\r
+        //we have decided on a function application\r
+      }\r
+      return getNextTerm( s, depth );\r
+    }else{\r
+      //do not choose function applications at depth 0\r
+      d_status++;\r
+      return getNextTerm( s, depth );\r
+    }\r
+  }else if( d_status==5 ){\r
+    //iterating over arguments\r
+    TNode f = s->getTgFunc( d_typ, d_status_num );\r
+    if( d_status_child_num<0 ){\r
+      //no more arguments\r
+      s->d_tg_gdepth--;\r
+      d_status--;\r
+      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 true;\r
+    }else{\r
+      Assert( d_status_child_num<(int)s->d_func_args[f].size() );\r
+      if( d_status_child_num==(int)d_children.size() ){\r
+        d_children.push_back( s->d_tg_id );\r
+        Assert( s->d_tg_alloc.find( s->d_tg_id )==s->d_tg_alloc.end() );\r
+        s->d_tg_alloc[d_children[d_status_child_num]].reset( s, s->d_func_args[f][d_status_child_num] );\r
+        return getNextTerm( s, depth );\r
+      }else{\r
+        Assert( d_status_child_num+1==(int)d_children.size() );\r
+        if( s->d_tg_alloc[d_children[d_status_child_num]].getNextTerm( s, depth-1 ) ){\r
+          d_status_child_num++;\r
+          return getNextTerm( s, depth );\r
+        }else{\r
+          d_children.pop_back();\r
+          d_status_child_num--;\r
+          return getNextTerm( s, depth );\r
+        }\r
+      }\r
+    }\r
+  }else if( d_status==1 || d_status==3 ){\r
+    if( d_status==1 ){\r
+      s->removeVar( d_typ );\r
+      Assert( d_status_num==(int)s->d_var_id[d_typ] );\r
+      //check if there is only one feasible equivalence class.  if so, don't make pattern any more specific.\r
+      //unsigned i = s->d_ccand_eqc[0].size()-1;\r
+      //if( s->d_ccand_eqc[0][i].size()==1 && s->d_ccand_eqc[1][i].empty() ){\r
+      //  Trace("ajr-temp") << "Apply this!" << std::endl;\r
+      //  d_status = 6;\r
+      //  return getNextTerm( s, depth );\r
+      //}\r
+      s->d_tg_gdepth++;\r
+    }\r
+    d_status++;\r
+    d_status_num = -1;\r
+    return getNextTerm( s, depth );\r
+  }else{\r
+    //clean up\r
+    Assert( d_children.empty() );\r
+    Trace("sg-gen-tg-debug2") << "...remove from context " << this << std::endl;\r
+    s->changeContext( false );\r
+    Assert( d_id==s->d_tg_id );\r
+    return false;\r
+  }\r
+}\r
+\r
+void TermGenerator::resetMatching( ConjectureGenerator * s, TNode eqc, unsigned mode ) {\r
+  d_match_status = 0;\r
+  d_match_status_child_num = 0;\r
+  d_match_children.clear();\r
+  d_match_children_end.clear();\r
+  d_match_mode = mode;\r
+}\r
+\r
+bool TermGenerator::getNextMatch( ConjectureGenerator * s, TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs ) {\r
+  if( Trace.isOn("sg-gen-tg-match") ){\r
+    Trace("sg-gen-tg-match") << "Matching ";\r
+    debugPrint( s, "sg-gen-tg-match", "sg-gen-tg-match" );\r
+    Trace("sg-gen-tg-match") << " with eqc e" << s->d_em[eqc] << "..." << std::endl;\r
+    Trace("sg-gen-tg-match") << "   mstatus = " << d_match_status;\r
+    if( d_status==5 ){\r
+      TNode f = s->getTgFunc( d_typ, d_status_num );\r
+      Trace("sg-gen-tg-debug2") << ", f = " << f;\r
+      Trace("sg-gen-tg-debug2") << ", #args = " << s->d_func_args[f].size();\r
+      Trace("sg-gen-tg-debug2") << ", mchildNum = " << d_match_status_child_num;\r
+      Trace("sg-gen-tg-debug2") << ", #mchildren = " << d_match_children.size();\r
+    }\r
+    Trace("sg-gen-tg-debug2") << ", current substitution : {";\r
+    for( std::map< TypeNode, std::map< unsigned, TNode > >::iterator itt = subs.begin(); itt != subs.end(); ++itt ){\r
+      for( std::map< unsigned, TNode >::iterator it = itt->second.begin(); it != itt->second.end(); ++it ){\r
+        Trace("sg-gen-tg-debug2")  << " " << it->first << " -> e" << s->d_em[it->second];\r
+      }\r
+    }\r
+    Trace("sg-gen-tg-debug2") << " } " << std::endl;\r
+  }\r
+  if( d_status==1 ){\r
+    //a variable\r
+    if( d_match_status==0 ){\r
+      d_match_status++;\r
+      if( d_match_mode>=2 ){\r
+        //only ground terms\r
+        if( !s->isGroundEqc( eqc ) ){\r
+          return false;\r
+        }\r
+      }\r
+      if( d_match_mode%2==1 ){\r
+        std::map< TNode, bool >::iterator it = rev_subs.find( eqc );\r
+        if( it==rev_subs.end() ){\r
+          rev_subs[eqc] = true;\r
+        }else{\r
+          return false;\r
+        }\r
+      }\r
+      Assert( subs[d_typ].find( d_status_num )==subs[d_typ].end() );\r
+      subs[d_typ][d_status_num] = eqc;\r
+      return true;\r
+    }else{\r
+      //clean up\r
+      subs[d_typ].erase( d_status_num );\r
+      if( d_match_mode%2==1 ){\r
+        rev_subs.erase( eqc );\r
+      }\r
+      return false;\r
+    }\r
+  }else if( d_status==2 ){\r
+    if( d_match_status==0 ){\r
+      d_match_status++;\r
+      Assert( d_status_num<(int)s->getNumTgVars( d_typ ) );\r
+      std::map< unsigned, TNode >::iterator it = subs[d_typ].find( d_status_num );\r
+      Assert( it!=subs[d_typ].end() );\r
+      return it->second==eqc;\r
+    }else{\r
+      return false;\r
+    }\r
+  }else if( d_status==5 ){\r
+    //Assert( d_match_children.size()<=d_children.size() );\r
+    //enumerating over f-applications in eqc\r
+    if( d_match_status_child_num<0 ){\r
+      return false;\r
+    }else if( d_match_status==0 ){\r
+      //set up next binding\r
+      if( d_match_status_child_num==(int)d_match_children.size() ){\r
+        if( d_match_status_child_num==0 ){\r
+          //initial binding\r
+          TNode f = s->getTgFunc( d_typ, d_status_num );\r
+          std::map< TNode, TermArgTrie >::iterator it = s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.find( eqc );\r
+          if( it!=s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.end() ){\r
+            d_match_children.push_back( it->second.d_data.begin() );\r
+            d_match_children_end.push_back( it->second.d_data.end() );\r
+          }else{\r
+            d_match_status++;\r
+            d_match_status_child_num--;\r
+            return getNextMatch( s, eqc, subs, rev_subs );\r
+          }\r
+        }else{\r
+          d_match_children.push_back( d_match_children[d_match_status_child_num-1]->second.d_data.begin() );\r
+          d_match_children_end.push_back( d_match_children[d_match_status_child_num-1]->second.d_data.end() );\r
+        }\r
+      }\r
+      d_match_status++;\r
+      Assert( d_match_status_child_num+1==(int)d_match_children.size() );\r
+      if( d_match_children[d_match_status_child_num]==d_match_children_end[d_match_status_child_num] ){\r
+        //no more arguments to bind\r
+        d_match_children.pop_back();\r
+        d_match_children_end.pop_back();\r
+        d_match_status_child_num--;\r
+        return getNextMatch( s, eqc, subs, rev_subs );\r
+      }else{\r
+        if( d_match_status_child_num==(int)d_children.size() ){\r
+          //successfully matched all children\r
+          d_match_children.pop_back();\r
+          d_match_children_end.pop_back();\r
+          d_match_status_child_num--;\r
+          return true;//return d_match_children[d_match_status]!=d_match_children_end[d_match_status];\r
+        }else{\r
+          //do next binding\r
+          s->d_tg_alloc[d_children[d_match_status_child_num]].resetMatching( s, d_match_children[d_match_status_child_num]->first, d_match_mode );\r
+          return getNextMatch( s, eqc, subs, rev_subs );\r
+        }\r
+      }\r
+    }else{\r
+      Assert( d_match_status==1 );\r
+      Assert( d_match_status_child_num+1==(int)d_match_children.size() );\r
+      Assert( d_match_children[d_match_status_child_num]!=d_match_children_end[d_match_status_child_num] );\r
+      d_match_status--;\r
+      if( s->d_tg_alloc[d_children[d_match_status_child_num]].getNextMatch( s, d_match_children[d_match_status_child_num]->first, subs, rev_subs ) ){\r
+        d_match_status_child_num++;\r
+        return getNextMatch( s, eqc, subs, rev_subs );\r
+      }else{\r
+        //iterate\r
+        d_match_children[d_match_status_child_num]++;\r
+        return getNextMatch( s, eqc, subs, rev_subs );\r
+      }\r
+    }\r
+  }\r
+  Assert( false );\r
+  return false;\r
+}\r
+\r
+unsigned TermGenerator::getDepth( ConjectureGenerator * s ) {\r
+  if( d_status==5 ){\r
+    unsigned maxd = 0;\r
+    for( unsigned i=0; i<d_children.size(); i++ ){\r
+      unsigned d = s->d_tg_alloc[d_children[i]].getDepth( s );\r
+      if( d>maxd ){\r
+        maxd = d;\r
+      }\r
+    }\r
+    return 1+maxd;\r
+  }else{\r
+    return 0;\r
+  }\r
+}\r
+\r
+unsigned TermGenerator::getGeneralizationDepth( ConjectureGenerator * s ) {\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
+    }\r
+    return sum;\r
+  }else if( d_status==2 ){\r
+    return 1;\r
+  }else{\r
+    Assert( d_status==1 );\r
+    return 0;\r
+  }\r
+}\r
+\r
+Node TermGenerator::getTerm( ConjectureGenerator * s ) {\r
+  if( d_status==1 || d_status==2 ){\r
+    Assert( !d_typ.isNull() );\r
+    return s->getFreeVar( d_typ, d_status_num );\r
+  }else if( d_status==5 ){\r
+    Node f = s->getTgFunc( d_typ, d_status_num );\r
+    if( d_children.size()==s->d_func_args[f].size() ){\r
+      std::vector< Node > children;\r
+      children.push_back( f );\r
+      for( unsigned i=0; i<d_children.size(); i++ ){\r
+        Node nc = s->d_tg_alloc[d_children[i]].getTerm( s );\r
+        if( nc.isNull() ){\r
+          return Node::null();\r
+        }else{\r
+          //Assert( nc.getType()==s->d_func_args[f][i] );\r
+          children.push_back( nc );\r
+        }\r
+      }\r
+      return NodeManager::currentNM()->mkNode( s->d_func_kind[f], children );\r
+    }\r
+  }else{\r
+    Assert( false );\r
+  }\r
+  return Node::null();\r
+}\r
+\r
+/*\r
+int TermGenerator::getActiveChild( ConjectureGenerator * s ) {\r
+  if( d_status==1 || d_status==2 ){\r
+    return d_id;\r
+  }else if( d_status==5 ){\r
+    Node f = s->getTgFunc( d_typ, d_status_num );\r
+    int i = d_children.size()-1;\r
+    if( d_children.size()==s->d_func_args[f].size() ){\r
+      if( d_children.empty() ){\r
+        return d_id;\r
+      }else{\r
+        int cac = s->d_tg_alloc[d_children[i]].getActiveChild( s );\r
+        return cac==(int)d_children[i] ? d_id : cac;\r
+      }\r
+    }else if( !d_children.empty() ){\r
+      return s->d_tg_alloc[d_children[i]].getActiveChild( s );\r
+    }\r
+  }else{\r
+    Assert( false );\r
+  }\r
+  return -1;\r
+}\r
+*/\r
+\r
+void TermGenerator::debugPrint( ConjectureGenerator * s, const char * c, const char * cd ) {\r
+  Trace(cd) << "[*" << d_id << "," << d_status << "]:";\r
+  if( d_status==1 || d_status==2 ){\r
+    Trace(c) << s->getFreeVar( d_typ, d_status_num );\r
+  }else if( d_status==5 ){\r
+    TNode f = s->getTgFunc( d_typ, d_status_num );\r
+    Trace(c) << "(" << f;\r
+    for( unsigned i=0; i<d_children.size(); i++ ){\r
+      Trace(c) << " ";\r
+       s->d_tg_alloc[d_children[i]].debugPrint( s, c, cd );\r
+    }\r
+    if( d_children.size()<s->d_func_args[f].size() ){\r
+      Trace(c) << " ...";\r
+    }\r
+    Trace(c) << ")";\r
+  }else{\r
+    Trace(c) << "???";\r
+  }\r
+}\r
+\r
+\r
+void SubstitutionIndex::addSubstitution( TNode eqc, std::vector< TNode >& vars, std::vector< TNode >& terms, unsigned i ) {\r
+  if( i==vars.size() ){\r
+    d_var = eqc;\r
+  }else{\r
+    Assert( d_var.isNull() || d_var==vars[i] );\r
+    d_var = vars[i];\r
+    d_children[terms[i]].addSubstitution( eqc, vars, terms, i+1 );\r
+  }\r
+}\r
+\r
+bool SubstitutionIndex::notifySubstitutions( ConjectureGenerator * s, std::map< TNode, TNode >& subs, TNode rhs, unsigned numVars, unsigned i ) {\r
+  if( i==numVars ){\r
+    Assert( d_children.empty() );\r
+    return s->notifySubstitution( d_var, subs, rhs );\r
+  }else{\r
+    Assert( i==0 || !d_children.empty() );\r
+    for( std::map< TNode, SubstitutionIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){\r
+      Trace("sg-cconj-debug2") << "Try " << d_var << " -> " << it->first << " (" << i << "/" << numVars << ")" << std::endl;\r
+      subs[d_var] = it->first;\r
+      if( !it->second.notifySubstitutions( s, subs, rhs, numVars, i+1 ) ){\r
+        return false;\r
+      }\r
+    }\r
+    return true;\r
+  }\r
+}\r
+\r
+\r
+void TheoremIndex::addTheorem( std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs ){\r
+  if( lhs_v.empty() ){\r
+    if( std::find( d_terms.begin(), d_terms.end(), rhs )==d_terms.end() ){\r
+      d_terms.push_back( rhs );\r
+    }\r
+  }else{\r
+    unsigned index = lhs_v.size()-1;\r
+    if( lhs_arg[index]==lhs_v[index].getNumChildren() ){\r
+      lhs_v.pop_back();\r
+      lhs_arg.pop_back();\r
+      addTheorem( lhs_v, lhs_arg, rhs );\r
+    }else{\r
+      lhs_arg[index]++;\r
+      addTheoremNode( lhs_v[index][lhs_arg[index]-1], lhs_v, lhs_arg, rhs );\r
+    }\r
+  }\r
+}\r
+\r
+void TheoremIndex::addTheoremNode( TNode curr, std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs ){\r
+  Trace("thm-db-debug") << "Adding conjecture for subterm " << curr << "..." << std::endl;\r
+  if( curr.hasOperator() ){\r
+    lhs_v.push_back( curr );\r
+    lhs_arg.push_back( 0 );\r
+    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
+    d_children[curr].addTheorem( lhs_v, lhs_arg, rhs );\r
+  }\r
+}\r
+\r
+void TheoremIndex::getEquivalentTerms( std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,\r
+                                       std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,\r
+                                       std::vector< Node >& terms ) {\r
+  Trace("thm-db-debug") << "Get equivalent terms " << n_v.size() << " " << n_arg.size() << std::endl;\r
+  if( n_v.empty() ){\r
+    Trace("thm-db-debug") << "Number of terms : " << d_terms.size() << std::endl;\r
+    //apply substutitions to RHS's\r
+    for( unsigned i=0; i<d_terms.size(); i++ ){\r
+      Node n = d_terms[i].substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );\r
+      terms.push_back( n );\r
+    }\r
+  }else{\r
+    unsigned index = n_v.size()-1;\r
+    if( n_arg[index]==n_v[index].getNumChildren() ){\r
+      n_v.pop_back();\r
+      n_arg.pop_back();\r
+      getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );\r
+    }else{\r
+      n_arg[index]++;\r
+      getEquivalentTermsNode( n_v[index][n_arg[index]-1], n_v, n_arg, smap, vars, subs, terms );\r
+    }\r
+  }\r
+}\r
+\r
+void TheoremIndex::getEquivalentTermsNode( Node curr, std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,\r
+                                           std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,\r
+                                           std::vector< Node >& terms ) {\r
+  Trace("thm-db-debug") << "Get equivalent based on subterm " << curr << "..." << std::endl;\r
+  if( curr.hasOperator() ){\r
+    Trace("thm-db-debug") << "Check based on operator..." << std::endl;\r
+    std::map< TNode, TheoremIndex >::iterator it = d_children.find( curr.getOperator() );\r
+    if( it!=d_children.end() ){\r
+      n_v.push_back( curr );\r
+      n_arg.push_back( 0 );\r
+      it->second.getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );\r
+    }\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
+    }\r
+  }\r
+}\r
+\r
+void TheoremIndex::debugPrint( const char * c, unsigned ind ) {\r
+  for( std::map< TNode, TheoremIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){\r
+    for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }\r
+    Trace(c) << it->first << std::endl;\r
+    it->second.debugPrint( c, ind+1 );\r
+  }\r
+  if( !d_terms.empty() ){\r
+    for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }\r
+    Trace(c) << "{";\r
+    for( unsigned i=0; i<d_terms.size(); i++ ){\r
+      Trace(c) << " " << d_terms[i];\r
+    }\r
+    Trace(c) << " }" << std::endl;\r
+  }\r
+  //if( !d_var.isNull() ){\r
+  //  for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }\r
+  //  Trace(c) << "var:" << d_var << std::endl;\r
+  //}\r
+}\r
+\r
+bool ConjectureGenerator::optReqDistinctVarPatterns() { return false; }\r
+bool ConjectureGenerator::optFilterFalsification() { return true; }\r
+bool ConjectureGenerator::optFilterConfirmation() { return true; }\r
+bool ConjectureGenerator::optFilterConfirmationDomain() { return true; }\r
+bool ConjectureGenerator::optFilterConfirmationOnlyGround() { return true; }//false; }\r
+bool ConjectureGenerator::optWaitForFullCheck() { return true; }\r
+unsigned ConjectureGenerator::optFullCheckFrequency() { return 1; }\r
+unsigned ConjectureGenerator::optFullCheckConjectures() { return 1; }\r
+\r
+\r
+}\r
+\r
+\r
diff --git a/src/theory/quantifiers/conjecture_generator.h b/src/theory/quantifiers/conjecture_generator.h
new file mode 100644 (file)
index 0000000..90c76d4
--- /dev/null
@@ -0,0 +1,408 @@
+/*********************                                                        */\r
+/*! \file subgoal_generator.h\r
+ ** \verbatim\r
+ ** Original author: Andrew Reynolds\r
+ ** Major contributors: none\r
+ ** Minor contributors (to current version): none\r
+ ** This file is part of the CVC4 project.\r
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
+ ** See the file COPYING in the top-level source directory for licensing\r
+ ** information.\endverbatim\r
+ **\r
+ ** \brief conjecture generator class\r
+ **/\r
+\r
+#include "cvc4_private.h"\r
+\r
+#ifndef CONJECTURE_GENERATOR_H\r
+#define CONJECTURE_GENERATOR_H\r
+\r
+#include "context/cdhashmap.h"\r
+#include "context/cdchunk_list.h"\r
+#include "theory/quantifiers_engine.h"\r
+\r
+namespace CVC4 {\r
+namespace theory {\r
+namespace quantifiers {\r
+\r
+class TermArgTrie;\r
+\r
+//algorithm for computing candidate subgoals\r
+\r
+class ConjectureGenerator;\r
+\r
+// operator independent index of arguments for an EQC\r
+class OpArgIndex\r
+{\r
+public:\r
+  std::map< TNode, OpArgIndex > d_child;\r
+  std::vector< TNode > d_ops;\r
+  std::vector< TNode > d_op_terms;\r
+  void addTerm( ConjectureGenerator * s, TNode n, unsigned index = 0 );\r
+  Node getGroundTerm( ConjectureGenerator * s, std::vector< TNode >& args );\r
+  void getGroundTerms( ConjectureGenerator * s, std::vector< TNode >& terms );\r
+};\r
+\r
+class PatternTypIndex\r
+{\r
+public:\r
+  std::vector< TNode > d_terms;\r
+  std::map< TypeNode, std::map< unsigned, PatternTypIndex > > d_children;\r
+  void clear() {\r
+    d_terms.clear();\r
+    d_children.clear();\r
+  }\r
+};\r
+\r
+class SubstitutionIndex\r
+{\r
+public:\r
+  //current variable, or ground EQC if d_children.empty()\r
+  TNode d_var;\r
+  std::map< TNode, SubstitutionIndex > d_children;\r
+  //add substitution\r
+  void addSubstitution( TNode eqc, std::vector< TNode >& vars, std::vector< TNode >& terms, unsigned i = 0 );\r
+  //notify substitutions\r
+  bool notifySubstitutions( ConjectureGenerator * s, std::map< TNode, TNode >& subs, TNode rhs, unsigned numVars, unsigned i = 0 );\r
+};\r
+\r
+class TermGenerator\r
+{\r
+public:\r
+  TermGenerator(){}\r
+  TypeNode d_typ;\r
+  unsigned d_id;\r
+  //1 : consider as unique variable\r
+  //2 : consider equal to another variable\r
+  //5 : consider a function application\r
+  unsigned d_status;\r
+  int d_status_num;\r
+  //for function applications: the number of children you have built\r
+  int d_status_child_num;\r
+  //children (pointers to TermGenerators)\r
+  std::vector< unsigned > d_children;\r
+  //possible eqc for this term\r
+  //std::vector< TNode > d_eqc;\r
+\r
+  //match status\r
+  unsigned d_match_status;\r
+  int d_match_status_child_num;\r
+  //match mode\r
+  //1 : different variables must have different matches\r
+  //2 : variables must map to ground terms\r
+  //3 : both 1 and 2\r
+  unsigned d_match_mode;\r
+  //children\r
+  std::vector< std::map< TNode, TermArgTrie >::iterator > d_match_children;\r
+  std::vector< std::map< TNode, TermArgTrie >::iterator > d_match_children_end;\r
+\r
+  void reset( ConjectureGenerator * s, TypeNode tn );\r
+  bool getNextTerm( ConjectureGenerator * s, unsigned depth );\r
+  void resetMatching( ConjectureGenerator * s, TNode eqc, unsigned mode );\r
+  bool getNextMatch( ConjectureGenerator * s, TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs );\r
+\r
+  unsigned getDepth( ConjectureGenerator * s );\r
+  unsigned getGeneralizationDepth( ConjectureGenerator * s );\r
+  Node getTerm( ConjectureGenerator * s );\r
+\r
+  void debugPrint( ConjectureGenerator * s, const char * c, const char * cd );\r
+};\r
+\r
+\r
+class TheoremIndex\r
+{\r
+private:\r
+  void addTheorem( std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs );\r
+  void addTheoremNode( TNode curr, std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs );\r
+  void getEquivalentTerms( std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,\r
+                           std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,\r
+                           std::vector< Node >& terms );\r
+  void getEquivalentTermsNode( Node curr, std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,\r
+                               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< TNode, TheoremIndex > d_children;\r
+  std::vector< Node > d_terms;\r
+\r
+  void addTheorem( TNode lhs, TNode rhs ) {\r
+    std::vector< TNode > v;\r
+    std::vector< unsigned > a;\r
+    addTheoremNode( lhs, v, a, rhs );\r
+  }\r
+  void getEquivalentTerms( TNode n, std::vector< Node >& terms ) {\r
+    std::vector< TNode > nv;\r
+    std::vector< unsigned > na;\r
+    std::map< TNode, TNode > smap;\r
+    std::vector< TNode > vars;\r
+    std::vector< TNode > subs;\r
+    getEquivalentTermsNode( n, nv, na, smap, vars, subs, terms );\r
+  }\r
+  void clear(){\r
+    d_var = Node::null();\r
+    d_children.clear();\r
+    d_terms.clear();\r
+  }\r
+  void debugPrint( const char * c, unsigned ind = 0 );\r
+};\r
+\r
+\r
+\r
+class ConjectureGenerator : public QuantifiersModule\r
+{\r
+  friend class OpArgIndex;\r
+  friend class PatGen;\r
+  friend class PatternGenEqc;\r
+  friend class PatternGen;\r
+  friend class SubsEqcIndex;\r
+  friend class TermGenerator;\r
+  typedef context::CDChunkList<Node> NodeList;\r
+  typedef context::CDHashMap< Node, Node, NodeHashFunction > NodeMap;\r
+  typedef context::CDHashMap< Node, bool, NodeHashFunction > BoolMap;\r
+//this class maintains a congruence closure for *universal* facts\r
+private:\r
+  //notification class for equality engine\r
+  class NotifyClass : public eq::EqualityEngineNotify {\r
+    ConjectureGenerator& d_sg;\r
+  public:\r
+    NotifyClass(ConjectureGenerator& sg): d_sg(sg) {}\r
+    bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; }\r
+    bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; }\r
+    bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { return true; }\r
+    void eqNotifyConstantTermMerge(TNode t1, TNode t2) { }\r
+    void eqNotifyNewClass(TNode t) { d_sg.eqNotifyNewClass(t); }\r
+    void eqNotifyPreMerge(TNode t1, TNode t2) { d_sg.eqNotifyPreMerge(t1, t2); }\r
+    void eqNotifyPostMerge(TNode t1, TNode t2) { d_sg.eqNotifyPostMerge(t1, t2); }\r
+    void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {d_sg.eqNotifyDisequal(t1, t2, reason); }\r
+  };/* class ConjectureGenerator::NotifyClass */\r
+  /** The notify class */\r
+  NotifyClass d_notify;\r
+  class EqcInfo{\r
+  public:\r
+    EqcInfo( context::Context* c );\r
+    //representative\r
+    context::CDO< Node > d_rep;\r
+  };\r
+  /** get or make eqc info */\r
+  EqcInfo* getOrMakeEqcInfo( TNode n, bool doMake = false );\r
+  /** (universal) equaltity engine */\r
+  eq::EqualityEngine d_uequalityEngine;\r
+  /** pending adds */\r
+  std::vector< Node > d_upendingAdds;\r
+  /** relevant terms */\r
+  std::map< Node, bool > d_urelevant_terms;\r
+  /** information necessary for equivalence classes */\r
+  std::map< Node, EqcInfo* > d_eqc_info;\r
+  /** called when a new equivalance class is created */\r
+  void eqNotifyNewClass(TNode t);\r
+  /** called when two equivalance classes will merge */\r
+  void eqNotifyPreMerge(TNode t1, TNode t2);\r
+  /** called when two equivalance classes have merged */\r
+  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
+  bool areUniversalDisequal( TNode n1, TNode n2 );\r
+  /** get universal representative */\r
+  TNode getUniversalRepresentative( TNode n, bool add = false );\r
+  /** set relevant */\r
+  void setUniversalRelevant( TNode n );\r
+  /** ordering for universal terms */\r
+  bool isUniversalLessThan( TNode rt1, TNode rt2 );\r
+  \r
+  /** the nodes we have reported as canonical representative */\r
+  std::vector< TNode > d_ue_canon;\r
+  /** is reported canon */\r
+  bool isReportedCanon( TNode n );\r
+  /** mark that term has been reported as canonical rep */\r
+  void markReportedCanon( TNode n );\r
+  \r
+private:  //information regarding the conjectures\r
+  /** list of all conjectures */\r
+  std::vector< Node > d_conjectures;\r
+  /** list of all waiting conjectures */\r
+  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
+  BoolMap d_ee_conjectures;\r
+  /** conjecture index */\r
+  TheoremIndex d_thm_index;\r
+  /** the relevant equivalence classes based on the conjectures */\r
+  std::vector< TNode > d_relevant_eqc[2];\r
+private:  //information regarding the signature we are enumerating conjectures for\r
+  //all functions\r
+  std::vector< TNode > d_funcs;\r
+  //functions per type\r
+  std::map< TypeNode, std::vector< TNode > > d_typ_funcs;\r
+  //function to kind map\r
+  std::map< TNode, Kind > d_func_kind;\r
+  //type of each argument of the function\r
+  std::map< TNode, std::vector< TypeNode > > d_func_args;\r
+  //free variables\r
+  std::map< TypeNode, std::vector< Node > > d_free_var;\r
+  //map from free variable to FV#\r
+  std::map< TNode, unsigned > d_free_var_num;\r
+  // get canonical free variable #i of type tn\r
+  Node getFreeVar( TypeNode tn, unsigned i );\r
+  // get maximum free variable numbers\r
+  void getMaxFreeVarNum( TNode n, std::map< TypeNode, unsigned >& mvn );\r
+  // get canonical term, return null if it contains a term apart from handled signature\r
+  Node getCanonicalTerm( TNode n, std::map< TypeNode, unsigned >& var_count, std::map< TNode, TNode >& subs );\r
+private:  //information regarding the terms\r
+  //relevant patterns (the LHS's)\r
+  std::map< TypeNode, std::vector< Node > > d_rel_patterns;\r
+  //total number of unique variables\r
+  std::map< TNode, unsigned > d_rel_pattern_var_sum;\r
+  //by types\r
+  PatternTypIndex d_rel_pattern_typ_index;\r
+  // substitution to ground EQC index\r
+  std::map< TNode, SubstitutionIndex > d_rel_pattern_subs_index;\r
+  //patterns (the RHS's)\r
+  std::map< TypeNode, std::vector< Node > > d_patterns;\r
+  //patterns to # variables per type\r
+  std::map< TNode, std::map< TypeNode, unsigned > > d_pattern_var_id;\r
+  // # 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
+  // 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
+  std::map< TNode, unsigned > d_pattern_fun_sum;\r
+  // collect functions\r
+  unsigned collectFunctions( TNode opat, TNode pat, std::map< TNode, unsigned >& funcs,\r
+                             std::map< TypeNode, unsigned >& mnvn, std::map< TypeNode, unsigned >& mxvn );\r
+  // 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
+  std::map< TypeNode, unsigned > d_var_id;\r
+  //the limit of number of variables per type to enumerate\r
+  std::map< TypeNode, unsigned > d_var_limit;\r
+  //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
+  std::vector< std::vector< TNode > > d_ccand_eqc[2];\r
+  //the term generation objects\r
+  unsigned d_tg_id;\r
+  std::map< unsigned, TermGenerator > d_tg_alloc;\r
+  unsigned d_tg_gdepth;\r
+  int d_tg_gdepth_limit;\r
+  //std::vector< std::vector< unsigned > > d_var_eq_tg;\r
+  //access functions\r
+  unsigned getNumTgVars( TypeNode tn );\r
+  bool allowVar( TypeNode tn );\r
+  void addVar( TypeNode tn );\r
+  void removeVar( TypeNode tn );\r
+  unsigned getNumTgFuncs( TypeNode tn );\r
+  TNode getTgFunc( TypeNode tn, unsigned i );\r
+  bool considerCurrentTerm();\r
+  bool considerTermCanon( unsigned tg_id );\r
+  void changeContext( bool add );\r
+public:  //for generalization lattice\r
+  //id of maximal nodes\r
+  std::map< TypeNode, std::vector< TNode > > d_gen_lat_maximal;\r
+  //generalization lattice\r
+  std::map< TNode, std::vector< TNode > > d_gen_lat_child;\r
+  std::map< TNode, std::vector< TNode > > d_gen_lat_parent;\r
+  //generalization depth\r
+  std::map< TNode, int > d_gen_depth;\r
+  //generalizations\r
+  bool isGeneralization( TNode patg, TNode pat ) {\r
+    std::map< TNode, TNode > subs;\r
+    return isGeneralization( patg, pat, subs );\r
+  }\r
+  bool isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs );\r
+  void addGeneralizationsOf( TNode pat, std::map< TNode, bool >& patProc );\r
+  \r
+  //from generalization depth to relevant patterns\r
+  std::map< TypeNode, std::map< unsigned, std::vector< TNode > > > d_rel_patterns_at_depth;\r
+  \r
+  \r
+public:  //for property enumeration\r
+  //conjectures to process at a particular depth\r
+  std::map< unsigned, std::vector< unsigned > > d_cconj_at_depth;\r
+  //RHS, LHS\r
+  std::vector< TNode > d_cconj[2];\r
+  // RHS paired\r
+  std::map< TNode, std::vector< TNode > > d_cconj_rhs_paired;\r
+  //add candidate conjecture\r
+  void addCandidateConjecture( TNode lhs, TNode rhs, unsigned depth );\r
+  //process candidate conjecture at depth\r
+  void processCandidateConjecture( unsigned cid, unsigned depth );\r
+  \r
+  //process candidate conjecture at depth\r
+  bool processCandidateConjecture2( TNode rhs, TypeNode tn, unsigned depth );\r
+  //process candidate conjecture \r
+  bool processCandidateConjecture2( TNode lhs, TNode rhs );\r
+  \r
+  //whether it should be considered\r
+  bool considerCandidateConjecture( TNode lhs, TNode rhs );\r
+  //notified of a substitution\r
+  bool notifySubstitution( TNode glhs, std::map< TNode, TNode >& subs, TNode rhs );\r
+  //confirmation count\r
+  unsigned d_subs_confirmCount;\r
+  //individual witnesses (for range)\r
+  std::vector< TNode > d_subs_confirmWitnessRange;\r
+  //individual witnesses (for domain)\r
+  std::map< TNode, std::vector< TNode > > d_subs_confirmWitnessDomain;\r
+public:  //for ground equivalence classes\r
+  eq::EqualityEngine * getEqualityEngine();\r
+  bool areDisequal( TNode n1, TNode n2 );\r
+  bool areEqual( TNode n1, TNode n2 );\r
+  TNode getRepresentative( TNode n );\r
+  TermDb * getTermDatabase();\r
+private:  //information about ground equivalence classes\r
+  TNode d_bool_eqc[2];\r
+  std::map< TNode, Node > d_ground_eqc_map;\r
+  std::vector< TNode > d_ground_terms;\r
+  //operator independent term index\r
+  std::map< TNode, OpArgIndex > d_op_arg_index;\r
+  //is handled term\r
+  bool isHandledTerm( TNode n );\r
+  Node getGroundEqc( TNode r );\r
+  bool isGroundEqc( TNode r );\r
+  bool isGroundTerm( TNode n );\r
+  // count of full effort checks\r
+  unsigned d_fullEffortCount;\r
+public:\r
+  ConjectureGenerator( QuantifiersEngine * qe, context::Context* c );\r
+  /* needs check */\r
+  bool needsCheck( Theory::Effort e );\r
+  /* reset at a round */\r
+  void reset_round( Theory::Effort e );\r
+  /* Call during quantifier engine's check */\r
+  void check( Theory::Effort e );\r
+  /* Called for new quantifiers */\r
+  void registerQuantifier( Node q );\r
+  void assertNode( Node n );\r
+  /** Identify this module (for debugging, dynamic configuration, etc..) */\r
+  std::string identify() const { return "ConjectureGenerator"; }\r
+\r
+//options\r
+private:\r
+  bool optReqDistinctVarPatterns();\r
+  bool optFilterFalsification();\r
+  bool optFilterConfirmation();\r
+  bool optFilterConfirmationDomain();\r
+  bool optFilterConfirmationOnlyGround();\r
+  bool optWaitForFullCheck();\r
+  unsigned optFullCheckFrequency();\r
+  unsigned optFullCheckConjectures();\r
+};\r
+\r
+\r
+}\r
+}\r
+}\r
+\r
+#endif\r
index 1421c639fb5b35dad6d674c985fa675894cd7849..0a0d4eba8fc84e4bd454131ee9e95be15cad47a6 100644 (file)
@@ -115,6 +115,24 @@ Node FirstOrderModel::getSomeDomainElement(TypeNode tn){
   return d_rep_set.d_type_reps[tn][0];
 }
 
+void FirstOrderModel::reset_round() {
+  d_quant_active.clear();
+}
+
+void FirstOrderModel::setQuantifierActive( TNode q, bool active ) {
+  d_quant_active[q] = active;
+}
+
+bool FirstOrderModel::isQuantifierActive( TNode q ) {
+  std::map< TNode, bool >::iterator it = d_quant_active.find( q );
+  if( it==d_quant_active.end() ){
+    return true;
+  }else{
+    return it->second;
+  }
+}
+
+
 FirstOrderModelIG::FirstOrderModelIG(QuantifiersEngine * qe, context::Context* c, std::string name) :
 FirstOrderModel(qe, c,name) {
 
index 76c3946ce2de45551e191792a50d2104c2b98ebf..6ad04a1e6a63aeb54640dede86cde4f352817abb 100644 (file)
@@ -92,6 +92,19 @@ public:
   }
   /** get some domain element */
   Node getSomeDomainElement(TypeNode tn);
+private:
+  //list of inactive quantified formulas
+  std::map< TNode, bool > d_quant_active;
+public:
+  /** reset round */
+  void reset_round();
+  /** set quantified formula active/inactive 
+   * a quantified formula may be set inactive if for instance:
+   *   - it is entailed by other quantified formulas
+   */
+  void setQuantifierActive( TNode q, bool active );
+  /** is quantified formula active */
+  bool isQuantifierActive( TNode q );
 };/* class FirstOrderModel */
 
 
index c024d0babf8e417dde418a8b061398d9b23ac2ac..6faa5ffca6381d387de5b85988e9475698595a73 100644 (file)
@@ -618,13 +618,7 @@ int InstMatchGeneratorSimple::addInstantiations( Node f, InstMatch& baseMatch, Q
   m.add( baseMatch );
   int addedLemmas = 0;
 
-  if( d_match_pattern.getType()==NodeManager::currentNM()->booleanType() ){
-    for( int i=0; i<2; i++ ){
-      addInstantiations( m, qe, addedLemmas, 0, &(qe->getTermDatabase()->d_pred_map_trie[i][ d_op ]) );
-    }
-  }else{
-    addInstantiations( m, qe, addedLemmas, 0, &(qe->getTermDatabase()->d_func_map_trie[ d_op ]) );
-  }
+  addInstantiations( m, qe, addedLemmas, 0, &(qe->getTermDatabase()->d_func_map_trie[ d_op ]) );
   return addedLemmas;
 }
 
@@ -646,7 +640,7 @@ void InstMatchGeneratorSimple::addInstantiations( InstMatch& m, QuantifiersEngin
   }else{
     if( d_match_pattern[argIndex].getKind()==INST_CONSTANT ){
       int v = d_var_num[argIndex];
-      for( std::map< Node, quantifiers::TermArgTrie >::iterator it = tat->d_data.begin(); it != tat->d_data.end(); ++it ){
+      for( std::map< TNode, quantifiers::TermArgTrie >::iterator it = tat->d_data.begin(); it != tat->d_data.end(); ++it ){
         Node t = it->first;
         Node prev = m.get( v );
         //using representatives, just check if equal
@@ -658,7 +652,7 @@ void InstMatchGeneratorSimple::addInstantiations( InstMatch& m, QuantifiersEngin
       }
     }else{
       Node r = qe->getEqualityQuery()->getRepresentative( d_match_pattern[argIndex] );
-      std::map< Node, quantifiers::TermArgTrie >::iterator it = tat->d_data.find( r );
+      std::map< TNode, quantifiers::TermArgTrie >::iterator it = tat->d_data.find( r );
       if( it!=tat->d_data.end() ){
         addInstantiations( m, qe, addedLemmas, argIndex+1, &(it->second) );
       }
index 3dd4423dede68a798c240cd4324d27cab3dddc15..2167c7c7dc6a26f9313dd6617d93a5652e64a3fc 100644 (file)
@@ -53,7 +53,13 @@ void InstantiationEngine::finishInit(){
     }else{
       d_isup = NULL;
     }
-    d_i_ag = new InstStrategyAutoGenTriggers( d_quantEngine, Trigger::TS_ALL, 3 );
+    int tstrt = Trigger::TS_ALL;
+    if( options::triggerSelMode()==TRIGGER_SEL_MIN ){
+      tstrt = Trigger::TS_MIN_TRIGGER;
+    }else if( options::triggerSelMode()==TRIGGER_SEL_MAX ){
+      tstrt = Trigger::TS_MAX_TRIGGER;
+    }
+    d_i_ag = new InstStrategyAutoGenTriggers( d_quantEngine, tstrt, 3 );
     d_i_ag->setGenerateAdditional( true );
     addInstStrategy( d_i_ag );
     //addInstStrategy( new InstStrategyAddFailSplits( this, ie ) );
@@ -214,9 +220,12 @@ void InstantiationEngine::check( Theory::Effort e ){
                          << d_quantEngine->getModel()->getNumAssertedQuantifiers() << std::endl;
     for( int i=0; i<(int)d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
       Node n = d_quantEngine->getModel()->getAssertedQuantifier( i );
-      //it is not active if we have found the skolemized negation is unsat
+      //it is not active if it corresponds to a rewrite rule: we will process in rewrite engine
       if( TermDb::isRewriteRule( n ) ){
         d_quant_active[n] = false;
+      }else if( !d_quantEngine->getModel()->isQuantifierActive( n ) ){
+        d_quant_active[n] = false;
+      //it is not active if we have found the skolemized negation is unsat
       }else if( options::cbqi() && hasAddedCbqiLemma( n ) ){
         Node cel = d_quantEngine->getTermDatabase()->getCounterexampleLiteral( n );
         bool active, value;
@@ -248,7 +257,6 @@ void InstantiationEngine::check( Theory::Effort e ){
           Debug("quantifiers") << ", ce is asserted";
         }
         Debug("quantifiers") << std::endl;
-      //it is not active if it corresponds to a rewrite rule: we will process in rewrite engine
       }else{
         d_quant_active[n] = true;
         if( !TermDb::hasInstConstAttr(n) ){
index 112e052c2f3d74ee9ea6a8a93f6ebbd039eac361..26978c8f9e586dc6cd3c6949e5703b67001e36f6 100644 (file)
@@ -107,6 +107,15 @@ typedef enum {
   USER_PAT_MODE_IGNORE,
 } UserPatMode;
 
+typedef enum {
+  /** default for trigger selection */
+  TRIGGER_SEL_DEFAULT,
+  /** only consider minimal terms for triggers */
+  TRIGGER_SEL_MIN,
+  /** only consider maximal terms for triggers */
+  TRIGGER_SEL_MAX,
+} TriggerSelMode;
+
 }/* CVC4::theory::quantifiers namespace */
 }/* CVC4::theory namespace */
 
index 1cdf5e8bdffb4c88c52bdd9052185d5bd09c032d..e23e701749500cf9d9f8b0b84982d376c150c07e 100644 (file)
@@ -63,6 +63,8 @@ option relevantTriggers --relevant-triggers bool :default false
  prefer triggers that are more relevant based on SInE style analysis
 option relationalTriggers --relational-triggers bool :default false
  choose relational triggers such as x = f(y), x >= f(y)
+option triggerSelMode --trigger-sel CVC4::theory::quantifiers::TriggerSelMode :default CVC4::theory::quantifiers::TRIGGER_SEL_DEFAULT :read-write :include "theory/quantifiers/modes.h" :handler  CVC4::theory::quantifiers::stringToTriggerSelMode :handler-include "theory/quantifiers/options_handlers.h"
+ selection mode for triggers
 
 # Whether to consider terms in the bodies of quantifiers for matching
 option registerQuantBodyTerms --register-quant-body-terms bool :default false
@@ -76,6 +78,9 @@ option instMaxLevel --inst-max-level=N int :default -1
 option eagerInstQuant --eager-inst-quant bool :default false
  apply quantifier instantiation eagerly
 
+option instNoEntail --inst-no-entail bool :read-write :default false
+ do not consider instances of quantified formulas that are currently entailed
+
 option fullSaturateQuant --full-saturate-quant bool :default false
  when all other quantifier instantiation strategies fail, instantiate with ground terms from relevant domain, then arbitrary ground terms before answering unknown
 
@@ -140,6 +145,8 @@ option rrOneInstPerRound --rr-one-inst-per-round bool :default false
  add one instance of rewrite rule per round
 
 option dtStcInduction --dt-stc-ind bool :default false
- apply strengthening for existential quantification over datatypes based on structural induction
+ apply strengthening for existential quantification over datatypes based on structural 
+option conjectureGen --conjecture-gen bool :default false
+ generate candidate conjectures for inductive strengthening
 
 endmodule
index 38567d166ce1065c815bcd84a21460598688fa31..86d0c27e4c3528f3ac005dcc86b56e7f001ba4fe 100644 (file)
@@ -152,6 +152,19 @@ ignore \n\
 + Ignore user-provided patterns. \n\
 \n\
 ";
+static const std::string triggerSelModeHelp = "\
+User pattern modes currently supported by the --trigger-sel option:\n\
+\n\
+default \n\
++ Default, consider all subterms of quantified formulas for trigger selection.\n\
+\n\
+min \n\
++ Consider only minimal subterms that meet criteria for triggers.\n\
+\n\
+max \n\
++ Consider only maximal subterms that meet criteria for triggers. \n\
+\n\
+";
 inline InstWhenMode stringToInstWhenMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) {
   if(optarg == "pre-full") {
     return INST_WHEN_PRE_FULL;
@@ -296,6 +309,21 @@ inline UserPatMode stringToUserPatMode(std::string option, std::string optarg, S
                           optarg + "'.  Try --user-pat help.");
   }
 }
+inline TriggerSelMode stringToTriggerSelMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) {
+  if(optarg ==  "default" || optarg == "all" ) {
+    return TRIGGER_SEL_DEFAULT;
+  } else if(optarg == "min") {
+    return TRIGGER_SEL_MIN;
+  } else if(optarg == "max") {
+    return TRIGGER_SEL_MAX;
+  } else if(optarg ==  "help") {
+    puts(triggerSelModeHelp.c_str());
+    exit(1);
+  } else {
+    throw OptionException(std::string("unknown option for --trigger-sel: `") +
+                          optarg + "'.  Try --trigger-sel help.");
+  }
+}
 }/* CVC4::theory::quantifiers namespace */
 }/* CVC4::theory namespace */
 }/* CVC4 namespace */
old mode 100644 (file)
new mode 100755 (executable)
index c6e8819..4e4d92d
-/*********************                                                        */
-/*! \file quant_conflict_find.cpp
- ** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014  New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief quant conflict find class
- **
- **/
-
-#include <vector>
-
-#include "theory/quantifiers/quant_conflict_find.h"
-#include "theory/quantifiers/quant_util.h"
-#include "theory/theory_engine.h"
-#include "theory/quantifiers/options.h"
-#include "theory/quantifiers/term_database.h"
-#include "theory/quantifiers/trigger.h"
-
-using namespace CVC4;
-using namespace CVC4::kind;
-using namespace CVC4::theory;
-using namespace CVC4::theory::quantifiers;
-using namespace std;
-
-namespace CVC4 {
-
-Node QcfNodeIndex::existsTerm( TNode n, std::vector< TNode >& reps, int index ) {
-  if( index==(int)reps.size() ){
-    if( d_children.empty() ){
-      return Node::null();
-    }else{
-      return d_children.begin()->first;
-    }
-  }else{
-    std::map< TNode, QcfNodeIndex >::iterator it = d_children.find( reps[index] );
-    if( it==d_children.end() ){
-      return Node::null();
-    }else{
-      return it->second.existsTerm( n, reps, index+1 );
-    }
-  }
-}
-
-Node QcfNodeIndex::addTerm( TNode n, std::vector< TNode >& reps, int index ) {
-  if( index==(int)reps.size() ){
-    if( d_children.empty() ){
-      d_children[ n ].clear();
-      return n;
-    }else{
-      return d_children.begin()->first;
-    }
-  }else{
-    return d_children[reps[index]].addTerm( n, reps, index+1 );
-  }
-}
-
-
-void QcfNodeIndex::debugPrint( const char * c, int t ) {
-  for( std::map< TNode, QcfNodeIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){
-    if( !it->first.isNull() ){
-      for( int j=0; j<t; j++ ){ Trace(c) << "  "; }
-      Trace(c) << it->first << " : " << std::endl;
-      it->second.debugPrint( c, t+1 );
-    }
-  }
-}
-
-
-void QuantInfo::initialize( Node q, Node qn ) {
-  d_q = q;
-  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
-    d_match.push_back( TNode::null() );
-    d_match_term.push_back( TNode::null() );
-  }
-
-  //register the variables
-  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
-    d_var_num[q[0][i]] = i;
-    d_vars.push_back( q[0][i] );
-  }
-
-  registerNode( qn, true, true );
-
-
-  Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;
-  d_mg = new MatchGen( this, qn );
-
-  if( d_mg->isValid() ){
-    /*
-    for( unsigned j=0; j<q[0].getNumChildren(); j++ ){
-      if( d_inMatchConstraint.find( q[0][j] )==d_inMatchConstraint.end() ){
-        Trace("qcf-invalid") << "QCF invalid : variable " << q[0][j] << " does not exist in a matching constraint." << std::endl;
-        d_mg->setInvalid();
-        break;
-      }
-    }
-    */
-    if( d_mg->isValid() ){
-      for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){
-        if( d_vars[j].getKind()!=BOUND_VARIABLE ){
-          d_var_mg[j] = NULL;
-          bool is_tsym = false;
-          if( !MatchGen::isHandledUfTerm( d_vars[j] ) && d_vars[j].getKind()!=ITE ){
-            is_tsym = true;
-            d_tsym_vars.push_back( j );
-          }
-          if( !is_tsym || options::qcfTConstraint() ){
-            d_var_mg[j] = new MatchGen( this, d_vars[j], true );
-          }
-          if( !d_var_mg[j] || !d_var_mg[j]->isValid() ){
-            Trace("qcf-invalid") << "QCF invalid : cannot match for " << d_vars[j] << std::endl;
-            d_mg->setInvalid();
-            break;
-          }else{
-            std::vector< int > bvars;
-            d_var_mg[j]->determineVariableOrder( this, bvars );
-          }
-        }
-      }
-      if( d_mg->isValid() ){
-        std::vector< int > bvars;
-        d_mg->determineVariableOrder( this, bvars );
-      }
-    }
-  }else{
-    Trace("qcf-invalid") << "QCF invalid : body of formula cannot be processed." << std::endl;
-  }
-  Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? "VALID " : "INVALID" ) << " : " << q << std::endl;
-}
-
-void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant ) {
-  Trace("qcf-qregister-debug2") << "Register : " << n << std::endl;
-  if( n.getKind()==FORALL ){
-    registerNode( n[1], hasPol, pol, true );
-  }else{
-    if( !MatchGen::isHandledBoolConnective( n ) ){
-      if( n.hasBoundVar() ){
-        //literals
-        if( n.getKind()==EQUAL ){
-          for( unsigned i=0; i<n.getNumChildren(); i++ ){
-            flatten( n[i], beneathQuant );
-          }
-        }else if( MatchGen::isHandledUfTerm( n ) ){
-          flatten( n, beneathQuant );
-        }else if( n.getKind()==ITE ){
-          for( unsigned i=1; i<=2; i++ ){
-            flatten( n[i], beneathQuant );
-          }
-          registerNode( n[0], false, pol, beneathQuant );
-        }else if( options::qcfTConstraint() ){
-          //a theory-specific predicate
-          for( unsigned i=0; i<n.getNumChildren(); i++ ){
-            flatten( n[i], beneathQuant );
-          }
-        }
-      }
-    }else{
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){
-        bool newHasPol;
-        bool newPol;
-        QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );
-        //QcfNode * qcfc = new QcfNode( d_c );
-        //qcfc->d_parent = qcf;
-        //qcf->d_child[i] = qcfc;
-        registerNode( n[i], newHasPol, newPol, beneathQuant );
-      }
-    }
-  }
-}
-
-void QuantInfo::flatten( Node n, bool beneathQuant ) {
-  Trace("qcf-qregister-debug2") << "Flatten : " << n << std::endl;
-  if( n.hasBoundVar() ){
-    if( n.getKind()==BOUND_VARIABLE ){
-      d_inMatchConstraint[n] = true;
-    }
-    //if( MatchGen::isHandledUfTerm( n ) || n.getKind()==ITE ){
-    if( d_var_num.find( n )==d_var_num.end() ){
-      Trace("qcf-qregister-debug2") << "Add FLATTEN VAR : " << n << std::endl;
-      d_var_num[n] = d_vars.size();
-      d_vars.push_back( n );
-      d_match.push_back( TNode::null() );
-      d_match_term.push_back( TNode::null() );
-      if( n.getKind()==ITE ){
-        registerNode( n, false, false );
-      }else{
-        for( unsigned i=0; i<n.getNumChildren(); i++ ){
-          flatten( n[i], beneathQuant );
-        }
-      }
-    }else{
-      Trace("qcf-qregister-debug2") << "...already processed" << std::endl;
-    }
-  }else{
-    Trace("qcf-qregister-debug2") << "...is ground." << std::endl;
-  }
-}
-
-
-void QuantInfo::reset_round( QuantConflictFind * p ) {
-  for( unsigned i=0; i<d_match.size(); i++ ){
-    d_match[i] = TNode::null();
-    d_match_term[i] = TNode::null();
-  }
-  d_curr_var_deq.clear();
-  d_tconstraints.clear();
-  //add built-in variable constraints
-  for( unsigned r=0; r<2; r++ ){
-    for( std::map< int, std::vector< Node > >::iterator it = d_var_constraint[r].begin();
-         it != d_var_constraint[r].end(); ++it ){
-      for( unsigned j=0; j<it->second.size(); j++ ){
-        Node rr = it->second[j];
-        if( !isVar( rr ) ){
-          rr = p->getRepresentative( rr );
-        }
-        if( addConstraint( p, it->first, rr, r==0 )==-1 ){
-          d_var_constraint[0].clear();
-          d_var_constraint[1].clear();
-          //quantified formula is actually equivalent to true
-          Trace("qcf-qregister") << "Quantifier is equivalent to true!!!" << std::endl;
-          d_mg->d_children.clear();
-          d_mg->d_n = NodeManager::currentNM()->mkConst( true );
-          d_mg->d_type = MatchGen::typ_ground;
-          return;
-        }
-      }
-    }
-  }
-  d_mg->reset_round( p );
-  for( std::map< int, MatchGen * >::iterator it = d_var_mg.begin(); it != d_var_mg.end(); ++it ){
-    it->second->reset_round( p );
-  }
-  //now, reset for matching
-  d_mg->reset( p, false, this );
-}
-
-int QuantInfo::getCurrentRepVar( int v ) {
-  if( v!=-1 && !d_match[v].isNull() ){
-    int vn = getVarNum( d_match[v] );
-    if( vn!=-1 ){
-      //int vr = getCurrentRepVar( vn );
-      //d_match[v] = d_vars[vr];
-      //return vr;
-      return getCurrentRepVar( vn );
-    }
-  }
-  return v;
-}
-
-TNode QuantInfo::getCurrentValue( TNode n ) {
-  int v = getVarNum( n );
-  if( v==-1 ){
-    return n;
-  }else{
-    if( d_match[v].isNull() ){
-      return n;
-    }else{
-      Assert( getVarNum( d_match[v] )!=v );
-      return getCurrentValue( d_match[v] );
-    }
-  }
-}
-
-TNode QuantInfo::getCurrentExpValue( TNode n ) {
-  int v = getVarNum( n );
-  if( v==-1 ){
-    return n;
-  }else{
-    if( d_match[v].isNull() ){
-      return n;
-    }else{
-      Assert( getVarNum( d_match[v] )!=v );
-      if( d_match_term[v].isNull() ){
-        return getCurrentValue( d_match[v] );
-      }else{
-        return d_match_term[v];
-      }
-    }
-  }
-}
-
-bool QuantInfo::getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq ) {
-  //check disequalities
-  std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );
-  if( itd!=d_curr_var_deq.end() ){
-    for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
-      Node cv = getCurrentValue( it->first );
-      Debug("qcf-ccbe") << "compare " << cv << " " << n << std::endl;
-      if( cv==n ){
-        return false;
-      }else if( chDiseq && !isVar( n ) && !isVar( cv ) ){
-        //they must actually be disequal if we are looking for conflicts
-        if( !p->areDisequal( n, cv ) ){
-          //TODO : check for entailed disequal
-
-          return false;
-        }
-      }
-    }
-  }
-  return true;
-}
-
-int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity ) {
-  v = getCurrentRepVar( v );
-  int vn = getVarNum( n );
-  vn = vn==-1 ? -1 : getCurrentRepVar( vn );
-  n = getCurrentValue( n );
-  return addConstraint( p, v, n, vn, polarity, false );
-}
-
-int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove ) {
-  //for handling equalities between variables, and disequalities involving variables
-  Debug("qcf-match-debug") << "- " << (doRemove ? "un" : "" ) << "constrain : " << v << " -> " << n << " (cv=" << getCurrentValue( n ) << ")";
-  Debug("qcf-match-debug") << ", (vn=" << vn << "), polarity = " << polarity << std::endl;
-  Assert( doRemove || n==getCurrentValue( n ) );
-  Assert( doRemove || v==getCurrentRepVar( v ) );
-  Assert( doRemove || vn==getCurrentRepVar( getVarNum( n ) ) );
-  if( polarity ){
-    if( vn!=v ){
-      if( doRemove ){
-        if( vn!=-1 ){
-          //if set to this in the opposite direction, clean up opposite instead
-          //          std::map< int, TNode >::iterator itmn = d_match.find( vn );
-          if( d_match[vn]==d_vars[v] ){
-            return addConstraint( p, vn, d_vars[v], v, true, true );
-          }else{
-            //unsetting variables equal
-            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( vn );
-            if( itd!=d_curr_var_deq.end() ){
-              //remove disequalities owned by this
-              std::vector< TNode > remDeq;
-              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
-                if( it->second==v ){
-                  remDeq.push_back( it->first );
-                }
-              }
-              for( unsigned i=0; i<remDeq.size(); i++ ){
-                d_curr_var_deq[vn].erase( remDeq[i] );
-              }
-            }
-          }
-        }
-        d_match[v] = TNode::null();
-        return 1;
-      }else{
-        //std::map< int, TNode >::iterator itm = d_match.find( v );
-
-        if( vn!=-1 ){
-          Debug("qcf-match-debug") << "  ...Variable bound to variable" << std::endl;
-          //std::map< int, TNode >::iterator itmn = d_match.find( vn );
-          if( d_match[v].isNull() ){
-            //setting variables equal
-            bool alreadySet = false;
-            if( !d_match[vn].isNull() ){
-              alreadySet = true;
-              Assert( !isVar( d_match[vn] ) );
-            }
-
-            //copy or check disequalities
-            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );
-            if( itd!=d_curr_var_deq.end() ){
-              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
-                Node dv = getCurrentValue( it->first );
-                if( !alreadySet ){
-                  if( d_curr_var_deq[vn].find( dv )==d_curr_var_deq[vn].end() ){
-                    d_curr_var_deq[vn][dv] = v;
-                  }
-                }else{
-                  if( !p->areMatchDisequal( d_match[vn], dv ) ){
-                    Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
-                    return -1;
-                  }
-                }
-              }
-            }
-            if( alreadySet ){
-              n = getCurrentValue( n );
-            }
-          }else{
-            if( d_match[vn].isNull() ){
-              Debug("qcf-match-debug") << " ...Reverse direction" << std::endl;
-              //set the opposite direction
-              return addConstraint( p, vn, d_vars[v], v, true, false );
-            }else{
-              Debug("qcf-match-debug") << "  -> Both variables bound, compare" << std::endl;
-              //are they currently equal
-              return p->areMatchEqual( d_match[v], d_match[vn] ) ? 0 : -1;
-            }
-          }
-        }else{
-          Debug("qcf-match-debug") << "  ...Variable bound to ground" << std::endl;
-          if( d_match[v].isNull() ){
-          }else{
-            //compare ground values
-            Debug("qcf-match-debug") << "  -> Ground value, compare " << d_match[v] << " "<< n << std::endl;
-            return p->areMatchEqual( d_match[v], n ) ? 0 : -1;
-          }
-        }
-        if( setMatch( p, v, n ) ){
-          Debug("qcf-match-debug") << "  -> success" << std::endl;
-          return 1;
-        }else{
-          Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
-          return -1;
-        }
-      }
-    }else{
-      Debug("qcf-match-debug") << "  -> redundant, variable identity" << std::endl;
-      return 0;
-    }
-  }else{
-    if( vn==v ){
-      Debug("qcf-match-debug") << "  -> fail, variable identity" << std::endl;
-      return -1;
-    }else{
-      if( doRemove ){
-        Assert( d_curr_var_deq[v].find( n )!=d_curr_var_deq[v].end() );
-        d_curr_var_deq[v].erase( n );
-        return 1;
-      }else{
-        if( d_curr_var_deq[v].find( n )==d_curr_var_deq[v].end() ){
-          //check if it respects equality
-          //std::map< int, TNode >::iterator itm = d_match.find( v );
-          if( !d_match[v].isNull() ){
-            TNode nv = getCurrentValue( n );
-            if( !p->areMatchDisequal( nv, d_match[v] ) ){
-              Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
-              return -1;
-            }
-          }
-          d_curr_var_deq[v][n] = v;
-          Debug("qcf-match-debug") << "  -> success" << std::endl;
-          return 1;
-        }else{
-          Debug("qcf-match-debug") << "  -> redundant disequality" << std::endl;
-          return 0;
-        }
-      }
-    }
-  }
-}
-
-bool QuantInfo::isConstrainedVar( int v ) {
-  if( d_curr_var_deq.find( v )!=d_curr_var_deq.end() && !d_curr_var_deq[v].empty() ){
-    return true;
-  }else{
-    Node vv = getVar( v );
-    //for( std::map< int, TNode >::iterator it = d_match.begin(); it != d_match.end(); ++it ){
-    for( unsigned i=0; i<d_match.size(); i++ ){
-      if( d_match[i]==vv ){
-        return true;
-      }
-    }
-    for( std::map< int, std::map< TNode, int > >::iterator it = d_curr_var_deq.begin(); it != d_curr_var_deq.end(); ++it ){
-      for( std::map< TNode, int >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
-        if( it2->first==vv ){
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-}
-
-bool QuantInfo::setMatch( QuantConflictFind * p, int v, TNode n ) {
-  if( getCurrentCanBeEqual( p, v, n ) ){
-    Debug("qcf-match-debug") << "-- bind : " << v << " -> " << n << ", checked " <<  d_curr_var_deq[v].size() << " disequalities" << std::endl;
-    d_match[v] = n;
-    return true;
-  }else{
-    return false;
-  }
-}
-
-bool QuantInfo::isMatchSpurious( QuantConflictFind * p ) {
-  for( int i=0; i<getNumVars(); i++ ){
-    //std::map< int, TNode >::iterator it = d_match.find( i );
-    if( !d_match[i].isNull() ){
-      if( !getCurrentCanBeEqual( p, i, d_match[i], p->d_effort==QuantConflictFind::effort_conflict ) ){
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-bool QuantInfo::isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms ) {
-  if( !d_tconstraints.empty() ){
-    //check constraints
-    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){
-      //apply substitution to the tconstraint
-      Node cons = it->first.substitute( p->getQuantifiersEngine()->getTermDatabase()->d_vars[d_q].begin(),
-                                        p->getQuantifiersEngine()->getTermDatabase()->d_vars[d_q].end(),
-                                        terms.begin(), terms.end() );
-      cons = it->second ? cons : cons.negate();
-      if( !entailmentTest( p, cons, p->d_effort==QuantConflictFind::effort_conflict ) ){
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-bool QuantInfo::entailmentTest( QuantConflictFind * p, Node lit, bool chEnt ) {
-  Trace("qcf-tconstraint-debug") << "Check : " << lit << std::endl;
-  Node rew = Rewriter::rewrite( lit );
-  if( rew==p->d_false ){
-    Trace("qcf-tconstraint-debug") << "...constraint " << lit << " is disentailed (rewrites to false)." << std::endl;
-    return false;
-  }else if( rew!=p->d_true ){
-    //if checking for conflicts, we must be sure that the constraint is entailed
-    if( chEnt ){
-      //check if it is entailed
-      Trace("qcf-tconstraint-debug") << "Check entailment of " << rew << "..." << std::endl;
-      std::pair<bool, Node> et = p->getQuantifiersEngine()->getTheoryEngine()->entailmentCheck(THEORY_OF_TYPE_BASED, rew );
-      ++(p->d_statistics.d_entailment_checks);
-      Trace("qcf-tconstraint-debug") << "ET result : " << et.first << " " << et.second << std::endl;
-      if( !et.first ){
-        Trace("qcf-tconstraint-debug") << "...cannot show entailment of " << rew << "." << std::endl;
-        return false;
-      }else{
-        return true;
-      }
-    }else{
-      Trace("qcf-tconstraint-debug") << "...does not need to be entailed." << std::endl;
-      return true;
-    }
-  }else{
-    Trace("qcf-tconstraint-debug") << "...rewrites to true." << std::endl;
-    return true;
-  }
-}
-
-bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue ) {
-  //assign values for variables that were unassigned (usually not necessary, but handles corner cases)
-  bool doFail = false;
-  bool success = true;
-  if( doContinue ){
-    doFail = true;
-    success = false;
-  }else{
-    //solve for interpreted symbol matches
-    //   this breaks the invariant that all introduced constraints are over existing terms
-    for( int i=(int)(d_tsym_vars.size()-1); i>=0; i-- ){
-      int index = d_tsym_vars[i];
-      TNode v = getCurrentValue( d_vars[index] );
-      int slv_v = -1;
-      if( v==d_vars[index] ){
-        slv_v = index;
-      }
-      Trace("qcf-tconstraint-debug") << "Solve " << d_vars[index] << " = " << v << " " << d_vars[index].getKind() << std::endl;
-      if( d_vars[index].getKind()==PLUS || d_vars[index].getKind()==MULT ){
-        Kind k = d_vars[index].getKind();
-        std::vector< TNode > children;
-        for( unsigned j=0; j<d_vars[index].getNumChildren(); j++ ){
-          int vn = getVarNum( d_vars[index][j] );
-          if( vn!=-1 ){
-            TNode vv = getCurrentValue( d_vars[index][j] );
-            if( vv==d_vars[index][j] ){
-              //we will assign this
-              if( slv_v==-1 ){
-                Trace("qcf-tconstraint-debug") << "...will solve for var #" << vn << std::endl;
-                slv_v = vn;
-                if( p->d_effort!=QuantConflictFind::effort_conflict ){
-                  break;
-                }
-              }else{
-                Node z = p->getZero( k );
-                if( !z.isNull() ){
-                  Trace("qcf-tconstraint-debug") << "...set " << d_vars[vn] << " = " << z << std::endl;
-                  assigned.push_back( vn );
-                  if( !setMatch( p, vn, z ) ){
-                    success = false;
-                    break;
-                  }
-                }
-              }
-            }else{
-              Trace("qcf-tconstraint-debug") << "...sum value " << vv << std::endl;
-              children.push_back( vv );
-            }
-          }else{
-            Trace("qcf-tconstraint-debug") << "...sum " << d_vars[index][j] << std::endl;
-            children.push_back( d_vars[index][j] );
-          }
-        }
-        if( success ){
-          if( slv_v!=-1 ){
-            Node lhs;
-            if( children.empty() ){
-              lhs = p->getZero( k );
-            }else if( children.size()==1 ){
-              lhs = children[0];
-            }else{
-              lhs = NodeManager::currentNM()->mkNode( k, children );
-            }
-            Node sum;
-            if( v==d_vars[index] ){
-              sum = lhs;
-            }else{
-              if( p->d_effort==QuantConflictFind::effort_conflict ){
-                Kind kn = k;
-                if( d_vars[index].getKind()==PLUS ){
-                  kn = MINUS;
-                }
-                if( kn!=k ){
-                  sum = NodeManager::currentNM()->mkNode( kn, v, lhs );
-                }
-              }
-            }
-            if( !sum.isNull() ){
-              assigned.push_back( slv_v );
-              Trace("qcf-tconstraint-debug") << "...set " << d_vars[slv_v] << " = " << sum << std::endl;
-              if( !setMatch( p, slv_v, sum ) ){
-                success = false;
-              }
-              p->d_tempCache.push_back( sum );
-            }
-          }else{
-            //must show that constraint is met
-            Node sum = NodeManager::currentNM()->mkNode( k, children );
-            Node eq = sum.eqNode( v );
-            if( !entailmentTest( p, eq ) ){
-              success = false;
-            }
-            p->d_tempCache.push_back( sum );
-          }
-        }
-      }
-
-      if( !success ){
-        break;
-      }
-    }
-    if( success ){
-      //check what is left to assign
-      d_unassigned.clear();
-      d_unassigned_tn.clear();
-      std::vector< int > unassigned[2];
-      std::vector< TypeNode > unassigned_tn[2];
-      for( int i=0; i<getNumVars(); i++ ){
-        if( d_match[i].isNull() ){
-          int rindex = d_var_mg.find( i )==d_var_mg.end() ? 1 : 0;
-          unassigned[rindex].push_back( i );
-          unassigned_tn[rindex].push_back( getVar( i ).getType() );
-          assigned.push_back( i );
-        }
-      }
-      d_unassigned_nvar = unassigned[0].size();
-      for( unsigned i=0; i<2; i++ ){
-        d_unassigned.insert( d_unassigned.end(), unassigned[i].begin(), unassigned[i].end() );
-        d_unassigned_tn.insert( d_unassigned_tn.end(), unassigned_tn[i].begin(), unassigned_tn[i].end() );
-      }
-      d_una_eqc_count.clear();
-      d_una_index = 0;
-    }
-  }
-
-  if( !d_unassigned.empty() && ( success || doContinue ) ){
-    Trace("qcf-check") << "Assign to unassigned..." << std::endl;
-    do {
-      if( doFail ){
-        Trace("qcf-check-unassign") << "Failure, try again..." << std::endl;
-      }
-      bool invalidMatch = false;
-      while( ( d_una_index>=0 && (int)d_una_index<(int)d_unassigned.size() ) || invalidMatch || doFail ){
-        invalidMatch = false;
-        if( !doFail && d_una_index==(int)d_una_eqc_count.size() ){
-          //check if it has now been assigned
-          if( d_una_index<d_unassigned_nvar ){
-            if( !isConstrainedVar( d_unassigned[d_una_index] ) ){
-              d_una_eqc_count.push_back( -1 );
-            }else{
-              d_var_mg[ d_unassigned[d_una_index] ]->reset( p, true, this );
-              d_una_eqc_count.push_back( 0 );
-            }
-          }else{
-            d_una_eqc_count.push_back( 0 );
-          }
-        }else{
-          bool failed = false;
-          if( !doFail ){
-            if( d_una_index<d_unassigned_nvar ){
-              if( !isConstrainedVar( d_unassigned[d_una_index] ) ){
-                Trace("qcf-check-unassign") << "Succeeded, variable unconstrained at " << d_una_index << std::endl;
-                d_una_index++;
-              }else if( d_var_mg[d_unassigned[d_una_index]]->getNextMatch( p, this ) ){
-                Trace("qcf-check-unassign") << "Succeeded match with mg at " << d_una_index << std::endl;
-                d_una_index++;
-              }else{
-                failed = true;
-                Trace("qcf-check-unassign") << "Failed match with mg at " << d_una_index << std::endl;
-              }
-            }else{
-              Assert( doFail || d_una_index==(int)d_una_eqc_count.size()-1 );
-              if( d_una_eqc_count[d_una_index]<(int)p->d_eqcs[d_unassigned_tn[d_una_index]].size() ){
-                int currIndex = d_una_eqc_count[d_una_index];
-                d_una_eqc_count[d_una_index]++;
-                Trace("qcf-check-unassign") << d_unassigned[d_una_index] << "->" << p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] << std::endl;
-                if( setMatch( p, d_unassigned[d_una_index], p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] ) ){
-                  d_match_term[d_unassigned[d_una_index]] = TNode::null();
-                  Trace("qcf-check-unassign") << "Succeeded match " << d_una_index << std::endl;
-                  d_una_index++;
-                }else{
-                  Trace("qcf-check-unassign") << "Failed match " << d_una_index << std::endl;
-                  invalidMatch = true;
-                }
-              }else{
-                failed = true;
-                Trace("qcf-check-unassign") << "No more matches " << d_una_index << std::endl;
-              }
-            }
-          }
-          if( doFail || failed ){
-            do{
-              if( !doFail ){
-                d_una_eqc_count.pop_back();
-              }else{
-                doFail = false;
-              }
-              d_una_index--;
-            }while( d_una_index>=0 && d_una_eqc_count[d_una_index]==-1 );
-          }
-        }
-      }
-      success = d_una_index>=0;
-      if( success ){
-        doFail = true;
-        Trace("qcf-check-unassign") << "  Try: " << std::endl;
-        for( unsigned i=0; i<d_unassigned.size(); i++ ){
-          int ui = d_unassigned[i];
-          if( !d_match[ui].isNull() ){
-            Trace("qcf-check-unassign") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;
-          }
-        }
-      }
-    }while( success && isMatchSpurious( p ) );
-  }
-  if( success ){
-    for( unsigned i=0; i<d_unassigned.size(); i++ ){
-      int ui = d_unassigned[i];
-      if( !d_match[ui].isNull() ){
-        Trace("qcf-check") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;
-      }
-    }
-    return true;
-  }else{
-    for( unsigned i=0; i<assigned.size(); i++ ){
-      d_match[ assigned[i] ] = TNode::null();
-    }
-    assigned.clear();
-    return false;
-  }
-}
-
-void QuantInfo::getMatch( std::vector< Node >& terms ){
-  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){
-    //Node cv = qi->getCurrentValue( qi->d_match[i] );
-    int repVar = getCurrentRepVar( i );
-    Node cv;
-    //std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );
-    if( !d_match_term[repVar].isNull() ){
-      cv = d_match_term[repVar];
-    }else{
-      cv = d_match[repVar];
-    }
-    Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << d_match[i] << std::endl;
-    terms.push_back( cv );
-  }
-}
-
-void QuantInfo::revertMatch( std::vector< int >& assigned ) {
-  for( unsigned i=0; i<assigned.size(); i++ ){
-    d_match[ assigned[i] ] = TNode::null();
-  }
-}
-
-void QuantInfo::debugPrintMatch( const char * c ) {
-  for( int i=0; i<getNumVars(); i++ ){
-    Trace(c) << "  " << d_vars[i] << " -> ";
-    if( !d_match[i].isNull() ){
-      Trace(c) << d_match[i];
-    }else{
-      Trace(c) << "(unassigned) ";
-    }
-    if( !d_curr_var_deq[i].empty() ){
-      Trace(c) << ", DEQ{ ";
-      for( std::map< TNode, int >::iterator it = d_curr_var_deq[i].begin(); it != d_curr_var_deq[i].end(); ++it ){
-        Trace(c) << it->first << " ";
-      }
-      Trace(c) << "}";
-    }
-    if( !d_match_term[i].isNull() && d_match_term[i]!=d_match[i] ){
-      Trace(c) << ", EXP : " << d_match_term[i];
-    }
-    Trace(c) <<  std::endl;
-  }
-  if( !d_tconstraints.empty() ){
-    Trace(c) << "ADDITIONAL CONSTRAINTS : " << std::endl;
-    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){
-      Trace(c) << "   " << it->first << " -> " << it->second << std::endl;
-    }
-  }
-}
-
-MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar ){
-  Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << std::endl;
-  std::vector< Node > qni_apps;
-  d_qni_size = 0;
-  if( isVar ){
-    Assert( qi->d_var_num.find( n )!=qi->d_var_num.end() );
-    if( n.getKind()==ITE ){
-      d_type = typ_ite_var;
-      d_type_not = false;
-      d_n = n;
-      d_children.push_back( MatchGen( qi, d_n[0] ) );
-      if( d_children[0].isValid() ){
-        d_type = typ_ite_var;
-        for( unsigned i=1; i<=2; i++ ){
-          Node nn = n.eqNode( n[i] );
-          d_children.push_back( MatchGen( qi, nn ) );
-          d_children[d_children.size()-1].d_qni_bound_except.push_back( 0 );
-          if( !d_children[d_children.size()-1].isValid() ){
-            setInvalid();
-            break;
-          }
-        }
-      }else{
-        d_type = typ_invalid;
-      }
-    }else{
-      d_type = isHandledUfTerm( n ) ? typ_var : typ_tsym;
-      d_qni_var_num[0] = qi->getVarNum( n );
-      d_qni_size++;
-      d_type_not = false;
-      d_n = n;
-      //Node f = getOperator( n );
-      for( unsigned j=0; j<d_n.getNumChildren(); j++ ){
-        Node nn = d_n[j];
-        Trace("qcf-qregister-debug") << "  " << d_qni_size;
-        if( qi->isVar( nn ) ){
-          int v = qi->d_var_num[nn];
-          Trace("qcf-qregister-debug") << " is var #" << v << std::endl;
-          d_qni_var_num[d_qni_size] = v;
-          //qi->addFuncParent( v, f, j );
-        }else{
-          Trace("qcf-qregister-debug") << " is gterm " << nn << std::endl;
-          d_qni_gterm[d_qni_size] = nn;
-        }
-        d_qni_size++;
-      }
-    }
-  }else{
-    if( n.hasBoundVar() ){
-      d_type_not = false;
-      d_n = n;
-      if( d_n.getKind()==NOT ){
-        d_n = d_n[0];
-        d_type_not = !d_type_not;
-      }
-
-      if( isHandledBoolConnective( d_n ) ){
-        //non-literals
-        d_type = typ_formula;
-        for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
-          if( d_n.getKind()!=FORALL || i==1 ){
-            d_children.push_back( MatchGen( qi, d_n[i], false ) );
-            if( !d_children[d_children.size()-1].isValid() ){
-              setInvalid();
-              break;
-            }
-          }
-          /*
-          else if( isTop && n.getKind()==OR && d_children[d_children.size()-1].d_type==typ_var_eq ){
-            Trace("qcf-qregister-debug") << "Remove child, make built-in constraint" << std::endl;
-            //if variable equality/disequality at top level, remove immediately
-            bool cIsNot = d_children[d_children.size()-1].d_type_not;
-            Node cn = d_children[d_children.size()-1].d_n;
-            Assert( cn.getKind()==EQUAL );
-            Assert( p->d_qinfo[q].isVar( cn[0] ) || p->d_qinfo[q].isVar( cn[1] ) );
-            //make it a built-in constraint instead
-            for( unsigned i=0; i<2; i++ ){
-              if( p->d_qinfo[q].isVar( cn[i] ) ){
-                int v = p->d_qinfo[q].getVarNum( cn[i] );
-                Node cno = cn[i==0 ? 1 : 0];
-                p->d_qinfo[q].d_var_constraint[ cIsNot ? 0 : 1 ][v].push_back( cno );
-                break;
-              }
-            }
-            d_children.pop_back();
-          }
-          */
-        }
-      }else{
-        d_type = typ_invalid;
-        //literals
-        if( isHandledUfTerm( d_n ) ){
-          Assert( qi->isVar( d_n ) );
-          d_type = typ_pred;
-        }else if( d_n.getKind()==BOUND_VARIABLE ){
-          Assert( d_n.getType().isBoolean() );
-          d_type = typ_bool_var;
-        }else if( d_n.getKind()==EQUAL || options::qcfTConstraint() ){
-          for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
-            if( d_n[i].hasBoundVar() ){
-              if( !qi->isVar( d_n[i] ) ){
-                Trace("qcf-qregister-debug")  << "ERROR : not var " << d_n[i] << std::endl;
-              }
-              Assert( qi->isVar( d_n[i] ) );
-              if( d_n.getKind()!=EQUAL && qi->isVar( d_n[i] ) ){
-                d_qni_var_num[i+1] = qi->d_var_num[d_n[i]];
-              }
-            }else{
-              d_qni_gterm[i] = d_n[i];
-            }
-          }
-          d_type = d_n.getKind()==EQUAL ? typ_eq : typ_tconstraint;
-          Trace("qcf-tconstraint") << "T-Constraint : " << d_n << std::endl;
-        }
-      }
-    }else{
-      //we will just evaluate
-      d_n = n;
-      d_type = typ_ground;
-    }
-    //if( d_type!=typ_invalid ){
-      //determine an efficient children ordering
-      //if( !d_children.empty() ){
-        //for( unsigned i=0; i<d_children.size(); i++ ){
-        //  d_children_order.push_back( i );
-        //}
-        //if( !d_n.isNull() && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF ) ){
-          //sort based on the type of the constraint : ground comes first, then literals, then others
-          //MatchGenSort mgs;
-          //mgs.d_mg = this;
-          //std::sort( d_children_order.begin(), d_children_order.end(), mgs );
-        //}
-      //}
-    //}
-  }
-  Trace("qcf-qregister-debug")  << "Done make match gen " << n << ", type = ";
-  debugPrintType( "qcf-qregister-debug", d_type, true );
-  Trace("qcf-qregister-debug") << std::endl;
-  //Assert( d_children.size()==d_children_order.size() );
-
-}
-
-void MatchGen::collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ) {
-  int v = qi->getVarNum( n );
-  if( v!=-1 && std::find( cbvars.begin(), cbvars.end(), v )==cbvars.end() ){
-    cbvars.push_back( v );
-  }
-  for( unsigned i=0; i<n.getNumChildren(); i++ ){
-    collectBoundVar( qi, n[i], cbvars );
-  }
-}
-
-void MatchGen::determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars ) {
-  Trace("qcf-qregister-debug") << "Determine variable order " << d_n << std::endl;
-  bool isCom = d_type==typ_formula && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF );
-  std::map< int, std::vector< int > > c_to_vars;
-  std::map< int, std::vector< int > > vars_to_c;
-  std::map< int, int > vb_count;
-  std::map< int, int > vu_count;
-  std::vector< bool > assigned;
-  Trace("qcf-qregister-debug") << "Calculate bound variables..." << std::endl;
-  for( unsigned i=0; i<d_children.size(); i++ ){
-    collectBoundVar( qi, d_children[i].d_n, c_to_vars[i] );
-    assigned.push_back( false );
-    vb_count[i] = 0;
-    vu_count[i] = 0;
-    for( unsigned j=0; j<c_to_vars[i].size(); j++ ){
-      int v = c_to_vars[i][j];
-      vars_to_c[v].push_back( i );
-      if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){
-        vu_count[i]++;
-        if( !isCom ){
-          bvars.push_back( v );
-        }
-      }else{
-        vb_count[i]++;
-      }
-    }
-  }
-  if( isCom ){
-    //children that bind the least number of unbound variables go first
-    do {
-      int min_score = -1;
-      int min_score_index = -1;
-      for( unsigned i=0; i<d_children.size(); i++ ){
-        if( !assigned[i] ){
-          int score = vu_count[i];
-          if( min_score==-1 || score<min_score ){
-            min_score = score;
-            min_score_index = i;
-          }
-        }
-      }
-      Trace("qcf-qregister-debug") << "...assign child " << min_score_index << "/" << d_children.size() << std::endl;
-      Assert( min_score_index!=-1 );
-      //add to children order
-      d_children_order.push_back( min_score_index );
-      assigned[min_score_index] = true;
-      //if( vb_count[min_score_index]==0 ){
-      //  d_independent.push_back( min_score_index );
-      //}
-      //determine order internal to children
-      d_children[min_score_index].determineVariableOrder( qi, bvars );
-      Trace("qcf-qregister-debug")  << "...bind variables" << std::endl;
-      //now, make it a bound variable
-      for( unsigned i=0; i<c_to_vars[min_score_index].size(); i++ ){
-        int v = c_to_vars[min_score_index][i];
-        if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){
-          for( unsigned j=0; j<vars_to_c[v].size(); j++ ){
-            int vc = vars_to_c[v][j];
-            vu_count[vc]--;
-            vb_count[vc]++;
-          }
-          bvars.push_back( v );
-        }
-      }
-      Trace("qcf-qregister-debug") << "...done assign child " << min_score_index << std::endl;
-    }while( d_children_order.size()!=d_children.size() );
-    Trace("qcf-qregister-debug") << "Done assign variable ordering for " << d_n << std::endl;
-  }else{
-    for( unsigned i=0; i<d_children.size(); i++ ){
-      d_children_order.push_back( i );
-      d_children[i].determineVariableOrder( qi, bvars );
-    }
-  }
-}
-
-
-void MatchGen::reset_round( QuantConflictFind * p ) {
-  d_wasSet = false;
-  for( unsigned i=0; i<d_children.size(); i++ ){
-    d_children[i].reset_round( p );
-  }
-  for( std::map< int, TNode >::iterator it = d_qni_gterm.begin(); it != d_qni_gterm.end(); ++it ){
-    d_qni_gterm_rep[it->first] = p->getRepresentative( it->second );
-  }
-  if( d_type==typ_ground ){
-    int e = p->evaluate( d_n );
-    if( e==1 ){
-      d_ground_eval[0] = p->d_true;
-    }else if( e==-1 ){
-      d_ground_eval[0] = p->d_false;
-    }
-  }else if( d_type==typ_eq ){
-    for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
-      if( !d_n[i].hasBoundVar() ){
-        d_ground_eval[i] = p->evaluateTerm( d_n[i] );
-      }
-    }
-  }
-  d_qni_bound_cons.clear();
-  d_qni_bound_cons_var.clear();
-  d_qni_bound.clear();
-}
-
-void MatchGen::reset( QuantConflictFind * p, bool tgt, QuantInfo * qi ) {
-  d_tgt = d_type_not ? !tgt : tgt;
-  Debug("qcf-match") << "     Reset for : " << d_n << ", type : ";
-  debugPrintType( "qcf-match", d_type );
-  Debug("qcf-match") << ", tgt = " << d_tgt << ", children = " << d_children.size() << " " << d_children_order.size() << std::endl;
-  d_qn.clear();
-  d_qni.clear();
-  d_qni_bound.clear();
-  d_child_counter = -1;
-  d_tgt_orig = d_tgt;
-
-  //set up processing matches
-  if( d_type==typ_invalid ){
-    //do nothing
-  }else if( d_type==typ_ground ){
-    if( d_ground_eval[0]==( d_tgt ? p->d_true : p->d_false ) ){
-      d_child_counter = 0;
-    }
-  }else if( d_type==typ_bool_var ){
-    //get current value of the variable
-    TNode n = qi->getCurrentValue( d_n );
-    int vn = qi->getCurrentRepVar( qi->getVarNum( n ) );
-    if( vn==-1 ){
-      //evaluate the value, see if it is compatible
-      int e = p->evaluate( n );
-      if( ( e==1 && d_tgt ) || ( e==0 && !d_tgt ) ){
-        d_child_counter = 0;
-      }
-    }else{
-      //unassigned, set match to true/false
-      d_qni_bound[0] = vn;
-      qi->setMatch( p, vn, d_tgt ? p->d_true : p->d_false );
-      d_child_counter = 0;
-    }
-    if( d_child_counter==0 ){
-      d_qn.push_back( NULL );
-    }
-  }else if( d_type==typ_var ){
-    Assert( isHandledUfTerm( d_n ) );
-    Node f = getOperator( p, d_n );
-    Debug("qcf-match-debug") << "       reset: Var will match operators of " << f << std::endl;
-    QcfNodeIndex * qni = p->getQcfNodeIndex( Node::null(), f );
-    if( qni!=NULL ){
-      d_qn.push_back( qni );
-    }
-    d_matched_basis = false;
-  }else if( d_type==typ_tsym || d_type==typ_tconstraint ){
-    for( std::map< int, int >::iterator it = d_qni_var_num.begin(); it != d_qni_var_num.end(); ++it ){
-      int repVar = qi->getCurrentRepVar( it->second );
-      if( qi->d_match[repVar].isNull() ){
-        Debug("qcf-match-debug") << "Force matching on child #" << it->first << ", which is var #" << repVar << std::endl;
-        d_qni_bound[it->first] = repVar;
-      }
-    }
-    d_qn.push_back( NULL );
-  }else if( d_type==typ_pred || d_type==typ_eq ){
-    //add initial constraint
-    Node nn[2];
-    int vn[2];
-    if( d_type==typ_pred ){
-      nn[0] = qi->getCurrentValue( d_n );
-      vn[0] = qi->getCurrentRepVar( qi->getVarNum( nn[0] ) );
-      nn[1] = p->getRepresentative( d_tgt ? p->d_true : p->d_false );
-      vn[1] = -1;
-      d_tgt = true;
-    }else{
-      for( unsigned i=0; i<2; i++ ){
-        TNode nc;
-        std::map< int, TNode >::iterator it = d_qni_gterm_rep.find( i );
-        if( it!=d_qni_gterm_rep.end() ){
-          nc = it->second;
-        }else{
-          nc = d_n[i];
-        }
-        nn[i] = qi->getCurrentValue( nc );
-        vn[i] = qi->getCurrentRepVar( qi->getVarNum( nn[i] ) );
-      }
-    }
-    bool success;
-    if( vn[0]==-1 && vn[1]==-1 ){
-      //Trace("qcf-explain") << "    reset : " << d_n << " check ground values " << nn[0] << " " << nn[1] << " (tgt=" << d_tgt << ")" << std::endl;
-      Debug("qcf-match-debug") << "       reset: check ground values " << nn[0] << " " << nn[1] << " (" << d_tgt << ")" << std::endl;
-      //just compare values
-      if( d_tgt ){
-        success = p->areMatchEqual( nn[0], nn[1] );
-      }else{
-        if( p->d_effort==QuantConflictFind::effort_conflict ){
-          success = p->areDisequal( nn[0], nn[1] );
-        }else{
-          success = p->areMatchDisequal( nn[0], nn[1] );
-        }
-      }
-    }else{
-      //otherwise, add a constraint to a variable
-      if( vn[1]!=-1 && vn[0]==-1 ){
-        //swap
-        Node t = nn[1];
-        nn[1] = nn[0];
-        nn[0] = t;
-        vn[0] = vn[1];
-        vn[1] = -1;
-      }
-      Debug("qcf-match-debug") << "       reset: add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << std::endl;
-      //add some constraint
-      int addc = qi->addConstraint( p, vn[0], nn[1], vn[1], d_tgt, false );
-      success = addc!=-1;
-      //if successful and non-redundant, store that we need to cleanup this
-      if( addc==1 ){
-        //Trace("qcf-explain") << "       reset: " << d_n << " add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << ", d_tgt = " << d_tgt << std::endl;
-        for( unsigned i=0; i<2; i++ ){
-          if( vn[i]!=-1 && std::find( d_qni_bound_except.begin(), d_qni_bound_except.end(), i )==d_qni_bound_except.end() ){
-            d_qni_bound[vn[i]] = vn[i];
-          }
-        }
-        d_qni_bound_cons[vn[0]] = nn[1];
-        d_qni_bound_cons_var[vn[0]] = vn[1];
-      }
-    }
-    //if successful, we will bind values to variables
-    if( success ){
-      d_qn.push_back( NULL );
-    }
-  }else{
-    if( d_children.empty() ){
-      //add dummy
-      d_qn.push_back( NULL );
-    }else{
-      if( d_tgt && d_n.getKind()==FORALL ){
-        //do nothing
-      }else{
-        //reset the first child to d_tgt
-        d_child_counter = 0;
-        getChild( d_child_counter )->reset( p, d_tgt, qi );
-      }
-    }
-  }
-  d_binding = false;
-  d_wasSet = true;
-  Debug("qcf-match") << "     reset: Finished reset for " << d_n << ", success = " << ( !d_qn.empty() || d_child_counter!=-1 ) << std::endl;
-}
-
-bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {
-  Debug("qcf-match") << "     Get next match for : " << d_n << ", type = ";
-  debugPrintType( "qcf-match", d_type );
-  Debug("qcf-match") << ", children = " << d_children.size() << ", binding = " << d_binding << std::endl;
-  if( d_type==typ_invalid || d_type==typ_ground ){
-    if( d_child_counter==0 ){
-      d_child_counter = -1;
-      return true;
-    }else{
-      d_wasSet = false;
-      return false;
-    }
-  }else if( d_type==typ_var || d_type==typ_eq || d_type==typ_pred || d_type==typ_bool_var || d_type==typ_tconstraint || d_type==typ_tsym ){
-    bool success = false;
-    bool terminate = false;
-    do {
-      bool doReset = false;
-      bool doFail = false;
-      if( !d_binding ){
-        if( doMatching( p, qi ) ){
-          Debug("qcf-match-debug") << "     - Matching succeeded" << std::endl;
-          d_binding = true;
-          d_binding_it = d_qni_bound.begin();
-          doReset = true;
-          //for tconstraint, add constraint
-          if( d_type==typ_tconstraint ){
-            std::map< Node, bool >::iterator it = qi->d_tconstraints.find( d_n );
-            if( it==qi->d_tconstraints.end() ){
-              qi->d_tconstraints[d_n] = d_tgt;
-              //store that we added this constraint
-              d_qni_bound_cons[0] = d_n;
-            }else if( d_tgt!=it->second ){
-              success = false;
-              terminate = true;
-            }
-          }
-        }else{
-          Debug("qcf-match-debug") << "     - Matching failed" << std::endl;
-          success = false;
-          terminate = true;
-        }
-      }else{
-        doFail = true;
-      }
-      if( d_binding ){
-        //also need to create match for each variable we bound
-        success = true;
-        Debug("qcf-match-debug") << "     Produce matches for bound variables by " << d_n << ", type = ";
-        debugPrintType( "qcf-match-debug", d_type );
-        Debug("qcf-match-debug") << "..." << std::endl;
-
-        while( ( success && d_binding_it!=d_qni_bound.end() ) || doFail ){
-          std::map< int, MatchGen * >::iterator itm;
-          if( !doFail ){
-            Debug("qcf-match-debug") << "       check variable " << d_binding_it->second << std::endl;
-            itm = qi->d_var_mg.find( d_binding_it->second );
-          }
-          if( doFail || ( d_binding_it->first!=0 && itm!=qi->d_var_mg.end() ) ){
-            Debug("qcf-match-debug") << "       we had bound variable " << d_binding_it->second << ", reset = " << doReset << std::endl;
-            if( doReset ){
-              itm->second->reset( p, true, qi );
-            }
-            if( doFail || !itm->second->getNextMatch( p, qi ) ){
-              do {
-                if( d_binding_it==d_qni_bound.begin() ){
-                  Debug("qcf-match-debug") << "       failed." << std::endl;
-                  success = false;
-                }else{
-                  --d_binding_it;
-                  Debug("qcf-match-debug") << "       decrement..." << std::endl;
-                }
-              }while( success && ( d_binding_it->first==0 || qi->d_var_mg.find( d_binding_it->second )==qi->d_var_mg.end() ) );
-              doReset = false;
-              doFail = false;
-            }else{
-              Debug("qcf-match-debug") << "       increment..." << std::endl;
-              ++d_binding_it;
-              doReset = true;
-            }
-          }else{
-            Debug("qcf-match-debug") << "       skip..." << d_binding_it->second << std::endl;
-            ++d_binding_it;
-            doReset = true;
-          }
-        }
-        if( !success ){
-          d_binding = false;
-        }else{
-          terminate = true;
-          if( d_binding_it==d_qni_bound.begin() ){
-            d_binding = false;
-          }
-        }
-      }
-    }while( !terminate );
-    //if not successful, clean up the variables you bound
-    if( !success ){
-      if( d_type==typ_eq || d_type==typ_pred ){
-        //clean up the constraints you added
-        for( std::map< int, TNode >::iterator it = d_qni_bound_cons.begin(); it != d_qni_bound_cons.end(); ++it ){
-          if( !it->second.isNull() ){
-            Debug("qcf-match") << "       Clean up bound var " << it->first << (d_tgt ? "!" : "") << " = " << it->second << std::endl;
-            std::map< int, int >::iterator itb = d_qni_bound_cons_var.find( it->first );
-            int vn = itb!=d_qni_bound_cons_var.end() ? itb->second : -1;
-            //Trace("qcf-explain") << "       cleanup: " << d_n << " remove constraint " << it->first << " -> " << it->second << " (vn=" << vn << ")" << ", d_tgt = " << d_tgt << std::endl;
-            qi->addConstraint( p, it->first, it->second, vn, d_tgt, true );
-          }
-        }
-        d_qni_bound_cons.clear();
-        d_qni_bound_cons_var.clear();
-        d_qni_bound.clear();
-      }else{
-        //clean up the matches you set
-        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){
-          Debug("qcf-match") << "       Clean up bound var " << it->second << std::endl;
-          Assert( it->second<qi->getNumVars() );
-          qi->d_match[ it->second ] = TNode::null();
-          qi->d_match_term[ it->second ] = TNode::null();
-        }
-        d_qni_bound.clear();
-      }
-      if( d_type==typ_tconstraint ){
-        //remove constraint if applicable
-        if( d_qni_bound_cons.find( 0 )!=d_qni_bound_cons.end() ){
-          qi->d_tconstraints.erase( d_n );
-          d_qni_bound_cons.clear();
-        }
-      }
-      /*
-      if( d_type==typ_var && p->d_effort==QuantConflictFind::effort_mc && !d_matched_basis ){
-        d_matched_basis = true;
-        Node f = getOperator( d_n );
-        TNode mbo = p->getQuantifiersEngine()->getTermDatabase()->getModelBasisOpTerm( f );
-        if( qi->setMatch( p, d_qni_var_num[0], mbo ) ){
-          success = true;
-          d_qni_bound[0] = d_qni_var_num[0];
-        }
-      }
-      */
-    }
-    Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;
-    d_wasSet = success;
-    return success;
-  }else if( d_type==typ_formula || d_type==typ_ite_var ){
-    bool success = false;
-    if( d_child_counter<0 ){
-      if( d_child_counter<-1 ){
-        success = true;
-        d_child_counter = -1;
-      }
-    }else{
-      while( !success && d_child_counter>=0 ){
-        //transition system based on d_child_counter
-        if( d_n.getKind()==OR || d_n.getKind()==AND ){
-          if( (d_n.getKind()==AND)==d_tgt ){
-            //all children must match simultaneously
-            if( getChild( d_child_counter )->getNextMatch( p, qi ) ){
-              if( d_child_counter<(int)(getNumChildren()-1) ){
-                d_child_counter++;
-                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << std::endl;
-                getChild( d_child_counter )->reset( p, d_tgt, qi );
-              }else{
-                success = true;
-              }
-            }else{
-              //if( std::find( d_independent.begin(), d_independent.end(), d_child_counter )!=d_independent.end() ){
-              //  d_child_counter--;
-              //}else{
-              d_child_counter--;
-              //}
-            }
-          }else{
-            //one child must match
-            if( !getChild( d_child_counter )->getNextMatch( p, qi ) ){
-              if( d_child_counter<(int)(getNumChildren()-1) ){
-                d_child_counter++;
-                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << ", one match" << std::endl;
-                getChild( d_child_counter )->reset( p, d_tgt, qi );
-              }else{
-                d_child_counter = -1;
-              }
-            }else{
-              success = true;
-            }
-          }
-        }else if( d_n.getKind()==IFF ){
-          //construct match based on both children
-          if( d_child_counter%2==0 ){
-            if( getChild( 0 )->getNextMatch( p, qi ) ){
-              d_child_counter++;
-              getChild( 1 )->reset( p, d_child_counter==1, qi );
-            }else{
-              if( d_child_counter==0 ){
-                d_child_counter = 2;
-                getChild( 0 )->reset( p, !d_tgt, qi );
-              }else{
-                d_child_counter = -1;
-              }
-            }
-          }
-          if( d_child_counter>=0 && d_child_counter%2==1 ){
-            if( getChild( 1 )->getNextMatch( p, qi ) ){
-              success = true;
-            }else{
-              d_child_counter--;
-            }
-          }
-        }else if( d_n.getKind()==ITE ){
-          if( d_child_counter%2==0 ){
-            int index1 = d_child_counter==4 ? 1 : 0;
-            if( getChild( index1 )->getNextMatch( p, qi ) ){
-              d_child_counter++;
-              getChild( d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2) )->reset( p, d_tgt, qi );
-            }else{
-              if( d_child_counter==4 || ( d_type==typ_ite_var && d_child_counter==2 ) ){
-                d_child_counter = -1;
-              }else{
-                d_child_counter +=2;
-                getChild( d_child_counter==2 ? 0 : 1 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );
-              }
-            }
-          }
-          if( d_child_counter>=0 && d_child_counter%2==1 ){
-            int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2);
-            if( getChild( index2 )->getNextMatch( p, qi ) ){
-              success = true;
-            }else{
-              d_child_counter--;
-            }
-          }
-        }else if( d_n.getKind()==FORALL ){
-          if( getChild( d_child_counter )->getNextMatch( p, qi ) ){
-            success = true;
-          }else{
-            d_child_counter = -1;
-          }
-        }
-      }
-        d_wasSet = success;
-      Debug("qcf-match") << "    ...finished construct match for " << d_n << ", success = " << success << std::endl;
-      return success;
-    }
-  }
-  Debug("qcf-match") << "    ...already finished for " << d_n << std::endl;
-  return false;
-}
-
-bool MatchGen::getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp ) {
-  if( d_type==typ_eq ){
-    Node n[2];
-    for( unsigned i=0; i<2; i++ ){
-      Trace("qcf-explain") << "Explain term " << d_n[i] << "..." << std::endl;
-      n[i] = getExplanationTerm( p, qi, d_n[i], exp );
-    }
-    Node eq = n[0].eqNode( n[1] );
-    if( !d_tgt_orig ){
-      eq = eq.negate();
-    }
-    exp.push_back( eq );
-    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << eq << ", set = " << d_wasSet << std::endl;
-    return true;
-  }else if( d_type==typ_pred ){
-    Trace("qcf-explain") << "Explain term " << d_n << "..." << std::endl;
-    Node n = getExplanationTerm( p, qi, d_n, exp );
-    if( !d_tgt_orig ){
-      n = n.negate();
-    }
-    exp.push_back( n );
-    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << n << ", set = " << d_wasSet << std::endl;
-    return true;
-  }else if( d_type==typ_formula ){
-    Trace("qcf-explain") << "Explanation get for " << d_n << ", counter = " << d_child_counter << ", tgt = " << d_tgt_orig << ", set = " << d_wasSet << std::endl;
-    if( d_n.getKind()==OR || d_n.getKind()==AND ){
-      if( (d_n.getKind()==AND)==d_tgt ){
-        for( unsigned i=0; i<getNumChildren(); i++ ){
-          if( !getChild( i )->getExplanation( p, qi, exp ) ){
-            return false;
-          }
-        }
-      }else{
-        return getChild( d_child_counter )->getExplanation( p, qi, exp );
-      }
-    }else if( d_n.getKind()==IFF ){
-      for( unsigned i=0; i<2; i++ ){
-        if( !getChild( i )->getExplanation( p, qi, exp ) ){
-          return false;
-        }
-      }
-    }else if( d_n.getKind()==ITE ){
-      for( unsigned i=0; i<3; i++ ){
-        bool isActive = ( ( i==0 && d_child_counter!=5 ) ||
-                          ( i==1 && d_child_counter!=( d_tgt ? 3 : 1 ) ) ||
-                          ( i==2 && d_child_counter!=( d_tgt ? 1 : 3 ) ) );
-        if( isActive ){
-          if( !getChild( i )->getExplanation( p, qi, exp ) ){
-            return false;
-          }
-        }
-      }
-    }else{
-      return false;
-    }
-    return true;
-  }else{
-    return false;
-  }
-}
-
-Node MatchGen::getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp ) {
-  Node v = qi->getCurrentExpValue( t );
-  if( isHandledUfTerm( t ) ){
-    for( unsigned i=0; i<t.getNumChildren(); i++ ){
-      Node vi = getExplanationTerm( p, qi, t[i], exp );
-      if( vi!=v[i] ){
-        Node eq = vi.eqNode( v[i] );
-        if( std::find( exp.begin(), exp.end(), eq )==exp.end() ){
-          Trace("qcf-explain") << "  add : " << eq << "." << std::endl;
-          exp.push_back( eq );
-        }
-      }
-    }
-  }
-  return v;
-}
-
-bool MatchGen::doMatching( QuantConflictFind * p, QuantInfo * qi ) {
-  if( !d_qn.empty() ){
-    if( d_qn[0]==NULL ){
-      d_qn.clear();
-      return true;
-    }else{
-      Assert( d_type==typ_var );
-      Assert( d_qni_size>0 );
-      bool invalidMatch;
-      do {
-        invalidMatch = false;
-        Debug("qcf-match-debug") << "       Do matching " << d_n << " " << d_qn.size() << " " << d_qni.size() << std::endl;
-        if( d_qn.size()==d_qni.size()+1 ) {
-          int index = (int)d_qni.size();
-          //initialize
-          TNode val;
-          std::map< int, int >::iterator itv = d_qni_var_num.find( index );
-          if( itv!=d_qni_var_num.end() ){
-            //get the representative variable this variable is equal to
-            int repVar = qi->getCurrentRepVar( itv->second );
-            Debug("qcf-match-debug") << "       Match " << index << " is a variable " << itv->second << ", which is repVar " << repVar << std::endl;
-            //get the value the rep variable
-            //std::map< int, TNode >::iterator itm = qi->d_match.find( repVar );
-            if( !qi->d_match[repVar].isNull() ){
-              val = qi->d_match[repVar];
-              Debug("qcf-match-debug") << "       Variable is already bound to " << val << std::endl;
-            }else{
-              //binding a variable
-              d_qni_bound[index] = repVar;
-              std::map< TNode, QcfNodeIndex >::iterator it = d_qn[index]->d_children.begin();
-              if( it != d_qn[index]->d_children.end() ) {
-                d_qni.push_back( it );
-                //set the match
-                if( qi->setMatch( p, d_qni_bound[index], it->first ) ){
-                  Debug("qcf-match-debug") << "       Binding variable" << std::endl;
-                  if( d_qn.size()<d_qni_size ){
-                    d_qn.push_back( &it->second );
-                  }
-                }else{
-                  Debug("qcf-match") << "       Binding variable, currently fail." << std::endl;
-                  invalidMatch = true;
-                }
-              }else{
-                Debug("qcf-match-debug") << "       Binding variable, fail, no more variables to bind" << std::endl;
-                d_qn.pop_back();
-              }
-            }
-          }else{
-            Debug("qcf-match-debug") << "       Match " << index << " is ground term" << std::endl;
-            Assert( d_qni_gterm.find( index )!=d_qni_gterm.end() );
-            Assert( d_qni_gterm_rep.find( index )!=d_qni_gterm_rep.end() );
-            val = d_qni_gterm_rep[index];
-            Assert( !val.isNull() );
-          }
-          if( !val.isNull() ){
-            //constrained by val
-            std::map< TNode, QcfNodeIndex >::iterator it = d_qn[index]->d_children.find( val );
-            if( it!=d_qn[index]->d_children.end() ){
-              Debug("qcf-match-debug") << "       Match" << std::endl;
-              d_qni.push_back( it );
-              if( d_qn.size()<d_qni_size ){
-                d_qn.push_back( &it->second );
-              }
-            }else{
-              Debug("qcf-match-debug") << "       Failed to match" << std::endl;
-              d_qn.pop_back();
-            }
-          }
-        }else{
-          Assert( d_qn.size()==d_qni.size() );
-          int index = d_qni.size()-1;
-          //increment if binding this variable
-          bool success = false;
-          std::map< int, int >::iterator itb = d_qni_bound.find( index );
-          if( itb!=d_qni_bound.end() ){
-            d_qni[index]++;
-            if( d_qni[index]!=d_qn[index]->d_children.end() ){
-              success = true;
-              if( qi->setMatch( p, itb->second, d_qni[index]->first ) ){
-                Debug("qcf-match-debug") << "       Bind next variable" << std::endl;
-                if( d_qn.size()<d_qni_size ){
-                  d_qn.push_back( &d_qni[index]->second );
-                }
-              }else{
-                Debug("qcf-match-debug") << "       Bind next variable, currently fail" << std::endl;
-                invalidMatch = true;
-              }
-            }else{
-              qi->d_match[ itb->second ] = TNode::null();
-              qi->d_match_term[ itb->second ] = TNode::null();
-              Debug("qcf-match-debug") << "       Bind next variable, no more variables to bind" << std::endl;
-            }
-          }else{
-            //TODO : if it equal to something else, also try that
-          }
-          //if not incrementing, move to next
-          if( !success ){
-            d_qn.pop_back();
-            d_qni.pop_back();
-          }
-        }
-      }while( ( !d_qn.empty() && d_qni.size()!=d_qni_size ) || invalidMatch );
-      if( d_qni.size()==d_qni_size ){
-        //Assert( !d_qni[d_qni.size()-1]->second.d_children.empty() );
-        //Debug("qcf-match-debug") << "       We matched " << d_qni[d_qni.size()-1]->second.d_children.begin()->first << std::endl;
-        Assert( !d_qni[d_qni.size()-1]->second.d_children.empty() );
-        TNode t = d_qni[d_qni.size()-1]->second.d_children.begin()->first;
-        Debug("qcf-match-debug") << "       " << d_n << " matched " << t << std::endl;
-        qi->d_match_term[d_qni_var_num[0]] = t;
-        //set the match terms
-        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){
-          Debug("qcf-match-debug") << "       position " << it->first << " bounded " << it->second << " / " << qi->d_q[0].getNumChildren() << std::endl;
-          //if( it->second<(int)qi->d_q[0].getNumChildren() ){   //if it is an actual variable, we are interested in knowing the actual term
-          if( it->first>0 ){
-            Assert( !qi->d_match[ it->second ].isNull() );
-            Assert( p->areEqual( t[it->first-1], qi->d_match[ it->second ] ) );
-            qi->d_match_term[it->second] = t[it->first-1];
-          }
-          //}
-        }
-      }
-    }
-  }
-  return !d_qn.empty();
-}
-
-void MatchGen::debugPrintType( const char * c, short typ, bool isTrace ) {
-  if( isTrace ){
-    switch( typ ){
-    case typ_invalid: Trace(c) << "invalid";break;
-    case typ_ground: Trace(c) << "ground";break;
-    case typ_eq: Trace(c) << "eq";break;
-    case typ_pred: Trace(c) << "pred";break;
-    case typ_formula: Trace(c) << "formula";break;
-    case typ_var: Trace(c) << "var";break;
-    case typ_ite_var: Trace(c) << "ite_var";break;
-    case typ_bool_var: Trace(c) << "bool_var";break;
-    }
-  }else{
-    switch( typ ){
-    case typ_invalid: Debug(c) << "invalid";break;
-    case typ_ground: Debug(c) << "ground";break;
-    case typ_eq: Debug(c) << "eq";break;
-    case typ_pred: Debug(c) << "pred";break;
-    case typ_formula: Debug(c) << "formula";break;
-    case typ_var: Debug(c) << "var";break;
-    case typ_ite_var: Debug(c) << "ite_var";break;
-    case typ_bool_var: Debug(c) << "bool_var";break;
-    }
-  }
-}
-
-void MatchGen::setInvalid() {
-  d_type = typ_invalid;
-  d_children.clear();
-}
-
-bool MatchGen::isHandledBoolConnective( TNode n ) {
-  return n.getType().isBoolean() && ( n.getKind()==OR || n.getKind()==AND || n.getKind()==IFF || n.getKind()==ITE || n.getKind()==FORALL || n.getKind()==NOT );
-}
-
-bool MatchGen::isHandledUfTerm( TNode n ) {
-  //return n.getKind()==APPLY_UF || n.getKind()==STORE || n.getKind()==SELECT ||
-  //       n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR_TOTAL || n.getKind()==APPLY_TESTER;
-  return inst::Trigger::isAtomicTriggerKind( n.getKind() );  
-}
-
-Node MatchGen::getOperator( QuantConflictFind * p, Node n ) {
-  if( isHandledUfTerm( n ) ){
-    return p->getQuantifiersEngine()->getTermDatabase()->getOperator( n );
-  }else{
-    return Node::null();
-  }
-}
-
-bool MatchGen::isHandled( TNode n ) {
-  if( n.getKind()!=BOUND_VARIABLE && n.hasBoundVar() ){
-    if( !isHandledBoolConnective( n ) && !isHandledUfTerm( n ) && n.getKind()!=EQUAL && n.getKind()!=ITE ){
-      return false;
-    }
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){
-      if( !isHandled( n[i] ) ){
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-
-QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :
-QuantifiersModule( qe ),
-d_c( c ),
-d_conflict( c, false ),
-d_qassert( c ) {
-  d_fid_count = 0;
-  d_true = NodeManager::currentNM()->mkConst<bool>(true);
-  d_false = NodeManager::currentNM()->mkConst<bool>(false);
-}
-
-Node QuantConflictFind::mkEqNode( Node a, Node b ) {
-  if( a.getType().isBoolean() ){
-    return a.iffNode( b );
-  }else{
-    return a.eqNode( b );
-  }
-}
-
-//-------------------------------------------------- registration
-
-void QuantConflictFind::registerQuantifier( Node q ) {
-  if( !TermDb::isRewriteRule( q ) ){
-    d_quants.push_back( q );
-    d_quant_id[q] = d_quants.size();
-    Trace("qcf-qregister") << "Register ";
-    debugPrintQuant( "qcf-qregister", q );
-    Trace("qcf-qregister") << " : " << q << std::endl;
-    //make QcfNode structure
-    Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;
-    d_qinfo[q].initialize( q, q[1] );
-
-    //debug print
-    Trace("qcf-qregister") << "- Flattened structure is :" << std::endl;
-    Trace("qcf-qregister") << "    ";
-    debugPrintQuantBody( "qcf-qregister", q, q[1] );
-    Trace("qcf-qregister") << std::endl;
-    if( d_qinfo[q].d_vars.size()>q[0].getNumChildren() ){
-      Trace("qcf-qregister") << "  with additional constraints : " << std::endl;
-      for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){
-        Trace("qcf-qregister") << "    ?x" << j << " = ";
-        debugPrintQuantBody( "qcf-qregister", q, d_qinfo[q].d_vars[j], false );
-        Trace("qcf-qregister") << std::endl;
-      }
-    }
-
-    Trace("qcf-qregister") << "Done registering quantifier." << std::endl;
-  }
-}
-
-int QuantConflictFind::evaluate( Node n, bool pref, bool hasPref ) {
-  int ret = 0;
-  if( n.getKind()==EQUAL ){
-    Node n1 = evaluateTerm( n[0] );
-    Node n2 = evaluateTerm( n[1] );
-    Debug("qcf-eval") << "Evaluate : Normalize " << n << " to " << n1 << " = " << n2 << std::endl;
-    if( areEqual( n1, n2 ) ){
-      ret = 1;
-    }else if( areDisequal( n1, n2 ) ){
-      ret = -1;
-    }
-    //else if( d_effort>QuantConflictFind::effort_conflict ){
-    //  ret = -1;
-    //}
-  }else if( MatchGen::isHandledUfTerm( n ) ){  //predicate
-    Node nn = evaluateTerm( n );
-    Debug("qcf-eval") << "Evaluate : Normalize " << nn << " to " << n << std::endl;
-    if( areEqual( nn, d_true ) ){
-      ret = 1;
-    }else if( areEqual( nn, d_false ) ){
-      ret = -1;
-    }
-    //else if( d_effort>QuantConflictFind::effort_conflict ){
-    //  ret = -1;
-    //}
-  }else if( n.getKind()==NOT ){
-    return -evaluate( n[0] );
-  }else if( n.getKind()==ITE ){
-    int cev1 = evaluate( n[0] );
-    int cevc[2] = { 0, 0 };
-    for( unsigned i=0; i<2; i++ ){
-      if( ( i==0 && cev1!=-1 ) || ( i==1 && cev1!=1 ) ){
-        cevc[i] = evaluate( n[i+1] );
-        if( cev1!=0 ){
-          ret = cevc[i];
-          break;
-        }else if( cevc[i]==0 ){
-          break;
-        }
-      }
-    }
-    if( ret==0 && cevc[0]!=0 && cevc[0]==cevc[1] ){
-      ret = cevc[0];
-    }
-  }else if( n.getKind()==IFF ){
-    int cev1 = evaluate( n[0] );
-    if( cev1!=0 ){
-      int cev2 = evaluate( n[1] );
-      if( cev2!=0 ){
-        ret = cev1==cev2 ? 1 : -1;
-      }
-    }
-
-  }else{
-    int ssval = 0;
-    if( n.getKind()==OR ){
-      ssval = 1;
-    }else if( n.getKind()==AND ){
-      ssval = -1;
-    }
-    bool isUnk = false;
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){
-      int cev = evaluate( n[i] );
-      if( cev==ssval ){
-        ret = ssval;
-        break;
-      }else if( cev==0 ){
-        isUnk = true;
-      }
-    }
-    if( ret==0 && !isUnk ){
-      ret = -ssval;
-    }
-  }
-  Debug("qcf-eval") << "Evaluate " << n << " to " << ret << std::endl;
-  return ret;
-}
-
-short QuantConflictFind::getMaxQcfEffort() {
-  if( options::qcfMode()==QCF_CONFLICT_ONLY ){
-    return effort_conflict;
-  }else if( options::qcfMode()==QCF_PROP_EQ ){
-    return effort_prop_eq;
-  }else if( options::qcfMode()==QCF_MC ){
-    return effort_mc;
-  }else{
-    return 0;
-  }
-}
-
-bool QuantConflictFind::areMatchEqual( TNode n1, TNode n2 ) {
-  //if( d_effort==QuantConflictFind::effort_mc ){
-  //  return n1==n2 || !areDisequal( n1, n2 );
-  //}else{
-  return n1==n2;
-  //}
-}
-
-bool QuantConflictFind::areMatchDisequal( TNode n1, TNode n2 ) {
-  //if( d_effort==QuantConflictFind::effort_conflict ){
-  //  return areDisequal( n1, n2 );
-  //}else{
-  return n1!=n2;
-  //}
-}
-
-//-------------------------------------------------- handling assertions / eqc
-
-void QuantConflictFind::assertNode( Node q ) {
-  if( !TermDb::isRewriteRule( q ) ){
-    Trace("qcf-proc") << "QCF : assertQuantifier : ";
-    debugPrintQuant("qcf-proc", q);
-    Trace("qcf-proc") << std::endl;
-    d_qassert.push_back( q );
-    //set the eqRegistries that this depends on to true
-    //for( std::map< EqRegistry *, bool >::iterator it = d_qinfo[q].d_rel_eqr.begin(); it != d_qinfo[q].d_rel_eqr.end(); ++it ){
-    //  it->first->d_active.set( true );
-    //}
-  }
-}
-
-eq::EqualityEngine * QuantConflictFind::getEqualityEngine() {
-  //return ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( theory::THEORY_UF ))->getEqualityEngine();
-  return d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
-}
-bool QuantConflictFind::areEqual( Node n1, Node n2 ) {
-  return getEqualityEngine()->hasTerm( n1 ) && getEqualityEngine()->hasTerm( n2 ) && getEqualityEngine()->areEqual( n1,n2 );
-}
-bool QuantConflictFind::areDisequal( Node n1, Node n2 ) {
-  return n1!=n2 && getEqualityEngine()->hasTerm( n1 ) && getEqualityEngine()->hasTerm( n2 ) && getEqualityEngine()->areDisequal( n1,n2, false );
-}
-Node QuantConflictFind::getRepresentative( Node n ) {
-  if( getEqualityEngine()->hasTerm( n ) ){
-    return getEqualityEngine()->getRepresentative( n );
-  }else{
-    return n;
-  }
-}
-Node QuantConflictFind::evaluateTerm( Node n ) {
-  if( MatchGen::isHandledUfTerm( n ) ){
-    Node f = MatchGen::getOperator( this, n );
-    Node nn;
-    computeUfTerms( f );
-    if( getEqualityEngine()->hasTerm( n ) ){
-      computeArgReps( n );
-      nn = d_uf_terms[f].existsTerm( n, d_arg_reps[n] );
-    }else{
-      std::vector< TNode > args;
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){
-        Node c = evaluateTerm( n[i] );
-        args.push_back( c );
-      }
-      nn = d_uf_terms[f].existsTerm( n, args );
-    }
-    if( !nn.isNull() ){
-      Debug("qcf-eval") << "GT: Term " << nn << " for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;
-      return getRepresentative( nn );
-    }else{
-      Debug("qcf-eval") << "GT: No term for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;
-      return n;
-    }
-  }else if( n.getKind()==ITE ){
-    int v = evaluate( n[0], false, false );
-    if( v==1 ){
-      return evaluateTerm( n[1] );
-    }else if( v==-1 ){
-      return evaluateTerm( n[2] );
-    }
-  }
-  return getRepresentative( n );
-}
-
-/*
-QuantConflictFind::EqcInfo * QuantConflictFind::getEqcInfo( Node n, bool doCreate ) {
-  std::map< Node, EqcInfo * >::iterator it2 = d_eqc_info.find( n );
-  if( it2==d_eqc_info.end() ){
-    if( doCreate ){
-      EqcInfo * eqci = new EqcInfo( d_c );
-      d_eqc_info[n] = eqci;
-      return eqci;
-    }else{
-      return NULL;
-    }
-  }
-  return it2->second;
-}
-*/
-
-QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node eqc, Node f ) {
-  computeUfTerms( f );
-  std::map< TNode, QcfNodeIndex >::iterator itut = d_eqc_uf_terms.find( f );
-  if( itut==d_eqc_uf_terms.end() ){
-    return NULL;
-  }else{
-    if( eqc.isNull() ){
-      return &itut->second;
-    }else{
-      std::map< TNode, QcfNodeIndex >::iterator itute = itut->second.d_children.find( eqc );
-      if( itute!=itut->second.d_children.end() ){
-        return &itute->second;
-      }else{
-        return NULL;
-      }
-    }
-  }
-}
-
-QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node f ) {
-  computeUfTerms( f );
-  std::map< TNode, QcfNodeIndex >::iterator itut = d_uf_terms.find( f );
-  if( itut!=d_uf_terms.end() ){
-    return &itut->second;
-  }else{
-    return NULL;
-  }
-}
-
-/** new node */
-void QuantConflictFind::newEqClass( Node n ) {
-  //Trace("qcf-proc-debug") << "QCF : newEqClass : " << n << std::endl;
-  //Trace("qcf-proc2-debug") << "QCF : finished newEqClass : " << n << std::endl;
-}
-
-/** merge */
-void QuantConflictFind::merge( Node a, Node b ) {
-  /*
-  if( b.getKind()==EQUAL ){
-    if( a==d_true ){
-      //will merge anyways
-      //merge( b[0], b[1] );
-    }else if( a==d_false ){
-      assertDisequal( b[0], b[1] );
-    }
-  }else{
-    Trace("qcf-proc") << "QCF : merge : " << a << " " << b << std::endl;
-    EqcInfo * eqc_b = getEqcInfo( b, false );
-    EqcInfo * eqc_a = NULL;
-    if( eqc_b ){
-      eqc_a = getEqcInfo( a );
-      //move disequalities of b into a
-      for( NodeBoolMap::iterator it = eqc_b->d_diseq.begin(); it != eqc_b->d_diseq.end(); ++it ){
-        if( (*it).second ){
-          Node n = (*it).first;
-          EqcInfo * eqc_n = getEqcInfo( n, false );
-          Assert( eqc_n );
-          if( !eqc_n->isDisequal( a ) ){
-            Assert( !eqc_a->isDisequal( n ) );
-            eqc_n->setDisequal( a );
-            eqc_a->setDisequal( n );
-            //setEqual( eqc_a, eqc_b, a, n, false );
-          }
-          eqc_n->setDisequal( b, false );
-        }
-      }
-      ////move all previous EqcRegistry's regarding equalities within b
-      //for( NodeBoolMap::iterator it = eqc_b->d_rel_eqr_e.begin(); it != eqc_b->d_rel_eqr_e.end(); ++it ){
-      //  if( (*it).second ){
-      //    eqc_a->d_rel_eqr_e[(*it).first] = true;
-      //  }
-      //}
-    }
-    //process new equalities
-    //setEqual( eqc_a, eqc_b, a, b, true );
-    Trace("qcf-proc2") << "QCF : finished merge : " << a << " " << b << std::endl;
-  }
-  */
-}
-
-/** assert disequal */
-void QuantConflictFind::assertDisequal( Node a, Node b ) {
-  /*
-  a = getRepresentative( a );
-  b = getRepresentative( b );
-  Trace("qcf-proc") << "QCF : assert disequal : " << a << " " << b << std::endl;
-  EqcInfo * eqc_a = getEqcInfo( a );
-  EqcInfo * eqc_b = getEqcInfo( b );
-  if( !eqc_a->isDisequal( b ) ){
-    Assert( !eqc_b->isDisequal( a ) );
-    eqc_b->setDisequal( a );
-    eqc_a->setDisequal( b );
-    //setEqual( eqc_a, eqc_b, a, b, false );
-  }
-  Trace("qcf-proc2") << "QCF : finished assert disequal : " << a << " " << b << std::endl;
-  */
-}
-
-//-------------------------------------------------- check function
-
-void QuantConflictFind::reset_round( Theory::Effort level ) {
-  d_needs_computeRelEqr = true;
-}
-
-/** check */
-void QuantConflictFind::check( Theory::Effort level ) {
-  Trace("qcf-check") << "QCF : check : " << level << std::endl;
-  if( d_conflict ){
-    Trace("qcf-check2") << "QCF : finished check : already in conflict." << std::endl;
-    if( level>=Theory::EFFORT_FULL ){
-      Trace("qcf-warn") << "ALREADY IN CONFLICT? " << level << std::endl;
-      //Assert( false );
-    }
-  }else{
-    int addedLemmas = 0;
-    if( d_performCheck ){
-      ++(d_statistics.d_inst_rounds);
-      double clSet = 0;
-      int prevEt = 0;
-      if( Trace.isOn("qcf-engine") ){
-        prevEt = d_statistics.d_entailment_checks.getData();
-        clSet = double(clock())/double(CLOCKS_PER_SEC);
-        Trace("qcf-engine") << "---Conflict Find Engine Round, effort = " << level << "---" << std::endl;
-      }
-      computeRelevantEqr();
-
-      //determine order for quantified formulas
-      std::vector< Node > qorder;
-      std::map< Node, bool > qassert;
-      //mark which are asserted
-      for( unsigned i=0; i<d_qassert.size(); i++ ){
-        qassert[d_qassert[i]] = true;
-      }
-      //add which ones are specified in the order
-      for( unsigned i=0; i<d_quant_order.size(); i++ ){
-        Node n = d_quant_order[i];
-        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() && qassert.find( n )!=qassert.end() ){
-          qorder.push_back( n );
-        }
-      }
-      d_quant_order.clear();
-      d_quant_order.insert( d_quant_order.begin(), qorder.begin(), qorder.end() );
-      //add remaining
-      for( unsigned i=0; i<d_qassert.size(); i++ ){
-        Node n = d_qassert[i];
-        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() ){
-          qorder.push_back( n );
-        }
-      }
-
-      if( Trace.isOn("qcf-debug") ){
-        Trace("qcf-debug") << std::endl;
-        debugPrint("qcf-debug");
-        Trace("qcf-debug") << std::endl;
-      }
-      short end_e = getMaxQcfEffort();
-      for( short e = effort_conflict; e<=end_e; e++ ){
-        d_effort = e;
-        Trace("qcf-check") << "Checking quantified formulas at effort " << e << "..." << std::endl;
-        for( unsigned j=0; j<qorder.size(); j++ ){
-          Node q = qorder[j];
-          QuantInfo * qi = &d_qinfo[q];
-
-          Assert( d_qinfo.find( q )!=d_qinfo.end() );
-          if( qi->d_mg->isValid() ){
-            Trace("qcf-check") << "Check quantified formula ";
-            debugPrintQuant("qcf-check", q);
-            Trace("qcf-check") << " : " << q << "..." << std::endl;
-
-            Trace("qcf-check-debug") << "Reset round..." << std::endl;
-            qi->reset_round( this );
-            //try to make a matches making the body false
-            Trace("qcf-check-debug") << "Get next match..." << std::endl;
-            while( qi->d_mg->getNextMatch( this, qi ) ){
-              Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;
-              qi->debugPrintMatch("qcf-check");
-              Trace("qcf-check") << std::endl;
-              std::vector< int > assigned;
-              if( !qi->isMatchSpurious( this ) ){
-                if( qi->completeMatch( this, assigned ) ){
-                  /*
-                  if( options::qcfExp() && d_effort==effort_conflict ){
-                    std::vector< Node > exp;
-                    if( qi->d_mg->getExplanation( this, qi, exp ) ){
-                      Trace("qcf-check-exp") << "Base explanation is : " << std::endl;
-                      for( unsigned c=0; c<exp.size(); c++ ){
-                        Trace("qcf-check-exp") << "  " << exp[c] << std::endl;
-                      }
-                      std::vector< TNode > c_exp;
-                      eq::EqualityEngine* ee = ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( THEORY_UF ))->getEqualityEngine() ;
-                      for( unsigned c=0; c<exp.size(); c++ ){
-                        bool pol = exp[c].getKind()!=NOT;
-                        TNode lit = pol ? exp[c] : exp[c][0];
-                        Trace("qcf-check-exp") << "Explain " << lit << ", polarity " << pol << std::endl;
-                        if( lit.getKind()==EQUAL ){
-                          if( !pol && !ee->areDisequal( lit[0], lit[1], true ) ){
-                            exit( 98 );
-                          }else if( pol && !ee->areEqual( lit[0], lit[1] ) ){
-                            exit( 99 );
-                          }
-                          ee->explainEquality( lit[0], lit[1], pol, c_exp );
-                        }else{
-                          if( !ee->areEqual( lit, pol ? d_true : d_false ) ){
-                            exit( pol ? 96 : 97 );
-                          }
-                          ee->explainPredicate( lit, pol, c_exp );
-                        }
-                      }
-                      std::vector< Node > c_lem;
-                      Trace("qcf-check-exp") << "Actual explanation is : " << std::endl;
-                      for( unsigned c=0; c<c_exp.size(); c++ ){
-                        Trace("qcf-check-exp") << "  " << c_exp[c] << std::endl;
-                        Node ccc = c_exp[c].negate();
-                        if( std::find( c_lem.begin(), c_lem.end(), ccc )==c_lem.end() ){
-                          c_lem.push_back( ccc );
-                        }
-                      }
-
-                      c_lem.push_back( q.negate() );
-                      Node conf = NodeManager::currentNM()->mkNode( OR, c_lem );
-                      Trace("qcf-conflict") << "QCF conflict : " << conf << std::endl;
-                      d_quantEngine->addLemma( conf, false );
-                      d_conflict.set( true );
-                      ++(d_statistics.d_conflict_inst);
-                      ++addedLemmas;
-                      break;
-                    }
-                  }
-                  */
-                  std::vector< Node > terms;
-                  qi->getMatch( terms );
-                  if( !qi->isTConstraintSpurious( this, terms ) ){
-                    if( Debug.isOn("qcf-check-inst") ){
-                      //if( e==effort_conflict ){
-                      Node inst = d_quantEngine->getInstantiation( q, terms );
-                      Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;
-                      Assert( evaluate( inst )!=1 );
-                      Assert( evaluate( inst )==-1 || e>effort_conflict );
-                      //}
-                    }
-                    if( d_quantEngine->addInstantiation( q, terms, false ) ){
-                      Trace("qcf-check") << "   ... Added instantiation" << std::endl;
-                      Trace("qcf-inst") << "*** Was from effort " << e << " : " << std::endl;
-                      qi->debugPrintMatch("qcf-inst");
-                      Trace("qcf-inst") << std::endl;
-                      ++addedLemmas;
-                      if( e==effort_conflict ){
-                        d_quant_order.insert( d_quant_order.begin(), q );
-                        d_conflict.set( true );
-                        ++(d_statistics.d_conflict_inst);
-                        break;
-                      }else if( e==effort_prop_eq ){
-                        ++(d_statistics.d_prop_inst);
-                      }
-                    }else{
-                      Trace("qcf-check") << "   ... Failed to add instantiation" << std::endl;
-                      //Assert( false );
-                    }
-                  }
-                  //clean up assigned
-                  qi->revertMatch( assigned );
-                  d_tempCache.clear();
-                }else{
-                  Trace("qcf-check") << "   ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;
-                }
-              }else{
-                Trace("qcf-check") << "   ... Spurious instantiation (match is inconsistent)" << std::endl;
-              }
-            }
-            if( d_conflict ){
-              break;
-            }
-          }
-        }
-        if( addedLemmas>0 ){
-          d_quantEngine->flushLemmas();
-          break;
-        }
-      }
-      if( Trace.isOn("qcf-engine") ){
-        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
-        Trace("qcf-engine") << "Finished conflict find engine, time = " << (clSet2-clSet);
-        if( addedLemmas>0 ){
-          Trace("qcf-engine") << ", effort = " << ( d_effort==effort_conflict ? "conflict" : ( d_effort==effort_prop_eq ? "prop_eq" : "mc" ) );
-          Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;
-        }
-        Trace("qcf-engine") << std::endl;
-        int currEt = d_statistics.d_entailment_checks.getData();
-        if( currEt!=prevEt ){
-          Trace("qcf-engine") << "  Entailment checks = " << ( currEt - prevEt ) << std::endl;
-        }
-      }
-    }
-    Trace("qcf-check2") << "QCF : finished check : " << level << std::endl;
-  }
-}
-
-bool QuantConflictFind::needsCheck( Theory::Effort level ) {
-  d_performCheck = false;
-  if( options::quantConflictFind() && !d_conflict ){
-    if( level==Theory::EFFORT_LAST_CALL ){
-      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_LAST_CALL;
-    }else if( level==Theory::EFFORT_FULL ){
-      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_DEFAULT;
-    }else if( level==Theory::EFFORT_STANDARD ){
-      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_STD;
-    }
-  }
-  return d_performCheck;
-}
-
-void QuantConflictFind::computeRelevantEqr() {
-  if( d_needs_computeRelEqr ){
-    d_needs_computeRelEqr = false;
-    Trace("qcf-check") << "Compute relevant equalities..." << std::endl;
-    d_uf_terms.clear();
-    d_eqc_uf_terms.clear();
-    d_eqcs.clear();
-    d_model_basis.clear();
-    d_arg_reps.clear();
-    //double clSet = 0;
-    //if( Trace.isOn("qcf-opt") ){
-    //  clSet = double(clock())/double(CLOCKS_PER_SEC);
-    //}
-
-    //long nTermst = 0;
-    //long nTerms = 0;
-    //long nEqc = 0;
-
-    //which nodes are irrelevant for disequality matches
-    std::map< TNode, bool > irrelevant_dnode;
-    //now, store matches
-    eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );
-    while( !eqcs_i.isFinished() ){
-      //nEqc++;
-      Node r = (*eqcs_i);
-      TypeNode rtn = r.getType();
-      if( options::qcfMode()==QCF_MC ){
-        std::map< TypeNode, std::vector< TNode > >::iterator itt = d_eqcs.find( rtn );
-        if( itt==d_eqcs.end() ){
-          Node mb = getQuantifiersEngine()->getTermDatabase()->getModelBasisTerm( rtn );
-          if( !getEqualityEngine()->hasTerm( mb ) ){
-            Trace("qcf-warn") << "WARNING: Model basis term does not exist!" << std::endl;
-            Assert( false );
-          }
-          Node mbr = getRepresentative( mb );
-          if( mbr!=r ){
-            d_eqcs[rtn].push_back( mbr );
-          }
-          d_eqcs[rtn].push_back( r );
-          d_model_basis[rtn] = mb;
-        }else{
-          itt->second.push_back( r );
-        }
-      }else{
-        d_eqcs[rtn].push_back( r );
-      }
-      /*
-      eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );
-      while( !eqc_i.isFinished() ){
-        TNode n = (*eqc_i);
-        if( n.hasBoundVar() ){
-          std::cout << "BAD TERM IN DB : " << n << std::endl;
-          exit( 199 );
-        }
-        ++eqc_i;
-      }
-
-      */
-
-      //if( r.getType().isInteger() ){
-      //  Trace("qcf-mv") << "Model value for eqc(" << r << ") : " << d_quantEngine->getValuation().getModelValue( r ) << std::endl;
-      //}
-      //EqcInfo * eqcir = getEqcInfo( r, false );
-      //get relevant nodes that we are disequal from
-      /*
-      std::vector< Node > deqc;
-      if( eqcir ){
-        for( NodeBoolMap::iterator it = eqcir->d_diseq.begin(); it != eqcir->d_diseq.end(); ++it ){
-          if( (*it).second ){
-            //Node rd = (*it).first;
-            //if( rd!=getRepresentative( rd ) ){
-            //  std::cout << "Bad rep!" << std::endl;
-            //  exit( 0 );
-            //}
-            deqc.push_back( (*it).first );
-          }
-        }
-      }
-      */
-      //process disequalities
-      /*
-      eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );
-      while( !eqc_i.isFinished() ){
-        TNode n = (*eqc_i);
-        if( n.getKind()!=EQUAL ){
-          nTermst++;
-          //node_to_rep[n] = r;
-          //if( n.getNumChildren()>0 ){
-          //  if( n.getKind()!=APPLY_UF ){
-          //    std::cout << n.getKind() << " " << n.getOperator() << " " << n << std::endl;
-          //  }
-          //}
-          if( !quantifiers::TermDb::hasBoundVarAttr( n ) ){    //temporary
-
-            bool isRedundant;
-            std::map< TNode, std::vector< TNode > >::iterator it_na;
-            TNode fn;
-            if( MatchGen::isHandledUfTerm( n ) ){
-              Node f = MatchGen::getOperator( this, n );
-              computeArgReps( n );
-              it_na = d_arg_reps.find( n );
-              Assert( it_na!=d_arg_reps.end() );
-              Node nadd = d_eqc_uf_terms[f].d_children[r].addTerm( n, d_arg_reps[n] );
-              isRedundant = (nadd!=n);
-              d_uf_terms[f].addTerm( n, d_arg_reps[n] );
-            }else{
-              isRedundant = false;
-            }
-            nTerms += isRedundant ? 0 : 1;
-          }else{
-            if( Debug.isOn("qcf-nground") ){
-              Debug("qcf-nground") << "Non-ground term in eqc : " << n << std::endl;
-              Assert( false );
-            }
-          }
-        }
-        ++eqc_i;
-      }
-      */
-      ++eqcs_i;
-    }
-    /*
-    if( Trace.isOn("qcf-opt") ){
-      double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
-      Trace("qcf-opt") << "Compute rel eqc : " << std::endl;
-      Trace("qcf-opt") << "   " << nEqc << " equivalence classes. " << std::endl;
-      Trace("qcf-opt") << "   " << nTerms << " / " << nTermst << " terms." << std::endl;
-      Trace("qcf-opt") << "   Time : " << (clSet2-clSet) << std::endl;
-    }
-    */
-  }
-}
-
-void QuantConflictFind::computeArgReps( TNode n ) {
-  if( d_arg_reps.find( n )==d_arg_reps.end() ){
-    Assert( MatchGen::isHandledUfTerm( n ) );
-    for( unsigned j=0; j<n.getNumChildren(); j++ ){
-      d_arg_reps[n].push_back( getRepresentative( n[j] ) );
-    }
-  }
-}
-
-void QuantConflictFind::computeUfTerms( TNode f ) {
-  if( d_uf_terms.find( f )==d_uf_terms.end() ){
-    d_uf_terms[f].clear();
-    unsigned nt = d_quantEngine->getTermDatabase()->getNumGroundTerms( f );
-    for( unsigned i=0; i<nt; i++ ){
-      Node n = d_quantEngine->getTermDatabase()->d_op_map[f][i];
-      if( getEqualityEngine()->hasTerm( n ) && !n.getAttribute(NoMatchAttribute()) ){
-        Node r = getRepresentative( n );
-        computeArgReps( n );
-        d_eqc_uf_terms[f].d_children[r].addTerm( n, d_arg_reps[n] );
-        d_uf_terms[f].addTerm( n, d_arg_reps[n] );
-      }
-    }
-  }
-}
-
-//-------------------------------------------------- debugging
-
-
-void QuantConflictFind::debugPrint( const char * c ) {
-  //print the equivalance classes
-  Trace(c) << "----------EQ classes" << std::endl;
-  eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );
-  while( !eqcs_i.isFinished() ){
-    Node n = (*eqcs_i);
-    //if( !n.getType().isInteger() ){
-    Trace(c) << "  - " << n << " : {";
-    eq::EqClassIterator eqc_i = eq::EqClassIterator( n, getEqualityEngine() );
-    bool pr = false;
-    while( !eqc_i.isFinished() ){
-      Node nn = (*eqc_i);
-      if( nn.getKind()!=EQUAL && nn!=n ){
-        Trace(c) << (pr ? "," : "" ) << " " << nn;
-        pr = true;
-      }
-      ++eqc_i;
-    }
-    Trace(c) << (pr ? " " : "" ) << "}" << std::endl;
-    /*
-    EqcInfo * eqcn = getEqcInfo( n, false );
-    if( eqcn ){
-      Trace(c) << "    DEQ : {";
-      pr = false;
-      for( NodeBoolMap::iterator it = eqcn->d_diseq.begin(); it != eqcn->d_diseq.end(); ++it ){
-        if( (*it).second ){
-          Trace(c) << (pr ? "," : "" ) << " " << (*it).first;
-          pr = true;
-        }
-      }
-      Trace(c) << (pr ? " " : "" ) << "}" << std::endl;
-    }
-    //}
-    */
-    ++eqcs_i;
-  }
-}
-
-void QuantConflictFind::debugPrintQuant( const char * c, Node q ) {
-  Trace(c) << "Q" << d_quant_id[q];
-}
-
-void QuantConflictFind::debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum ) {
-  if( n.getNumChildren()==0 ){
-    Trace(c) << n;
-  }else if( doVarNum && d_qinfo[q].d_var_num.find( n )!=d_qinfo[q].d_var_num.end() ){
-    Trace(c) << "?x" << d_qinfo[q].d_var_num[n];
-  }else{
-    Trace(c) << "(";
-    if( n.getKind()==APPLY_UF ){
-      Trace(c) << n.getOperator();
-    }else{
-      Trace(c) << n.getKind();
-    }
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){
-      Trace(c) << " ";
-      debugPrintQuantBody( c, q, n[i] );
-    }
-    Trace(c) << ")";
-  }
-}
-
-QuantConflictFind::Statistics::Statistics():
-  d_inst_rounds("QuantConflictFind::Inst_Rounds", 0),
-  d_conflict_inst("QuantConflictFind::Instantiations_Conflict_Find", 0 ),
-  d_prop_inst("QuantConflictFind::Instantiations_Prop", 0 ),
-  d_entailment_checks("QuantConflictFind::Entailment_Checks",0)
-{
-  StatisticsRegistry::registerStat(&d_inst_rounds);
-  StatisticsRegistry::registerStat(&d_conflict_inst);
-  StatisticsRegistry::registerStat(&d_prop_inst);
-  StatisticsRegistry::registerStat(&d_entailment_checks);
-}
-
-QuantConflictFind::Statistics::~Statistics(){
-  StatisticsRegistry::unregisterStat(&d_inst_rounds);
-  StatisticsRegistry::unregisterStat(&d_conflict_inst);
-  StatisticsRegistry::unregisterStat(&d_prop_inst);
-  StatisticsRegistry::unregisterStat(&d_entailment_checks);
-}
-
-TNode QuantConflictFind::getZero( Kind k ) {
-  std::map< Kind, Node >::iterator it = d_zero.find( k );
-  if( it==d_zero.end() ){
-    Node nn;
-    if( k==PLUS ){
-      nn = NodeManager::currentNM()->mkConst( Rational(0) );
-    }
-    d_zero[k] = nn;
-    return nn;
-  }else{
-    return it->second;
-  }
-}
-
-
-}
+/*********************                                                        */\r
+/*! \file quant_conflict_find.cpp\r
+ ** \verbatim\r
+ ** Original author: Andrew Reynolds\r
+ ** Major contributors: none\r
+ ** Minor contributors (to current version): none\r
+ ** This file is part of the CVC4 project.\r
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
+ ** See the file COPYING in the top-level source directory for licensing\r
+ ** information.\endverbatim\r
+ **\r
+ ** \brief quant conflict find class\r
+ **\r
+ **/\r
+\r
+#include <vector>\r
+\r
+#include "theory/quantifiers/quant_conflict_find.h"\r
+#include "theory/quantifiers/quant_util.h"\r
+#include "theory/theory_engine.h"\r
+#include "theory/quantifiers/options.h"\r
+#include "theory/quantifiers/term_database.h"\r
+#include "theory/quantifiers/trigger.h"\r
+\r
+using namespace CVC4;\r
+using namespace CVC4::kind;\r
+using namespace CVC4::theory;\r
+using namespace CVC4::theory::quantifiers;\r
+using namespace std;\r
+\r
+namespace CVC4 {\r
+\r
+\r
+\r
+void QuantInfo::initialize( Node q, Node qn ) {\r
+  d_q = q;\r
+  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
+    d_match.push_back( TNode::null() );\r
+    d_match_term.push_back( TNode::null() );\r
+  }\r
+\r
+  //register the variables\r
+  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
+    d_var_num[q[0][i]] = i;\r
+    d_vars.push_back( q[0][i] );\r
+  }\r
+\r
+  registerNode( qn, true, true );\r
+\r
+\r
+  Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;\r
+  d_mg = new MatchGen( this, qn );\r
+\r
+  if( d_mg->isValid() ){\r
+    /*\r
+    for( unsigned j=0; j<q[0].getNumChildren(); j++ ){\r
+      if( d_inMatchConstraint.find( q[0][j] )==d_inMatchConstraint.end() ){\r
+        Trace("qcf-invalid") << "QCF invalid : variable " << q[0][j] << " does not exist in a matching constraint." << std::endl;\r
+        d_mg->setInvalid();\r
+        break;\r
+      }\r
+    }\r
+    */\r
+    if( d_mg->isValid() ){\r
+      for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){\r
+        if( d_vars[j].getKind()!=BOUND_VARIABLE ){\r
+          d_var_mg[j] = NULL;\r
+          bool is_tsym = false;\r
+          if( !MatchGen::isHandledUfTerm( d_vars[j] ) && d_vars[j].getKind()!=ITE ){\r
+            is_tsym = true;\r
+            d_tsym_vars.push_back( j );\r
+          }\r
+          if( !is_tsym || options::qcfTConstraint() ){\r
+            d_var_mg[j] = new MatchGen( this, d_vars[j], true );\r
+          }\r
+          if( !d_var_mg[j] || !d_var_mg[j]->isValid() ){\r
+            Trace("qcf-invalid") << "QCF invalid : cannot match for " << d_vars[j] << std::endl;\r
+            d_mg->setInvalid();\r
+            break;\r
+          }else{\r
+            std::vector< int > bvars;\r
+            d_var_mg[j]->determineVariableOrder( this, bvars );\r
+          }\r
+        }\r
+      }\r
+      if( d_mg->isValid() ){\r
+        std::vector< int > bvars;\r
+        d_mg->determineVariableOrder( this, bvars );\r
+      }\r
+    }\r
+  }else{\r
+    Trace("qcf-invalid") << "QCF invalid : body of formula cannot be processed." << std::endl;\r
+  }\r
+  Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? "VALID " : "INVALID" ) << " : " << q << std::endl;\r
+}\r
+\r
+void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant ) {\r
+  Trace("qcf-qregister-debug2") << "Register : " << n << std::endl;\r
+  if( n.getKind()==FORALL ){\r
+    registerNode( n[1], hasPol, pol, true );\r
+  }else{\r
+    if( !MatchGen::isHandledBoolConnective( n ) ){\r
+      if( n.hasBoundVar() ){\r
+        //literals\r
+        if( n.getKind()==EQUAL ){\r
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+            flatten( n[i], beneathQuant );\r
+          }\r
+        }else if( MatchGen::isHandledUfTerm( n ) ){\r
+          flatten( n, beneathQuant );\r
+        }else if( n.getKind()==ITE ){\r
+          for( unsigned i=1; i<=2; i++ ){\r
+            flatten( n[i], beneathQuant );\r
+          }\r
+          registerNode( n[0], false, pol, beneathQuant );\r
+        }else if( options::qcfTConstraint() ){\r
+          //a theory-specific predicate\r
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+            flatten( n[i], beneathQuant );\r
+          }\r
+        }\r
+      }\r
+    }else{\r
+      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+        bool newHasPol;\r
+        bool newPol;\r
+        QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );\r
+        //QcfNode * qcfc = new QcfNode( d_c );\r
+        //qcfc->d_parent = qcf;\r
+        //qcf->d_child[i] = qcfc;\r
+        registerNode( n[i], newHasPol, newPol, beneathQuant );\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+void QuantInfo::flatten( Node n, bool beneathQuant ) {\r
+  Trace("qcf-qregister-debug2") << "Flatten : " << n << std::endl;\r
+  if( n.hasBoundVar() ){\r
+    if( n.getKind()==BOUND_VARIABLE ){\r
+      d_inMatchConstraint[n] = true;\r
+    }\r
+    //if( MatchGen::isHandledUfTerm( n ) || n.getKind()==ITE ){\r
+    if( d_var_num.find( n )==d_var_num.end() ){\r
+      Trace("qcf-qregister-debug2") << "Add FLATTEN VAR : " << n << std::endl;\r
+      d_var_num[n] = d_vars.size();\r
+      d_vars.push_back( n );\r
+      d_match.push_back( TNode::null() );\r
+      d_match_term.push_back( TNode::null() );\r
+      if( n.getKind()==ITE ){\r
+        registerNode( n, false, false );\r
+      }else{\r
+        for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+          flatten( n[i], beneathQuant );\r
+        }\r
+      }\r
+    }else{\r
+      Trace("qcf-qregister-debug2") << "...already processed" << std::endl;\r
+    }\r
+  }else{\r
+    Trace("qcf-qregister-debug2") << "...is ground." << std::endl;\r
+  }\r
+}\r
+\r
+\r
+void QuantInfo::reset_round( QuantConflictFind * p ) {\r
+  for( unsigned i=0; i<d_match.size(); i++ ){\r
+    d_match[i] = TNode::null();\r
+    d_match_term[i] = TNode::null();\r
+  }\r
+  d_curr_var_deq.clear();\r
+  d_tconstraints.clear();\r
+  //add built-in variable constraints\r
+  for( unsigned r=0; r<2; r++ ){\r
+    for( std::map< int, std::vector< Node > >::iterator it = d_var_constraint[r].begin();\r
+         it != d_var_constraint[r].end(); ++it ){\r
+      for( unsigned j=0; j<it->second.size(); j++ ){\r
+        Node rr = it->second[j];\r
+        if( !isVar( rr ) ){\r
+          rr = p->getRepresentative( rr );\r
+        }\r
+        if( addConstraint( p, it->first, rr, r==0 )==-1 ){\r
+          d_var_constraint[0].clear();\r
+          d_var_constraint[1].clear();\r
+          //quantified formula is actually equivalent to true\r
+          Trace("qcf-qregister") << "Quantifier is equivalent to true!!!" << std::endl;\r
+          d_mg->d_children.clear();\r
+          d_mg->d_n = NodeManager::currentNM()->mkConst( true );\r
+          d_mg->d_type = MatchGen::typ_ground;\r
+          return;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  d_mg->reset_round( p );\r
+  for( std::map< int, MatchGen * >::iterator it = d_var_mg.begin(); it != d_var_mg.end(); ++it ){\r
+    it->second->reset_round( p );\r
+  }\r
+  //now, reset for matching\r
+  d_mg->reset( p, false, this );\r
+}\r
+\r
+int QuantInfo::getCurrentRepVar( int v ) {\r
+  if( v!=-1 && !d_match[v].isNull() ){\r
+    int vn = getVarNum( d_match[v] );\r
+    if( vn!=-1 ){\r
+      //int vr = getCurrentRepVar( vn );\r
+      //d_match[v] = d_vars[vr];\r
+      //return vr;\r
+      return getCurrentRepVar( vn );\r
+    }\r
+  }\r
+  return v;\r
+}\r
+\r
+TNode QuantInfo::getCurrentValue( TNode n ) {\r
+  int v = getVarNum( n );\r
+  if( v==-1 ){\r
+    return n;\r
+  }else{\r
+    if( d_match[v].isNull() ){\r
+      return n;\r
+    }else{\r
+      Assert( getVarNum( d_match[v] )!=v );\r
+      return getCurrentValue( d_match[v] );\r
+    }\r
+  }\r
+}\r
+\r
+TNode QuantInfo::getCurrentExpValue( TNode n ) {\r
+  int v = getVarNum( n );\r
+  if( v==-1 ){\r
+    return n;\r
+  }else{\r
+    if( d_match[v].isNull() ){\r
+      return n;\r
+    }else{\r
+      Assert( getVarNum( d_match[v] )!=v );\r
+      if( d_match_term[v].isNull() ){\r
+        return getCurrentValue( d_match[v] );\r
+      }else{\r
+        return d_match_term[v];\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+bool QuantInfo::getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq ) {\r
+  //check disequalities\r
+  std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );\r
+  if( itd!=d_curr_var_deq.end() ){\r
+    for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
+      Node cv = getCurrentValue( it->first );\r
+      Debug("qcf-ccbe") << "compare " << cv << " " << n << std::endl;\r
+      if( cv==n ){\r
+        return false;\r
+      }else if( chDiseq && !isVar( n ) && !isVar( cv ) ){\r
+        //they must actually be disequal if we are looking for conflicts\r
+        if( !p->areDisequal( n, cv ) ){\r
+          //TODO : check for entailed disequal\r
+\r
+          return false;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  return true;\r
+}\r
+\r
+int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity ) {\r
+  v = getCurrentRepVar( v );\r
+  int vn = getVarNum( n );\r
+  vn = vn==-1 ? -1 : getCurrentRepVar( vn );\r
+  n = getCurrentValue( n );\r
+  return addConstraint( p, v, n, vn, polarity, false );\r
+}\r
+\r
+int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove ) {\r
+  //for handling equalities between variables, and disequalities involving variables\r
+  Debug("qcf-match-debug") << "- " << (doRemove ? "un" : "" ) << "constrain : " << v << " -> " << n << " (cv=" << getCurrentValue( n ) << ")";\r
+  Debug("qcf-match-debug") << ", (vn=" << vn << "), polarity = " << polarity << std::endl;\r
+  Assert( doRemove || n==getCurrentValue( n ) );\r
+  Assert( doRemove || v==getCurrentRepVar( v ) );\r
+  Assert( doRemove || vn==getCurrentRepVar( getVarNum( n ) ) );\r
+  if( polarity ){\r
+    if( vn!=v ){\r
+      if( doRemove ){\r
+        if( vn!=-1 ){\r
+          //if set to this in the opposite direction, clean up opposite instead\r
+          //          std::map< int, TNode >::iterator itmn = d_match.find( vn );\r
+          if( d_match[vn]==d_vars[v] ){\r
+            return addConstraint( p, vn, d_vars[v], v, true, true );\r
+          }else{\r
+            //unsetting variables equal\r
+            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( vn );\r
+            if( itd!=d_curr_var_deq.end() ){\r
+              //remove disequalities owned by this\r
+              std::vector< TNode > remDeq;\r
+              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
+                if( it->second==v ){\r
+                  remDeq.push_back( it->first );\r
+                }\r
+              }\r
+              for( unsigned i=0; i<remDeq.size(); i++ ){\r
+                d_curr_var_deq[vn].erase( remDeq[i] );\r
+              }\r
+            }\r
+          }\r
+        }\r
+        d_match[v] = TNode::null();\r
+        return 1;\r
+      }else{\r
+        //std::map< int, TNode >::iterator itm = d_match.find( v );\r
+\r
+        if( vn!=-1 ){\r
+          Debug("qcf-match-debug") << "  ...Variable bound to variable" << std::endl;\r
+          //std::map< int, TNode >::iterator itmn = d_match.find( vn );\r
+          if( d_match[v].isNull() ){\r
+            //setting variables equal\r
+            bool alreadySet = false;\r
+            if( !d_match[vn].isNull() ){\r
+              alreadySet = true;\r
+              Assert( !isVar( d_match[vn] ) );\r
+            }\r
+\r
+            //copy or check disequalities\r
+            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );\r
+            if( itd!=d_curr_var_deq.end() ){\r
+              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
+                Node dv = getCurrentValue( it->first );\r
+                if( !alreadySet ){\r
+                  if( d_curr_var_deq[vn].find( dv )==d_curr_var_deq[vn].end() ){\r
+                    d_curr_var_deq[vn][dv] = v;\r
+                  }\r
+                }else{\r
+                  if( !p->areMatchDisequal( d_match[vn], dv ) ){\r
+                    Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
+                    return -1;\r
+                  }\r
+                }\r
+              }\r
+            }\r
+            if( alreadySet ){\r
+              n = getCurrentValue( n );\r
+            }\r
+          }else{\r
+            if( d_match[vn].isNull() ){\r
+              Debug("qcf-match-debug") << " ...Reverse direction" << std::endl;\r
+              //set the opposite direction\r
+              return addConstraint( p, vn, d_vars[v], v, true, false );\r
+            }else{\r
+              Debug("qcf-match-debug") << "  -> Both variables bound, compare" << std::endl;\r
+              //are they currently equal\r
+              return p->areMatchEqual( d_match[v], d_match[vn] ) ? 0 : -1;\r
+            }\r
+          }\r
+        }else{\r
+          Debug("qcf-match-debug") << "  ...Variable bound to ground" << std::endl;\r
+          if( d_match[v].isNull() ){\r
+          }else{\r
+            //compare ground values\r
+            Debug("qcf-match-debug") << "  -> Ground value, compare " << d_match[v] << " "<< n << std::endl;\r
+            return p->areMatchEqual( d_match[v], n ) ? 0 : -1;\r
+          }\r
+        }\r
+        if( setMatch( p, v, n ) ){\r
+          Debug("qcf-match-debug") << "  -> success" << std::endl;\r
+          return 1;\r
+        }else{\r
+          Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
+          return -1;\r
+        }\r
+      }\r
+    }else{\r
+      Debug("qcf-match-debug") << "  -> redundant, variable identity" << std::endl;\r
+      return 0;\r
+    }\r
+  }else{\r
+    if( vn==v ){\r
+      Debug("qcf-match-debug") << "  -> fail, variable identity" << std::endl;\r
+      return -1;\r
+    }else{\r
+      if( doRemove ){\r
+        Assert( d_curr_var_deq[v].find( n )!=d_curr_var_deq[v].end() );\r
+        d_curr_var_deq[v].erase( n );\r
+        return 1;\r
+      }else{\r
+        if( d_curr_var_deq[v].find( n )==d_curr_var_deq[v].end() ){\r
+          //check if it respects equality\r
+          //std::map< int, TNode >::iterator itm = d_match.find( v );\r
+          if( !d_match[v].isNull() ){\r
+            TNode nv = getCurrentValue( n );\r
+            if( !p->areMatchDisequal( nv, d_match[v] ) ){\r
+              Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
+              return -1;\r
+            }\r
+          }\r
+          d_curr_var_deq[v][n] = v;\r
+          Debug("qcf-match-debug") << "  -> success" << std::endl;\r
+          return 1;\r
+        }else{\r
+          Debug("qcf-match-debug") << "  -> redundant disequality" << std::endl;\r
+          return 0;\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+bool QuantInfo::isConstrainedVar( int v ) {\r
+  if( d_curr_var_deq.find( v )!=d_curr_var_deq.end() && !d_curr_var_deq[v].empty() ){\r
+    return true;\r
+  }else{\r
+    Node vv = getVar( v );\r
+    //for( std::map< int, TNode >::iterator it = d_match.begin(); it != d_match.end(); ++it ){\r
+    for( unsigned i=0; i<d_match.size(); i++ ){\r
+      if( d_match[i]==vv ){\r
+        return true;\r
+      }\r
+    }\r
+    for( std::map< int, std::map< TNode, int > >::iterator it = d_curr_var_deq.begin(); it != d_curr_var_deq.end(); ++it ){\r
+      for( std::map< TNode, int >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){\r
+        if( it2->first==vv ){\r
+          return true;\r
+        }\r
+      }\r
+    }\r
+    return false;\r
+  }\r
+}\r
+\r
+bool QuantInfo::setMatch( QuantConflictFind * p, int v, TNode n ) {\r
+  if( getCurrentCanBeEqual( p, v, n ) ){\r
+    Debug("qcf-match-debug") << "-- bind : " << v << " -> " << n << ", checked " <<  d_curr_var_deq[v].size() << " disequalities" << std::endl;\r
+    d_match[v] = n;\r
+    return true;\r
+  }else{\r
+    return false;\r
+  }\r
+}\r
+\r
+bool QuantInfo::isMatchSpurious( QuantConflictFind * p ) {\r
+  for( int i=0; i<getNumVars(); i++ ){\r
+    //std::map< int, TNode >::iterator it = d_match.find( i );\r
+    if( !d_match[i].isNull() ){\r
+      if( !getCurrentCanBeEqual( p, i, d_match[i], p->d_effort==QuantConflictFind::effort_conflict ) ){\r
+        return true;\r
+      }\r
+    }\r
+  }\r
+  return false;\r
+}\r
+\r
+bool QuantInfo::isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms ) {\r
+  if( !d_tconstraints.empty() ){\r
+    //check constraints\r
+    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){\r
+      //apply substitution to the tconstraint\r
+      Node cons = it->first.substitute( p->getQuantifiersEngine()->getTermDatabase()->d_vars[d_q].begin(),\r
+                                        p->getQuantifiersEngine()->getTermDatabase()->d_vars[d_q].end(),\r
+                                        terms.begin(), terms.end() );\r
+      cons = it->second ? cons : cons.negate();\r
+      if( !entailmentTest( p, cons, p->d_effort==QuantConflictFind::effort_conflict ) ){\r
+        return true;\r
+      }\r
+    }\r
+  }\r
+  return false;\r
+}\r
+\r
+bool QuantInfo::entailmentTest( QuantConflictFind * p, Node lit, bool chEnt ) {\r
+  Trace("qcf-tconstraint-debug") << "Check : " << lit << std::endl;\r
+  Node rew = Rewriter::rewrite( lit );\r
+  if( rew==p->d_false ){\r
+    Trace("qcf-tconstraint-debug") << "...constraint " << lit << " is disentailed (rewrites to false)." << std::endl;\r
+    return false;\r
+  }else if( rew!=p->d_true ){\r
+    //if checking for conflicts, we must be sure that the constraint is entailed\r
+    if( chEnt ){\r
+      //check if it is entailed\r
+      Trace("qcf-tconstraint-debug") << "Check entailment of " << rew << "..." << std::endl;\r
+      std::pair<bool, Node> et = p->getQuantifiersEngine()->getTheoryEngine()->entailmentCheck(THEORY_OF_TYPE_BASED, rew );\r
+      ++(p->d_statistics.d_entailment_checks);\r
+      Trace("qcf-tconstraint-debug") << "ET result : " << et.first << " " << et.second << std::endl;\r
+      if( !et.first ){\r
+        Trace("qcf-tconstraint-debug") << "...cannot show entailment of " << rew << "." << std::endl;\r
+        return false;\r
+      }else{\r
+        return true;\r
+      }\r
+    }else{\r
+      Trace("qcf-tconstraint-debug") << "...does not need to be entailed." << std::endl;\r
+      return true;\r
+    }\r
+  }else{\r
+    Trace("qcf-tconstraint-debug") << "...rewrites to true." << std::endl;\r
+    return true;\r
+  }\r
+}\r
+\r
+bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue ) {\r
+  //assign values for variables that were unassigned (usually not necessary, but handles corner cases)\r
+  bool doFail = false;\r
+  bool success = true;\r
+  if( doContinue ){\r
+    doFail = true;\r
+    success = false;\r
+  }else{\r
+    //solve for interpreted symbol matches\r
+    //   this breaks the invariant that all introduced constraints are over existing terms\r
+    for( int i=(int)(d_tsym_vars.size()-1); i>=0; i-- ){\r
+      int index = d_tsym_vars[i];\r
+      TNode v = getCurrentValue( d_vars[index] );\r
+      int slv_v = -1;\r
+      if( v==d_vars[index] ){\r
+        slv_v = index;\r
+      }\r
+      Trace("qcf-tconstraint-debug") << "Solve " << d_vars[index] << " = " << v << " " << d_vars[index].getKind() << std::endl;\r
+      if( d_vars[index].getKind()==PLUS || d_vars[index].getKind()==MULT ){\r
+        Kind k = d_vars[index].getKind();\r
+        std::vector< TNode > children;\r
+        for( unsigned j=0; j<d_vars[index].getNumChildren(); j++ ){\r
+          int vn = getVarNum( d_vars[index][j] );\r
+          if( vn!=-1 ){\r
+            TNode vv = getCurrentValue( d_vars[index][j] );\r
+            if( vv==d_vars[index][j] ){\r
+              //we will assign this\r
+              if( slv_v==-1 ){\r
+                Trace("qcf-tconstraint-debug") << "...will solve for var #" << vn << std::endl;\r
+                slv_v = vn;\r
+                if( p->d_effort!=QuantConflictFind::effort_conflict ){\r
+                  break;\r
+                }\r
+              }else{\r
+                Node z = p->getZero( k );\r
+                if( !z.isNull() ){\r
+                  Trace("qcf-tconstraint-debug") << "...set " << d_vars[vn] << " = " << z << std::endl;\r
+                  assigned.push_back( vn );\r
+                  if( !setMatch( p, vn, z ) ){\r
+                    success = false;\r
+                    break;\r
+                  }\r
+                }\r
+              }\r
+            }else{\r
+              Trace("qcf-tconstraint-debug") << "...sum value " << vv << std::endl;\r
+              children.push_back( vv );\r
+            }\r
+          }else{\r
+            Trace("qcf-tconstraint-debug") << "...sum " << d_vars[index][j] << std::endl;\r
+            children.push_back( d_vars[index][j] );\r
+          }\r
+        }\r
+        if( success ){\r
+          if( slv_v!=-1 ){\r
+            Node lhs;\r
+            if( children.empty() ){\r
+              lhs = p->getZero( k );\r
+            }else if( children.size()==1 ){\r
+              lhs = children[0];\r
+            }else{\r
+              lhs = NodeManager::currentNM()->mkNode( k, children );\r
+            }\r
+            Node sum;\r
+            if( v==d_vars[index] ){\r
+              sum = lhs;\r
+            }else{\r
+              if( p->d_effort==QuantConflictFind::effort_conflict ){\r
+                Kind kn = k;\r
+                if( d_vars[index].getKind()==PLUS ){\r
+                  kn = MINUS;\r
+                }\r
+                if( kn!=k ){\r
+                  sum = NodeManager::currentNM()->mkNode( kn, v, lhs );\r
+                }\r
+              }\r
+            }\r
+            if( !sum.isNull() ){\r
+              assigned.push_back( slv_v );\r
+              Trace("qcf-tconstraint-debug") << "...set " << d_vars[slv_v] << " = " << sum << std::endl;\r
+              if( !setMatch( p, slv_v, sum ) ){\r
+                success = false;\r
+              }\r
+              p->d_tempCache.push_back( sum );\r
+            }\r
+          }else{\r
+            //must show that constraint is met\r
+            Node sum = NodeManager::currentNM()->mkNode( k, children );\r
+            Node eq = sum.eqNode( v );\r
+            if( !entailmentTest( p, eq ) ){\r
+              success = false;\r
+            }\r
+            p->d_tempCache.push_back( sum );\r
+          }\r
+        }\r
+      }\r
+\r
+      if( !success ){\r
+        break;\r
+      }\r
+    }\r
+    if( success ){\r
+      //check what is left to assign\r
+      d_unassigned.clear();\r
+      d_unassigned_tn.clear();\r
+      std::vector< int > unassigned[2];\r
+      std::vector< TypeNode > unassigned_tn[2];\r
+      for( int i=0; i<getNumVars(); i++ ){\r
+        if( d_match[i].isNull() ){\r
+          int rindex = d_var_mg.find( i )==d_var_mg.end() ? 1 : 0;\r
+          unassigned[rindex].push_back( i );\r
+          unassigned_tn[rindex].push_back( getVar( i ).getType() );\r
+          assigned.push_back( i );\r
+        }\r
+      }\r
+      d_unassigned_nvar = unassigned[0].size();\r
+      for( unsigned i=0; i<2; i++ ){\r
+        d_unassigned.insert( d_unassigned.end(), unassigned[i].begin(), unassigned[i].end() );\r
+        d_unassigned_tn.insert( d_unassigned_tn.end(), unassigned_tn[i].begin(), unassigned_tn[i].end() );\r
+      }\r
+      d_una_eqc_count.clear();\r
+      d_una_index = 0;\r
+    }\r
+  }\r
+\r
+  if( !d_unassigned.empty() && ( success || doContinue ) ){\r
+    Trace("qcf-check") << "Assign to unassigned..." << std::endl;\r
+    do {\r
+      if( doFail ){\r
+        Trace("qcf-check-unassign") << "Failure, try again..." << std::endl;\r
+      }\r
+      bool invalidMatch = false;\r
+      while( ( d_una_index>=0 && (int)d_una_index<(int)d_unassigned.size() ) || invalidMatch || doFail ){\r
+        invalidMatch = false;\r
+        if( !doFail && d_una_index==(int)d_una_eqc_count.size() ){\r
+          //check if it has now been assigned\r
+          if( d_una_index<d_unassigned_nvar ){\r
+            if( !isConstrainedVar( d_unassigned[d_una_index] ) ){\r
+              d_una_eqc_count.push_back( -1 );\r
+            }else{\r
+              d_var_mg[ d_unassigned[d_una_index] ]->reset( p, true, this );\r
+              d_una_eqc_count.push_back( 0 );\r
+            }\r
+          }else{\r
+            d_una_eqc_count.push_back( 0 );\r
+          }\r
+        }else{\r
+          bool failed = false;\r
+          if( !doFail ){\r
+            if( d_una_index<d_unassigned_nvar ){\r
+              if( !isConstrainedVar( d_unassigned[d_una_index] ) ){\r
+                Trace("qcf-check-unassign") << "Succeeded, variable unconstrained at " << d_una_index << std::endl;\r
+                d_una_index++;\r
+              }else if( d_var_mg[d_unassigned[d_una_index]]->getNextMatch( p, this ) ){\r
+                Trace("qcf-check-unassign") << "Succeeded match with mg at " << d_una_index << std::endl;\r
+                d_una_index++;\r
+              }else{\r
+                failed = true;\r
+                Trace("qcf-check-unassign") << "Failed match with mg at " << d_una_index << std::endl;\r
+              }\r
+            }else{\r
+              Assert( doFail || d_una_index==(int)d_una_eqc_count.size()-1 );\r
+              if( d_una_eqc_count[d_una_index]<(int)p->d_eqcs[d_unassigned_tn[d_una_index]].size() ){\r
+                int currIndex = d_una_eqc_count[d_una_index];\r
+                d_una_eqc_count[d_una_index]++;\r
+                Trace("qcf-check-unassign") << d_unassigned[d_una_index] << "->" << p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] << std::endl;\r
+                if( setMatch( p, d_unassigned[d_una_index], p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] ) ){\r
+                  d_match_term[d_unassigned[d_una_index]] = TNode::null();\r
+                  Trace("qcf-check-unassign") << "Succeeded match " << d_una_index << std::endl;\r
+                  d_una_index++;\r
+                }else{\r
+                  Trace("qcf-check-unassign") << "Failed match " << d_una_index << std::endl;\r
+                  invalidMatch = true;\r
+                }\r
+              }else{\r
+                failed = true;\r
+                Trace("qcf-check-unassign") << "No more matches " << d_una_index << std::endl;\r
+              }\r
+            }\r
+          }\r
+          if( doFail || failed ){\r
+            do{\r
+              if( !doFail ){\r
+                d_una_eqc_count.pop_back();\r
+              }else{\r
+                doFail = false;\r
+              }\r
+              d_una_index--;\r
+            }while( d_una_index>=0 && d_una_eqc_count[d_una_index]==-1 );\r
+          }\r
+        }\r
+      }\r
+      success = d_una_index>=0;\r
+      if( success ){\r
+        doFail = true;\r
+        Trace("qcf-check-unassign") << "  Try: " << std::endl;\r
+        for( unsigned i=0; i<d_unassigned.size(); i++ ){\r
+          int ui = d_unassigned[i];\r
+          if( !d_match[ui].isNull() ){\r
+            Trace("qcf-check-unassign") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;\r
+          }\r
+        }\r
+      }\r
+    }while( success && isMatchSpurious( p ) );\r
+  }\r
+  if( success ){\r
+    for( unsigned i=0; i<d_unassigned.size(); i++ ){\r
+      int ui = d_unassigned[i];\r
+      if( !d_match[ui].isNull() ){\r
+        Trace("qcf-check") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;\r
+      }\r
+    }\r
+    return true;\r
+  }else{\r
+    for( unsigned i=0; i<assigned.size(); i++ ){\r
+      d_match[ assigned[i] ] = TNode::null();\r
+    }\r
+    assigned.clear();\r
+    return false;\r
+  }\r
+}\r
+\r
+void QuantInfo::getMatch( std::vector< Node >& terms ){\r
+  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){\r
+    //Node cv = qi->getCurrentValue( qi->d_match[i] );\r
+    int repVar = getCurrentRepVar( i );\r
+    Node cv;\r
+    //std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );\r
+    if( !d_match_term[repVar].isNull() ){\r
+      cv = d_match_term[repVar];\r
+    }else{\r
+      cv = d_match[repVar];\r
+    }\r
+    Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << d_match[i] << std::endl;\r
+    terms.push_back( cv );\r
+  }\r
+}\r
+\r
+void QuantInfo::revertMatch( std::vector< int >& assigned ) {\r
+  for( unsigned i=0; i<assigned.size(); i++ ){\r
+    d_match[ assigned[i] ] = TNode::null();\r
+  }\r
+}\r
+\r
+void QuantInfo::debugPrintMatch( const char * c ) {\r
+  for( int i=0; i<getNumVars(); i++ ){\r
+    Trace(c) << "  " << d_vars[i] << " -> ";\r
+    if( !d_match[i].isNull() ){\r
+      Trace(c) << d_match[i];\r
+    }else{\r
+      Trace(c) << "(unassigned) ";\r
+    }\r
+    if( !d_curr_var_deq[i].empty() ){\r
+      Trace(c) << ", DEQ{ ";\r
+      for( std::map< TNode, int >::iterator it = d_curr_var_deq[i].begin(); it != d_curr_var_deq[i].end(); ++it ){\r
+        Trace(c) << it->first << " ";\r
+      }\r
+      Trace(c) << "}";\r
+    }\r
+    if( !d_match_term[i].isNull() && d_match_term[i]!=d_match[i] ){\r
+      Trace(c) << ", EXP : " << d_match_term[i];\r
+    }\r
+    Trace(c) <<  std::endl;\r
+  }\r
+  if( !d_tconstraints.empty() ){\r
+    Trace(c) << "ADDITIONAL CONSTRAINTS : " << std::endl;\r
+    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){\r
+      Trace(c) << "   " << it->first << " -> " << it->second << std::endl;\r
+    }\r
+  }\r
+}\r
+\r
+MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar ){\r
+  Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << std::endl;\r
+  std::vector< Node > qni_apps;\r
+  d_qni_size = 0;\r
+  if( isVar ){\r
+    Assert( qi->d_var_num.find( n )!=qi->d_var_num.end() );\r
+    if( n.getKind()==ITE ){\r
+      d_type = typ_ite_var;\r
+      d_type_not = false;\r
+      d_n = n;\r
+      d_children.push_back( MatchGen( qi, d_n[0] ) );\r
+      if( d_children[0].isValid() ){\r
+        d_type = typ_ite_var;\r
+        for( unsigned i=1; i<=2; i++ ){\r
+          Node nn = n.eqNode( n[i] );\r
+          d_children.push_back( MatchGen( qi, nn ) );\r
+          d_children[d_children.size()-1].d_qni_bound_except.push_back( 0 );\r
+          if( !d_children[d_children.size()-1].isValid() ){\r
+            setInvalid();\r
+            break;\r
+          }\r
+        }\r
+      }else{\r
+        d_type = typ_invalid;\r
+      }\r
+    }else{\r
+      d_type = isHandledUfTerm( n ) ? typ_var : typ_tsym;\r
+      d_qni_var_num[0] = qi->getVarNum( n );\r
+      d_qni_size++;\r
+      d_type_not = false;\r
+      d_n = n;\r
+      //Node f = getOperator( n );\r
+      for( unsigned j=0; j<d_n.getNumChildren(); j++ ){\r
+        Node nn = d_n[j];\r
+        Trace("qcf-qregister-debug") << "  " << d_qni_size;\r
+        if( qi->isVar( nn ) ){\r
+          int v = qi->d_var_num[nn];\r
+          Trace("qcf-qregister-debug") << " is var #" << v << std::endl;\r
+          d_qni_var_num[d_qni_size] = v;\r
+          //qi->addFuncParent( v, f, j );\r
+        }else{\r
+          Trace("qcf-qregister-debug") << " is gterm " << nn << std::endl;\r
+          d_qni_gterm[d_qni_size] = nn;\r
+        }\r
+        d_qni_size++;\r
+      }\r
+    }\r
+  }else{\r
+    if( n.hasBoundVar() ){\r
+      d_type_not = false;\r
+      d_n = n;\r
+      if( d_n.getKind()==NOT ){\r
+        d_n = d_n[0];\r
+        d_type_not = !d_type_not;\r
+      }\r
+\r
+      if( isHandledBoolConnective( d_n ) ){\r
+        //non-literals\r
+        d_type = typ_formula;\r
+        for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
+          if( d_n.getKind()!=FORALL || i==1 ){\r
+            d_children.push_back( MatchGen( qi, d_n[i], false ) );\r
+            if( !d_children[d_children.size()-1].isValid() ){\r
+              setInvalid();\r
+              break;\r
+            }\r
+          }\r
+          /*\r
+          else if( isTop && n.getKind()==OR && d_children[d_children.size()-1].d_type==typ_var_eq ){\r
+            Trace("qcf-qregister-debug") << "Remove child, make built-in constraint" << std::endl;\r
+            //if variable equality/disequality at top level, remove immediately\r
+            bool cIsNot = d_children[d_children.size()-1].d_type_not;\r
+            Node cn = d_children[d_children.size()-1].d_n;\r
+            Assert( cn.getKind()==EQUAL );\r
+            Assert( p->d_qinfo[q].isVar( cn[0] ) || p->d_qinfo[q].isVar( cn[1] ) );\r
+            //make it a built-in constraint instead\r
+            for( unsigned i=0; i<2; i++ ){\r
+              if( p->d_qinfo[q].isVar( cn[i] ) ){\r
+                int v = p->d_qinfo[q].getVarNum( cn[i] );\r
+                Node cno = cn[i==0 ? 1 : 0];\r
+                p->d_qinfo[q].d_var_constraint[ cIsNot ? 0 : 1 ][v].push_back( cno );\r
+                break;\r
+              }\r
+            }\r
+            d_children.pop_back();\r
+          }\r
+          */\r
+        }\r
+      }else{\r
+        d_type = typ_invalid;\r
+        //literals\r
+        if( isHandledUfTerm( d_n ) ){\r
+          Assert( qi->isVar( d_n ) );\r
+          d_type = typ_pred;\r
+        }else if( d_n.getKind()==BOUND_VARIABLE ){\r
+          Assert( d_n.getType().isBoolean() );\r
+          d_type = typ_bool_var;\r
+        }else if( d_n.getKind()==EQUAL || options::qcfTConstraint() ){\r
+          for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
+            if( d_n[i].hasBoundVar() ){\r
+              if( !qi->isVar( d_n[i] ) ){\r
+                Trace("qcf-qregister-debug")  << "ERROR : not var " << d_n[i] << std::endl;\r
+              }\r
+              Assert( qi->isVar( d_n[i] ) );\r
+              if( d_n.getKind()!=EQUAL && qi->isVar( d_n[i] ) ){\r
+                d_qni_var_num[i+1] = qi->d_var_num[d_n[i]];\r
+              }\r
+            }else{\r
+              d_qni_gterm[i] = d_n[i];\r
+            }\r
+          }\r
+          d_type = d_n.getKind()==EQUAL ? typ_eq : typ_tconstraint;\r
+          Trace("qcf-tconstraint") << "T-Constraint : " << d_n << std::endl;\r
+        }\r
+      }\r
+    }else{\r
+      //we will just evaluate\r
+      d_n = n;\r
+      d_type = typ_ground;\r
+    }\r
+    //if( d_type!=typ_invalid ){\r
+      //determine an efficient children ordering\r
+      //if( !d_children.empty() ){\r
+        //for( unsigned i=0; i<d_children.size(); i++ ){\r
+        //  d_children_order.push_back( i );\r
+        //}\r
+        //if( !d_n.isNull() && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF ) ){\r
+          //sort based on the type of the constraint : ground comes first, then literals, then others\r
+          //MatchGenSort mgs;\r
+          //mgs.d_mg = this;\r
+          //std::sort( d_children_order.begin(), d_children_order.end(), mgs );\r
+        //}\r
+      //}\r
+    //}\r
+  }\r
+  Trace("qcf-qregister-debug")  << "Done make match gen " << n << ", type = ";\r
+  debugPrintType( "qcf-qregister-debug", d_type, true );\r
+  Trace("qcf-qregister-debug") << std::endl;\r
+  //Assert( d_children.size()==d_children_order.size() );\r
+\r
+}\r
+\r
+void MatchGen::collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ) {\r
+  int v = qi->getVarNum( n );\r
+  if( v!=-1 && std::find( cbvars.begin(), cbvars.end(), v )==cbvars.end() ){\r
+    cbvars.push_back( v );\r
+  }\r
+  for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+    collectBoundVar( qi, n[i], cbvars );\r
+  }\r
+}\r
+\r
+void MatchGen::determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars ) {\r
+  Trace("qcf-qregister-debug") << "Determine variable order " << d_n << std::endl;\r
+  bool isCom = d_type==typ_formula && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF );\r
+  std::map< int, std::vector< int > > c_to_vars;\r
+  std::map< int, std::vector< int > > vars_to_c;\r
+  std::map< int, int > vb_count;\r
+  std::map< int, int > vu_count;\r
+  std::vector< bool > assigned;\r
+  Trace("qcf-qregister-debug") << "Calculate bound variables..." << std::endl;\r
+  for( unsigned i=0; i<d_children.size(); i++ ){\r
+    collectBoundVar( qi, d_children[i].d_n, c_to_vars[i] );\r
+    assigned.push_back( false );\r
+    vb_count[i] = 0;\r
+    vu_count[i] = 0;\r
+    for( unsigned j=0; j<c_to_vars[i].size(); j++ ){\r
+      int v = c_to_vars[i][j];\r
+      vars_to_c[v].push_back( i );\r
+      if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){\r
+        vu_count[i]++;\r
+        if( !isCom ){\r
+          bvars.push_back( v );\r
+        }\r
+      }else{\r
+        vb_count[i]++;\r
+      }\r
+    }\r
+  }\r
+  if( isCom ){\r
+    //children that bind the least number of unbound variables go first\r
+    do {\r
+      int min_score = -1;\r
+      int min_score_index = -1;\r
+      for( unsigned i=0; i<d_children.size(); i++ ){\r
+        if( !assigned[i] ){\r
+          int score = vu_count[i];\r
+          if( min_score==-1 || score<min_score ){\r
+            min_score = score;\r
+            min_score_index = i;\r
+          }\r
+        }\r
+      }\r
+      Trace("qcf-qregister-debug") << "...assign child " << min_score_index << "/" << d_children.size() << std::endl;\r
+      Assert( min_score_index!=-1 );\r
+      //add to children order\r
+      d_children_order.push_back( min_score_index );\r
+      assigned[min_score_index] = true;\r
+      //if( vb_count[min_score_index]==0 ){\r
+      //  d_independent.push_back( min_score_index );\r
+      //}\r
+      //determine order internal to children\r
+      d_children[min_score_index].determineVariableOrder( qi, bvars );\r
+      Trace("qcf-qregister-debug")  << "...bind variables" << std::endl;\r
+      //now, make it a bound variable\r
+      for( unsigned i=0; i<c_to_vars[min_score_index].size(); i++ ){\r
+        int v = c_to_vars[min_score_index][i];\r
+        if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){\r
+          for( unsigned j=0; j<vars_to_c[v].size(); j++ ){\r
+            int vc = vars_to_c[v][j];\r
+            vu_count[vc]--;\r
+            vb_count[vc]++;\r
+          }\r
+          bvars.push_back( v );\r
+        }\r
+      }\r
+      Trace("qcf-qregister-debug") << "...done assign child " << min_score_index << std::endl;\r
+    }while( d_children_order.size()!=d_children.size() );\r
+    Trace("qcf-qregister-debug") << "Done assign variable ordering for " << d_n << std::endl;\r
+  }else{\r
+    for( unsigned i=0; i<d_children.size(); i++ ){\r
+      d_children_order.push_back( i );\r
+      d_children[i].determineVariableOrder( qi, bvars );\r
+    }\r
+  }\r
+}\r
+\r
+\r
+void MatchGen::reset_round( QuantConflictFind * p ) {\r
+  d_wasSet = false;\r
+  for( unsigned i=0; i<d_children.size(); i++ ){\r
+    d_children[i].reset_round( p );\r
+  }\r
+  for( std::map< int, TNode >::iterator it = d_qni_gterm.begin(); it != d_qni_gterm.end(); ++it ){\r
+    d_qni_gterm_rep[it->first] = p->getRepresentative( it->second );\r
+  }\r
+  if( d_type==typ_ground ){\r
+    int e = p->evaluate( d_n );\r
+    if( e==1 ){\r
+      d_ground_eval[0] = p->d_true;\r
+    }else if( e==-1 ){\r
+      d_ground_eval[0] = p->d_false;\r
+    }\r
+  }else if( d_type==typ_eq ){\r
+    for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
+      if( !d_n[i].hasBoundVar() ){\r
+        d_ground_eval[i] = p->evaluateTerm( d_n[i] );\r
+      }\r
+    }\r
+  }\r
+  d_qni_bound_cons.clear();\r
+  d_qni_bound_cons_var.clear();\r
+  d_qni_bound.clear();\r
+}\r
+\r
+void MatchGen::reset( QuantConflictFind * p, bool tgt, QuantInfo * qi ) {\r
+  d_tgt = d_type_not ? !tgt : tgt;\r
+  Debug("qcf-match") << "     Reset for : " << d_n << ", type : ";\r
+  debugPrintType( "qcf-match", d_type );\r
+  Debug("qcf-match") << ", tgt = " << d_tgt << ", children = " << d_children.size() << " " << d_children_order.size() << std::endl;\r
+  d_qn.clear();\r
+  d_qni.clear();\r
+  d_qni_bound.clear();\r
+  d_child_counter = -1;\r
+  d_tgt_orig = d_tgt;\r
+\r
+  //set up processing matches\r
+  if( d_type==typ_invalid ){\r
+    //do nothing\r
+  }else if( d_type==typ_ground ){\r
+    if( d_ground_eval[0]==( d_tgt ? p->d_true : p->d_false ) ){\r
+      d_child_counter = 0;\r
+    }\r
+  }else if( d_type==typ_bool_var ){\r
+    //get current value of the variable\r
+    TNode n = qi->getCurrentValue( d_n );\r
+    int vn = qi->getCurrentRepVar( qi->getVarNum( n ) );\r
+    if( vn==-1 ){\r
+      //evaluate the value, see if it is compatible\r
+      int e = p->evaluate( n );\r
+      if( ( e==1 && d_tgt ) || ( e==0 && !d_tgt ) ){\r
+        d_child_counter = 0;\r
+      }\r
+    }else{\r
+      //unassigned, set match to true/false\r
+      d_qni_bound[0] = vn;\r
+      qi->setMatch( p, vn, d_tgt ? p->d_true : p->d_false );\r
+      d_child_counter = 0;\r
+    }\r
+    if( d_child_counter==0 ){\r
+      d_qn.push_back( NULL );\r
+    }\r
+  }else if( d_type==typ_var ){\r
+    Assert( isHandledUfTerm( d_n ) );\r
+    Node f = getOperator( p, d_n );\r
+    Debug("qcf-match-debug") << "       reset: Var will match operators of " << f << std::endl;\r
+    TermArgTrie * qni = p->getTermDatabase()->getTermArgTrie( Node::null(), f );\r
+    if( qni!=NULL ){\r
+      d_qn.push_back( qni );\r
+    }\r
+    d_matched_basis = false;\r
+  }else if( d_type==typ_tsym || d_type==typ_tconstraint ){\r
+    for( std::map< int, int >::iterator it = d_qni_var_num.begin(); it != d_qni_var_num.end(); ++it ){\r
+      int repVar = qi->getCurrentRepVar( it->second );\r
+      if( qi->d_match[repVar].isNull() ){\r
+        Debug("qcf-match-debug") << "Force matching on child #" << it->first << ", which is var #" << repVar << std::endl;\r
+        d_qni_bound[it->first] = repVar;\r
+      }\r
+    }\r
+    d_qn.push_back( NULL );\r
+  }else if( d_type==typ_pred || d_type==typ_eq ){\r
+    //add initial constraint\r
+    Node nn[2];\r
+    int vn[2];\r
+    if( d_type==typ_pred ){\r
+      nn[0] = qi->getCurrentValue( d_n );\r
+      vn[0] = qi->getCurrentRepVar( qi->getVarNum( nn[0] ) );\r
+      nn[1] = p->getRepresentative( d_tgt ? p->d_true : p->d_false );\r
+      vn[1] = -1;\r
+      d_tgt = true;\r
+    }else{\r
+      for( unsigned i=0; i<2; i++ ){\r
+        TNode nc;\r
+        std::map< int, TNode >::iterator it = d_qni_gterm_rep.find( i );\r
+        if( it!=d_qni_gterm_rep.end() ){\r
+          nc = it->second;\r
+        }else{\r
+          nc = d_n[i];\r
+        }\r
+        nn[i] = qi->getCurrentValue( nc );\r
+        vn[i] = qi->getCurrentRepVar( qi->getVarNum( nn[i] ) );\r
+      }\r
+    }\r
+    bool success;\r
+    if( vn[0]==-1 && vn[1]==-1 ){\r
+      //Trace("qcf-explain") << "    reset : " << d_n << " check ground values " << nn[0] << " " << nn[1] << " (tgt=" << d_tgt << ")" << std::endl;\r
+      Debug("qcf-match-debug") << "       reset: check ground values " << nn[0] << " " << nn[1] << " (" << d_tgt << ")" << std::endl;\r
+      //just compare values\r
+      if( d_tgt ){\r
+        success = p->areMatchEqual( nn[0], nn[1] );\r
+      }else{\r
+        if( p->d_effort==QuantConflictFind::effort_conflict ){\r
+          success = p->areDisequal( nn[0], nn[1] );\r
+        }else{\r
+          success = p->areMatchDisequal( nn[0], nn[1] );\r
+        }\r
+      }\r
+    }else{\r
+      //otherwise, add a constraint to a variable\r
+      if( vn[1]!=-1 && vn[0]==-1 ){\r
+        //swap\r
+        Node t = nn[1];\r
+        nn[1] = nn[0];\r
+        nn[0] = t;\r
+        vn[0] = vn[1];\r
+        vn[1] = -1;\r
+      }\r
+      Debug("qcf-match-debug") << "       reset: add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << std::endl;\r
+      //add some constraint\r
+      int addc = qi->addConstraint( p, vn[0], nn[1], vn[1], d_tgt, false );\r
+      success = addc!=-1;\r
+      //if successful and non-redundant, store that we need to cleanup this\r
+      if( addc==1 ){\r
+        //Trace("qcf-explain") << "       reset: " << d_n << " add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << ", d_tgt = " << d_tgt << std::endl;\r
+        for( unsigned i=0; i<2; i++ ){\r
+          if( vn[i]!=-1 && std::find( d_qni_bound_except.begin(), d_qni_bound_except.end(), i )==d_qni_bound_except.end() ){\r
+            d_qni_bound[vn[i]] = vn[i];\r
+          }\r
+        }\r
+        d_qni_bound_cons[vn[0]] = nn[1];\r
+        d_qni_bound_cons_var[vn[0]] = vn[1];\r
+      }\r
+    }\r
+    //if successful, we will bind values to variables\r
+    if( success ){\r
+      d_qn.push_back( NULL );\r
+    }\r
+  }else{\r
+    if( d_children.empty() ){\r
+      //add dummy\r
+      d_qn.push_back( NULL );\r
+    }else{\r
+      if( d_tgt && d_n.getKind()==FORALL ){\r
+        //do nothing\r
+      }else{\r
+        //reset the first child to d_tgt\r
+        d_child_counter = 0;\r
+        getChild( d_child_counter )->reset( p, d_tgt, qi );\r
+      }\r
+    }\r
+  }\r
+  d_binding = false;\r
+  d_wasSet = true;\r
+  Debug("qcf-match") << "     reset: Finished reset for " << d_n << ", success = " << ( !d_qn.empty() || d_child_counter!=-1 ) << std::endl;\r
+}\r
+\r
+bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {\r
+  Debug("qcf-match") << "     Get next match for : " << d_n << ", type = ";\r
+  debugPrintType( "qcf-match", d_type );\r
+  Debug("qcf-match") << ", children = " << d_children.size() << ", binding = " << d_binding << std::endl;\r
+  if( d_type==typ_invalid || d_type==typ_ground ){\r
+    if( d_child_counter==0 ){\r
+      d_child_counter = -1;\r
+      return true;\r
+    }else{\r
+      d_wasSet = false;\r
+      return false;\r
+    }\r
+  }else if( d_type==typ_var || d_type==typ_eq || d_type==typ_pred || d_type==typ_bool_var || d_type==typ_tconstraint || d_type==typ_tsym ){\r
+    bool success = false;\r
+    bool terminate = false;\r
+    do {\r
+      bool doReset = false;\r
+      bool doFail = false;\r
+      if( !d_binding ){\r
+        if( doMatching( p, qi ) ){\r
+          Debug("qcf-match-debug") << "     - Matching succeeded" << std::endl;\r
+          d_binding = true;\r
+          d_binding_it = d_qni_bound.begin();\r
+          doReset = true;\r
+          //for tconstraint, add constraint\r
+          if( d_type==typ_tconstraint ){\r
+            std::map< Node, bool >::iterator it = qi->d_tconstraints.find( d_n );\r
+            if( it==qi->d_tconstraints.end() ){\r
+              qi->d_tconstraints[d_n] = d_tgt;\r
+              //store that we added this constraint\r
+              d_qni_bound_cons[0] = d_n;\r
+            }else if( d_tgt!=it->second ){\r
+              success = false;\r
+              terminate = true;\r
+            }\r
+          }\r
+        }else{\r
+          Debug("qcf-match-debug") << "     - Matching failed" << std::endl;\r
+          success = false;\r
+          terminate = true;\r
+        }\r
+      }else{\r
+        doFail = true;\r
+      }\r
+      if( d_binding ){\r
+        //also need to create match for each variable we bound\r
+        success = true;\r
+        Debug("qcf-match-debug") << "     Produce matches for bound variables by " << d_n << ", type = ";\r
+        debugPrintType( "qcf-match-debug", d_type );\r
+        Debug("qcf-match-debug") << "..." << std::endl;\r
+\r
+        while( ( success && d_binding_it!=d_qni_bound.end() ) || doFail ){\r
+          std::map< int, MatchGen * >::iterator itm;\r
+          if( !doFail ){\r
+            Debug("qcf-match-debug") << "       check variable " << d_binding_it->second << std::endl;\r
+            itm = qi->d_var_mg.find( d_binding_it->second );\r
+          }\r
+          if( doFail || ( d_binding_it->first!=0 && itm!=qi->d_var_mg.end() ) ){\r
+            Debug("qcf-match-debug") << "       we had bound variable " << d_binding_it->second << ", reset = " << doReset << std::endl;\r
+            if( doReset ){\r
+              itm->second->reset( p, true, qi );\r
+            }\r
+            if( doFail || !itm->second->getNextMatch( p, qi ) ){\r
+              do {\r
+                if( d_binding_it==d_qni_bound.begin() ){\r
+                  Debug("qcf-match-debug") << "       failed." << std::endl;\r
+                  success = false;\r
+                }else{\r
+                  --d_binding_it;\r
+                  Debug("qcf-match-debug") << "       decrement..." << std::endl;\r
+                }\r
+              }while( success && ( d_binding_it->first==0 || qi->d_var_mg.find( d_binding_it->second )==qi->d_var_mg.end() ) );\r
+              doReset = false;\r
+              doFail = false;\r
+            }else{\r
+              Debug("qcf-match-debug") << "       increment..." << std::endl;\r
+              ++d_binding_it;\r
+              doReset = true;\r
+            }\r
+          }else{\r
+            Debug("qcf-match-debug") << "       skip..." << d_binding_it->second << std::endl;\r
+            ++d_binding_it;\r
+            doReset = true;\r
+          }\r
+        }\r
+        if( !success ){\r
+          d_binding = false;\r
+        }else{\r
+          terminate = true;\r
+          if( d_binding_it==d_qni_bound.begin() ){\r
+            d_binding = false;\r
+          }\r
+        }\r
+      }\r
+    }while( !terminate );\r
+    //if not successful, clean up the variables you bound\r
+    if( !success ){\r
+      if( d_type==typ_eq || d_type==typ_pred ){\r
+        //clean up the constraints you added\r
+        for( std::map< int, TNode >::iterator it = d_qni_bound_cons.begin(); it != d_qni_bound_cons.end(); ++it ){\r
+          if( !it->second.isNull() ){\r
+            Debug("qcf-match") << "       Clean up bound var " << it->first << (d_tgt ? "!" : "") << " = " << it->second << std::endl;\r
+            std::map< int, int >::iterator itb = d_qni_bound_cons_var.find( it->first );\r
+            int vn = itb!=d_qni_bound_cons_var.end() ? itb->second : -1;\r
+            //Trace("qcf-explain") << "       cleanup: " << d_n << " remove constraint " << it->first << " -> " << it->second << " (vn=" << vn << ")" << ", d_tgt = " << d_tgt << std::endl;\r
+            qi->addConstraint( p, it->first, it->second, vn, d_tgt, true );\r
+          }\r
+        }\r
+        d_qni_bound_cons.clear();\r
+        d_qni_bound_cons_var.clear();\r
+        d_qni_bound.clear();\r
+      }else{\r
+        //clean up the matches you set\r
+        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){\r
+          Debug("qcf-match") << "       Clean up bound var " << it->second << std::endl;\r
+          Assert( it->second<qi->getNumVars() );\r
+          qi->d_match[ it->second ] = TNode::null();\r
+          qi->d_match_term[ it->second ] = TNode::null();\r
+        }\r
+        d_qni_bound.clear();\r
+      }\r
+      if( d_type==typ_tconstraint ){\r
+        //remove constraint if applicable\r
+        if( d_qni_bound_cons.find( 0 )!=d_qni_bound_cons.end() ){\r
+          qi->d_tconstraints.erase( d_n );\r
+          d_qni_bound_cons.clear();\r
+        }\r
+      }\r
+      /*\r
+      if( d_type==typ_var && p->d_effort==QuantConflictFind::effort_mc && !d_matched_basis ){\r
+        d_matched_basis = true;\r
+        Node f = getOperator( d_n );\r
+        TNode mbo = p->getQuantifiersEngine()->getTermDatabase()->getModelBasisOpTerm( f );\r
+        if( qi->setMatch( p, d_qni_var_num[0], mbo ) ){\r
+          success = true;\r
+          d_qni_bound[0] = d_qni_var_num[0];\r
+        }\r
+      }\r
+      */\r
+    }\r
+    Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;\r
+    d_wasSet = success;\r
+    return success;\r
+  }else if( d_type==typ_formula || d_type==typ_ite_var ){\r
+    bool success = false;\r
+    if( d_child_counter<0 ){\r
+      if( d_child_counter<-1 ){\r
+        success = true;\r
+        d_child_counter = -1;\r
+      }\r
+    }else{\r
+      while( !success && d_child_counter>=0 ){\r
+        //transition system based on d_child_counter\r
+        if( d_n.getKind()==OR || d_n.getKind()==AND ){\r
+          if( (d_n.getKind()==AND)==d_tgt ){\r
+            //all children must match simultaneously\r
+            if( getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
+              if( d_child_counter<(int)(getNumChildren()-1) ){\r
+                d_child_counter++;\r
+                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << std::endl;\r
+                getChild( d_child_counter )->reset( p, d_tgt, qi );\r
+              }else{\r
+                success = true;\r
+              }\r
+            }else{\r
+              //if( std::find( d_independent.begin(), d_independent.end(), d_child_counter )!=d_independent.end() ){\r
+              //  d_child_counter--;\r
+              //}else{\r
+              d_child_counter--;\r
+              //}\r
+            }\r
+          }else{\r
+            //one child must match\r
+            if( !getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
+              if( d_child_counter<(int)(getNumChildren()-1) ){\r
+                d_child_counter++;\r
+                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << ", one match" << std::endl;\r
+                getChild( d_child_counter )->reset( p, d_tgt, qi );\r
+              }else{\r
+                d_child_counter = -1;\r
+              }\r
+            }else{\r
+              success = true;\r
+            }\r
+          }\r
+        }else if( d_n.getKind()==IFF ){\r
+          //construct match based on both children\r
+          if( d_child_counter%2==0 ){\r
+            if( getChild( 0 )->getNextMatch( p, qi ) ){\r
+              d_child_counter++;\r
+              getChild( 1 )->reset( p, d_child_counter==1, qi );\r
+            }else{\r
+              if( d_child_counter==0 ){\r
+                d_child_counter = 2;\r
+                getChild( 0 )->reset( p, !d_tgt, qi );\r
+              }else{\r
+                d_child_counter = -1;\r
+              }\r
+            }\r
+          }\r
+          if( d_child_counter>=0 && d_child_counter%2==1 ){\r
+            if( getChild( 1 )->getNextMatch( p, qi ) ){\r
+              success = true;\r
+            }else{\r
+              d_child_counter--;\r
+            }\r
+          }\r
+        }else if( d_n.getKind()==ITE ){\r
+          if( d_child_counter%2==0 ){\r
+            int index1 = d_child_counter==4 ? 1 : 0;\r
+            if( getChild( index1 )->getNextMatch( p, qi ) ){\r
+              d_child_counter++;\r
+              getChild( d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2) )->reset( p, d_tgt, qi );\r
+            }else{\r
+              if( d_child_counter==4 || ( d_type==typ_ite_var && d_child_counter==2 ) ){\r
+                d_child_counter = -1;\r
+              }else{\r
+                d_child_counter +=2;\r
+                getChild( d_child_counter==2 ? 0 : 1 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );\r
+              }\r
+            }\r
+          }\r
+          if( d_child_counter>=0 && d_child_counter%2==1 ){\r
+            int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2);\r
+            if( getChild( index2 )->getNextMatch( p, qi ) ){\r
+              success = true;\r
+            }else{\r
+              d_child_counter--;\r
+            }\r
+          }\r
+        }else if( d_n.getKind()==FORALL ){\r
+          if( getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
+            success = true;\r
+          }else{\r
+            d_child_counter = -1;\r
+          }\r
+        }\r
+      }\r
+        d_wasSet = success;\r
+      Debug("qcf-match") << "    ...finished construct match for " << d_n << ", success = " << success << std::endl;\r
+      return success;\r
+    }\r
+  }\r
+  Debug("qcf-match") << "    ...already finished for " << d_n << std::endl;\r
+  return false;\r
+}\r
+\r
+bool MatchGen::getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp ) {\r
+  if( d_type==typ_eq ){\r
+    Node n[2];\r
+    for( unsigned i=0; i<2; i++ ){\r
+      Trace("qcf-explain") << "Explain term " << d_n[i] << "..." << std::endl;\r
+      n[i] = getExplanationTerm( p, qi, d_n[i], exp );\r
+    }\r
+    Node eq = n[0].eqNode( n[1] );\r
+    if( !d_tgt_orig ){\r
+      eq = eq.negate();\r
+    }\r
+    exp.push_back( eq );\r
+    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << eq << ", set = " << d_wasSet << std::endl;\r
+    return true;\r
+  }else if( d_type==typ_pred ){\r
+    Trace("qcf-explain") << "Explain term " << d_n << "..." << std::endl;\r
+    Node n = getExplanationTerm( p, qi, d_n, exp );\r
+    if( !d_tgt_orig ){\r
+      n = n.negate();\r
+    }\r
+    exp.push_back( n );\r
+    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << n << ", set = " << d_wasSet << std::endl;\r
+    return true;\r
+  }else if( d_type==typ_formula ){\r
+    Trace("qcf-explain") << "Explanation get for " << d_n << ", counter = " << d_child_counter << ", tgt = " << d_tgt_orig << ", set = " << d_wasSet << std::endl;\r
+    if( d_n.getKind()==OR || d_n.getKind()==AND ){\r
+      if( (d_n.getKind()==AND)==d_tgt ){\r
+        for( unsigned i=0; i<getNumChildren(); i++ ){\r
+          if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
+            return false;\r
+          }\r
+        }\r
+      }else{\r
+        return getChild( d_child_counter )->getExplanation( p, qi, exp );\r
+      }\r
+    }else if( d_n.getKind()==IFF ){\r
+      for( unsigned i=0; i<2; i++ ){\r
+        if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
+          return false;\r
+        }\r
+      }\r
+    }else if( d_n.getKind()==ITE ){\r
+      for( unsigned i=0; i<3; i++ ){\r
+        bool isActive = ( ( i==0 && d_child_counter!=5 ) ||\r
+                          ( i==1 && d_child_counter!=( d_tgt ? 3 : 1 ) ) ||\r
+                          ( i==2 && d_child_counter!=( d_tgt ? 1 : 3 ) ) );\r
+        if( isActive ){\r
+          if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
+            return false;\r
+          }\r
+        }\r
+      }\r
+    }else{\r
+      return false;\r
+    }\r
+    return true;\r
+  }else{\r
+    return false;\r
+  }\r
+}\r
+\r
+Node MatchGen::getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp ) {\r
+  Node v = qi->getCurrentExpValue( t );\r
+  if( isHandledUfTerm( t ) ){\r
+    for( unsigned i=0; i<t.getNumChildren(); i++ ){\r
+      Node vi = getExplanationTerm( p, qi, t[i], exp );\r
+      if( vi!=v[i] ){\r
+        Node eq = vi.eqNode( v[i] );\r
+        if( std::find( exp.begin(), exp.end(), eq )==exp.end() ){\r
+          Trace("qcf-explain") << "  add : " << eq << "." << std::endl;\r
+          exp.push_back( eq );\r
+        }\r
+      }\r
+    }\r
+  }\r
+  return v;\r
+}\r
+\r
+bool MatchGen::doMatching( QuantConflictFind * p, QuantInfo * qi ) {\r
+  if( !d_qn.empty() ){\r
+    if( d_qn[0]==NULL ){\r
+      d_qn.clear();\r
+      return true;\r
+    }else{\r
+      Assert( d_type==typ_var );\r
+      Assert( d_qni_size>0 );\r
+      bool invalidMatch;\r
+      do {\r
+        invalidMatch = false;\r
+        Debug("qcf-match-debug") << "       Do matching " << d_n << " " << d_qn.size() << " " << d_qni.size() << std::endl;\r
+        if( d_qn.size()==d_qni.size()+1 ) {\r
+          int index = (int)d_qni.size();\r
+          //initialize\r
+          TNode val;\r
+          std::map< int, int >::iterator itv = d_qni_var_num.find( index );\r
+          if( itv!=d_qni_var_num.end() ){\r
+            //get the representative variable this variable is equal to\r
+            int repVar = qi->getCurrentRepVar( itv->second );\r
+            Debug("qcf-match-debug") << "       Match " << index << " is a variable " << itv->second << ", which is repVar " << repVar << std::endl;\r
+            //get the value the rep variable\r
+            //std::map< int, TNode >::iterator itm = qi->d_match.find( repVar );\r
+            if( !qi->d_match[repVar].isNull() ){\r
+              val = qi->d_match[repVar];\r
+              Debug("qcf-match-debug") << "       Variable is already bound to " << val << std::endl;\r
+            }else{\r
+              //binding a variable\r
+              d_qni_bound[index] = repVar;\r
+              std::map< TNode, TermArgTrie >::iterator it = d_qn[index]->d_data.begin();\r
+              if( it != d_qn[index]->d_data.end() ) {\r
+                d_qni.push_back( it );\r
+                //set the match\r
+                if( qi->setMatch( p, d_qni_bound[index], it->first ) ){\r
+                  Debug("qcf-match-debug") << "       Binding variable" << std::endl;\r
+                  if( d_qn.size()<d_qni_size ){\r
+                    d_qn.push_back( &it->second );\r
+                  }\r
+                }else{\r
+                  Debug("qcf-match") << "       Binding variable, currently fail." << std::endl;\r
+                  invalidMatch = true;\r
+                }\r
+              }else{\r
+                Debug("qcf-match-debug") << "       Binding variable, fail, no more variables to bind" << std::endl;\r
+                d_qn.pop_back();\r
+              }\r
+            }\r
+          }else{\r
+            Debug("qcf-match-debug") << "       Match " << index << " is ground term" << std::endl;\r
+            Assert( d_qni_gterm.find( index )!=d_qni_gterm.end() );\r
+            Assert( d_qni_gterm_rep.find( index )!=d_qni_gterm_rep.end() );\r
+            val = d_qni_gterm_rep[index];\r
+            Assert( !val.isNull() );\r
+          }\r
+          if( !val.isNull() ){\r
+            //constrained by val\r
+            std::map< TNode, TermArgTrie >::iterator it = d_qn[index]->d_data.find( val );\r
+            if( it!=d_qn[index]->d_data.end() ){\r
+              Debug("qcf-match-debug") << "       Match" << std::endl;\r
+              d_qni.push_back( it );\r
+              if( d_qn.size()<d_qni_size ){\r
+                d_qn.push_back( &it->second );\r
+              }\r
+            }else{\r
+              Debug("qcf-match-debug") << "       Failed to match" << std::endl;\r
+              d_qn.pop_back();\r
+            }\r
+          }\r
+        }else{\r
+          Assert( d_qn.size()==d_qni.size() );\r
+          int index = d_qni.size()-1;\r
+          //increment if binding this variable\r
+          bool success = false;\r
+          std::map< int, int >::iterator itb = d_qni_bound.find( index );\r
+          if( itb!=d_qni_bound.end() ){\r
+            d_qni[index]++;\r
+            if( d_qni[index]!=d_qn[index]->d_data.end() ){\r
+              success = true;\r
+              if( qi->setMatch( p, itb->second, d_qni[index]->first ) ){\r
+                Debug("qcf-match-debug") << "       Bind next variable" << std::endl;\r
+                if( d_qn.size()<d_qni_size ){\r
+                  d_qn.push_back( &d_qni[index]->second );\r
+                }\r
+              }else{\r
+                Debug("qcf-match-debug") << "       Bind next variable, currently fail" << std::endl;\r
+                invalidMatch = true;\r
+              }\r
+            }else{\r
+              qi->d_match[ itb->second ] = TNode::null();\r
+              qi->d_match_term[ itb->second ] = TNode::null();\r
+              Debug("qcf-match-debug") << "       Bind next variable, no more variables to bind" << std::endl;\r
+            }\r
+          }else{\r
+            //TODO : if it equal to something else, also try that\r
+          }\r
+          //if not incrementing, move to next\r
+          if( !success ){\r
+            d_qn.pop_back();\r
+            d_qni.pop_back();\r
+          }\r
+        }\r
+      }while( ( !d_qn.empty() && d_qni.size()!=d_qni_size ) || invalidMatch );\r
+      if( d_qni.size()==d_qni_size ){\r
+        //Assert( !d_qni[d_qni.size()-1]->second.d_data.empty() );\r
+        //Debug("qcf-match-debug") << "       We matched " << d_qni[d_qni.size()-1]->second.d_children.begin()->first << std::endl;\r
+        Assert( !d_qni[d_qni.size()-1]->second.d_data.empty() );\r
+        TNode t = d_qni[d_qni.size()-1]->second.d_data.begin()->first;\r
+        Debug("qcf-match-debug") << "       " << d_n << " matched " << t << std::endl;\r
+        qi->d_match_term[d_qni_var_num[0]] = t;\r
+        //set the match terms\r
+        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){\r
+          Debug("qcf-match-debug") << "       position " << it->first << " bounded " << it->second << " / " << qi->d_q[0].getNumChildren() << std::endl;\r
+          //if( it->second<(int)qi->d_q[0].getNumChildren() ){   //if it is an actual variable, we are interested in knowing the actual term\r
+          if( it->first>0 ){\r
+            Assert( !qi->d_match[ it->second ].isNull() );\r
+            Assert( p->areEqual( t[it->first-1], qi->d_match[ it->second ] ) );\r
+            qi->d_match_term[it->second] = t[it->first-1];\r
+          }\r
+          //}\r
+        }\r
+      }\r
+    }\r
+  }\r
+  return !d_qn.empty();\r
+}\r
+\r
+void MatchGen::debugPrintType( const char * c, short typ, bool isTrace ) {\r
+  if( isTrace ){\r
+    switch( typ ){\r
+    case typ_invalid: Trace(c) << "invalid";break;\r
+    case typ_ground: Trace(c) << "ground";break;\r
+    case typ_eq: Trace(c) << "eq";break;\r
+    case typ_pred: Trace(c) << "pred";break;\r
+    case typ_formula: Trace(c) << "formula";break;\r
+    case typ_var: Trace(c) << "var";break;\r
+    case typ_ite_var: Trace(c) << "ite_var";break;\r
+    case typ_bool_var: Trace(c) << "bool_var";break;\r
+    }\r
+  }else{\r
+    switch( typ ){\r
+    case typ_invalid: Debug(c) << "invalid";break;\r
+    case typ_ground: Debug(c) << "ground";break;\r
+    case typ_eq: Debug(c) << "eq";break;\r
+    case typ_pred: Debug(c) << "pred";break;\r
+    case typ_formula: Debug(c) << "formula";break;\r
+    case typ_var: Debug(c) << "var";break;\r
+    case typ_ite_var: Debug(c) << "ite_var";break;\r
+    case typ_bool_var: Debug(c) << "bool_var";break;\r
+    }\r
+  }\r
+}\r
+\r
+void MatchGen::setInvalid() {\r
+  d_type = typ_invalid;\r
+  d_children.clear();\r
+}\r
+\r
+bool MatchGen::isHandledBoolConnective( TNode n ) {\r
+  return n.getType().isBoolean() && ( n.getKind()==OR || n.getKind()==AND || n.getKind()==IFF || n.getKind()==ITE || n.getKind()==FORALL || n.getKind()==NOT );\r
+}\r
+\r
+bool MatchGen::isHandledUfTerm( TNode n ) {\r
+  //return n.getKind()==APPLY_UF || n.getKind()==STORE || n.getKind()==SELECT ||\r
+  //       n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR_TOTAL || n.getKind()==APPLY_TESTER;\r
+  return inst::Trigger::isAtomicTriggerKind( n.getKind() );  \r
+}\r
+\r
+Node MatchGen::getOperator( QuantConflictFind * p, Node n ) {\r
+  if( isHandledUfTerm( n ) ){\r
+    return p->getQuantifiersEngine()->getTermDatabase()->getOperator( n );\r
+  }else{\r
+    return Node::null();\r
+  }\r
+}\r
+\r
+bool MatchGen::isHandled( TNode n ) {\r
+  if( n.getKind()!=BOUND_VARIABLE && n.hasBoundVar() ){\r
+    if( !isHandledBoolConnective( n ) && !isHandledUfTerm( n ) && n.getKind()!=EQUAL && n.getKind()!=ITE ){\r
+      return false;\r
+    }\r
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+      if( !isHandled( n[i] ) ){\r
+        return false;\r
+      }\r
+    }\r
+  }\r
+  return true;\r
+}\r
+\r
+\r
+QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :\r
+QuantifiersModule( qe ),\r
+d_c( c ),\r
+d_conflict( c, false ),\r
+d_qassert( c ) {\r
+  d_fid_count = 0;\r
+  d_true = NodeManager::currentNM()->mkConst<bool>(true);\r
+  d_false = NodeManager::currentNM()->mkConst<bool>(false);\r
+}\r
+\r
+Node QuantConflictFind::mkEqNode( Node a, Node b ) {\r
+  if( a.getType().isBoolean() ){\r
+    return a.iffNode( b );\r
+  }else{\r
+    return a.eqNode( b );\r
+  }\r
+}\r
+\r
+//-------------------------------------------------- registration\r
+\r
+void QuantConflictFind::registerQuantifier( Node q ) {\r
+  if( !TermDb::isRewriteRule( q ) ){\r
+    d_quants.push_back( q );\r
+    d_quant_id[q] = d_quants.size();\r
+    Trace("qcf-qregister") << "Register ";\r
+    debugPrintQuant( "qcf-qregister", q );\r
+    Trace("qcf-qregister") << " : " << q << std::endl;\r
+    //make QcfNode structure\r
+    Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;\r
+    d_qinfo[q].initialize( q, q[1] );\r
+\r
+    //debug print\r
+    Trace("qcf-qregister") << "- Flattened structure is :" << std::endl;\r
+    Trace("qcf-qregister") << "    ";\r
+    debugPrintQuantBody( "qcf-qregister", q, q[1] );\r
+    Trace("qcf-qregister") << std::endl;\r
+    if( d_qinfo[q].d_vars.size()>q[0].getNumChildren() ){\r
+      Trace("qcf-qregister") << "  with additional constraints : " << std::endl;\r
+      for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){\r
+        Trace("qcf-qregister") << "    ?x" << j << " = ";\r
+        debugPrintQuantBody( "qcf-qregister", q, d_qinfo[q].d_vars[j], false );\r
+        Trace("qcf-qregister") << std::endl;\r
+      }\r
+    }\r
+\r
+    Trace("qcf-qregister") << "Done registering quantifier." << std::endl;\r
+  }\r
+}\r
+\r
+int QuantConflictFind::evaluate( Node n, bool pref, bool hasPref ) {\r
+  int ret = 0;\r
+  if( n.getKind()==EQUAL ){\r
+    Node n1 = evaluateTerm( n[0] );\r
+    Node n2 = evaluateTerm( n[1] );\r
+    Debug("qcf-eval") << "Evaluate : Normalize " << n << " to " << n1 << " = " << n2 << std::endl;\r
+    if( areEqual( n1, n2 ) ){\r
+      ret = 1;\r
+    }else if( areDisequal( n1, n2 ) ){\r
+      ret = -1;\r
+    }\r
+    //else if( d_effort>QuantConflictFind::effort_conflict ){\r
+    //  ret = -1;\r
+    //}\r
+  }else if( MatchGen::isHandledUfTerm( n ) ){  //predicate\r
+    Node nn = evaluateTerm( n );\r
+    Debug("qcf-eval") << "Evaluate : Normalize " << nn << " to " << n << std::endl;\r
+    if( areEqual( nn, d_true ) ){\r
+      ret = 1;\r
+    }else if( areEqual( nn, d_false ) ){\r
+      ret = -1;\r
+    }\r
+    //else if( d_effort>QuantConflictFind::effort_conflict ){\r
+    //  ret = -1;\r
+    //}\r
+  }else if( n.getKind()==NOT ){\r
+    return -evaluate( n[0] );\r
+  }else if( n.getKind()==ITE ){\r
+    int cev1 = evaluate( n[0] );\r
+    int cevc[2] = { 0, 0 };\r
+    for( unsigned i=0; i<2; i++ ){\r
+      if( ( i==0 && cev1!=-1 ) || ( i==1 && cev1!=1 ) ){\r
+        cevc[i] = evaluate( n[i+1] );\r
+        if( cev1!=0 ){\r
+          ret = cevc[i];\r
+          break;\r
+        }else if( cevc[i]==0 ){\r
+          break;\r
+        }\r
+      }\r
+    }\r
+    if( ret==0 && cevc[0]!=0 && cevc[0]==cevc[1] ){\r
+      ret = cevc[0];\r
+    }\r
+  }else if( n.getKind()==IFF ){\r
+    int cev1 = evaluate( n[0] );\r
+    if( cev1!=0 ){\r
+      int cev2 = evaluate( n[1] );\r
+      if( cev2!=0 ){\r
+        ret = cev1==cev2 ? 1 : -1;\r
+      }\r
+    }\r
+\r
+  }else{\r
+    int ssval = 0;\r
+    if( n.getKind()==OR ){\r
+      ssval = 1;\r
+    }else if( n.getKind()==AND ){\r
+      ssval = -1;\r
+    }\r
+    bool isUnk = false;\r
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+      int cev = evaluate( n[i] );\r
+      if( cev==ssval ){\r
+        ret = ssval;\r
+        break;\r
+      }else if( cev==0 ){\r
+        isUnk = true;\r
+      }\r
+    }\r
+    if( ret==0 && !isUnk ){\r
+      ret = -ssval;\r
+    }\r
+  }\r
+  Debug("qcf-eval") << "Evaluate " << n << " to " << ret << std::endl;\r
+  return ret;\r
+}\r
+\r
+short QuantConflictFind::getMaxQcfEffort() {\r
+  if( options::qcfMode()==QCF_CONFLICT_ONLY ){\r
+    return effort_conflict;\r
+  }else if( options::qcfMode()==QCF_PROP_EQ ){\r
+    return effort_prop_eq;\r
+  }else if( options::qcfMode()==QCF_MC ){\r
+    return effort_mc;\r
+  }else{\r
+    return 0;\r
+  }\r
+}\r
+\r
+bool QuantConflictFind::areMatchEqual( TNode n1, TNode n2 ) {\r
+  //if( d_effort==QuantConflictFind::effort_mc ){\r
+  //  return n1==n2 || !areDisequal( n1, n2 );\r
+  //}else{\r
+  return n1==n2;\r
+  //}\r
+}\r
+\r
+bool QuantConflictFind::areMatchDisequal( TNode n1, TNode n2 ) {\r
+  //if( d_effort==QuantConflictFind::effort_conflict ){\r
+  //  return areDisequal( n1, n2 );\r
+  //}else{\r
+  return n1!=n2;\r
+  //}\r
+}\r
+\r
+//-------------------------------------------------- handling assertions / eqc\r
+\r
+void QuantConflictFind::assertNode( Node q ) {\r
+  if( !TermDb::isRewriteRule( q ) ){\r
+    Trace("qcf-proc") << "QCF : assertQuantifier : ";\r
+    debugPrintQuant("qcf-proc", q);\r
+    Trace("qcf-proc") << std::endl;\r
+    d_qassert.push_back( q );\r
+    //set the eqRegistries that this depends on to true\r
+    //for( std::map< EqRegistry *, bool >::iterator it = d_qinfo[q].d_rel_eqr.begin(); it != d_qinfo[q].d_rel_eqr.end(); ++it ){\r
+    //  it->first->d_active.set( true );\r
+    //}\r
+  }\r
+}\r
+\r
+eq::EqualityEngine * QuantConflictFind::getEqualityEngine() {\r
+  //return ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( theory::THEORY_UF ))->getEqualityEngine();\r
+  return d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();\r
+}\r
+bool QuantConflictFind::areEqual( Node n1, Node n2 ) {\r
+  return getEqualityEngine()->hasTerm( n1 ) && getEqualityEngine()->hasTerm( n2 ) && getEqualityEngine()->areEqual( n1,n2 );\r
+}\r
+bool QuantConflictFind::areDisequal( Node n1, Node n2 ) {\r
+  return n1!=n2 && getEqualityEngine()->hasTerm( n1 ) && getEqualityEngine()->hasTerm( n2 ) && getEqualityEngine()->areDisequal( n1,n2, false );\r
+}\r
+Node QuantConflictFind::getRepresentative( Node n ) {\r
+  if( getEqualityEngine()->hasTerm( n ) ){\r
+    return getEqualityEngine()->getRepresentative( n );\r
+  }else{\r
+    return n;\r
+  }\r
+}\r
+TermDb* QuantConflictFind::getTermDatabase() { \r
+  return d_quantEngine->getTermDatabase();\r
+}\r
+\r
+Node QuantConflictFind::evaluateTerm( Node n ) {\r
+  if( MatchGen::isHandledUfTerm( n ) ){\r
+    Node f = MatchGen::getOperator( this, n );\r
+    Node nn;\r
+    if( getEqualityEngine()->hasTerm( n ) ){\r
+      nn = getTermDatabase()->existsTerm( f, n );\r
+    }else{\r
+      std::vector< TNode > args;\r
+      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+        Node c = evaluateTerm( n[i] );\r
+        args.push_back( c );\r
+      }\r
+      nn = getTermDatabase()->d_func_map_trie[f].existsTerm( args );\r
+    }\r
+    if( !nn.isNull() ){\r
+      Debug("qcf-eval") << "GT: Term " << nn << " for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;\r
+      return getRepresentative( nn );\r
+    }else{\r
+      Debug("qcf-eval") << "GT: No term for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;\r
+      return n;\r
+    }\r
+  }else if( n.getKind()==ITE ){\r
+    int v = evaluate( n[0], false, false );\r
+    if( v==1 ){\r
+      return evaluateTerm( n[1] );\r
+    }else if( v==-1 ){\r
+      return evaluateTerm( n[2] );\r
+    }\r
+  }\r
+  return getRepresentative( n );\r
+}\r
+\r
+/** new node */\r
+void QuantConflictFind::newEqClass( Node n ) {\r
+  //Trace("qcf-proc-debug") << "QCF : newEqClass : " << n << std::endl;\r
+  //Trace("qcf-proc2-debug") << "QCF : finished newEqClass : " << n << std::endl;\r
+}\r
+\r
+/** merge */\r
+void QuantConflictFind::merge( Node a, Node b ) {\r
+\r
+}\r
+\r
+/** assert disequal */\r
+void QuantConflictFind::assertDisequal( Node a, Node b ) {\r
+\r
+}\r
+\r
+//-------------------------------------------------- check function\r
+\r
+void QuantConflictFind::reset_round( Theory::Effort level ) {\r
+  d_needs_computeRelEqr = true;\r
+}\r
+\r
+/** check */\r
+void QuantConflictFind::check( Theory::Effort level ) {\r
+  Trace("qcf-check") << "QCF : check : " << level << std::endl;\r
+  if( d_conflict ){\r
+    Trace("qcf-check2") << "QCF : finished check : already in conflict." << std::endl;\r
+    if( level>=Theory::EFFORT_FULL ){\r
+      Trace("qcf-warn") << "ALREADY IN CONFLICT? " << level << std::endl;\r
+      //Assert( false );\r
+    }\r
+  }else{\r
+    int addedLemmas = 0;\r
+    if( d_performCheck ){\r
+      ++(d_statistics.d_inst_rounds);\r
+      double clSet = 0;\r
+      int prevEt = 0;\r
+      if( Trace.isOn("qcf-engine") ){\r
+        prevEt = d_statistics.d_entailment_checks.getData();\r
+        clSet = double(clock())/double(CLOCKS_PER_SEC);\r
+        Trace("qcf-engine") << "---Conflict Find Engine Round, effort = " << level << "---" << std::endl;\r
+      }\r
+      computeRelevantEqr();\r
+\r
+      //determine order for quantified formulas\r
+      std::vector< Node > qorder;\r
+      std::map< Node, bool > qassert;\r
+      //mark which are asserted\r
+      for( unsigned i=0; i<d_qassert.size(); i++ ){\r
+        qassert[d_qassert[i]] = true;\r
+      }\r
+      //add which ones are specified in the order\r
+      for( unsigned i=0; i<d_quant_order.size(); i++ ){\r
+        Node n = d_quant_order[i];\r
+        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() && qassert.find( n )!=qassert.end() ){\r
+          qorder.push_back( n );\r
+        }\r
+      }\r
+      d_quant_order.clear();\r
+      d_quant_order.insert( d_quant_order.begin(), qorder.begin(), qorder.end() );\r
+      //add remaining\r
+      for( unsigned i=0; i<d_qassert.size(); i++ ){\r
+        Node n = d_qassert[i];\r
+        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() ){\r
+          qorder.push_back( n );\r
+        }\r
+      }\r
+\r
+      if( Trace.isOn("qcf-debug") ){\r
+        Trace("qcf-debug") << std::endl;\r
+        debugPrint("qcf-debug");\r
+        Trace("qcf-debug") << std::endl;\r
+      }\r
+      short end_e = getMaxQcfEffort();\r
+      for( short e = effort_conflict; e<=end_e; e++ ){\r
+        d_effort = e;\r
+        Trace("qcf-check") << "Checking quantified formulas at effort " << e << "..." << std::endl;\r
+        for( unsigned j=0; j<qorder.size(); j++ ){\r
+          Node q = qorder[j];\r
+          QuantInfo * qi = &d_qinfo[q];\r
+\r
+          Assert( d_qinfo.find( q )!=d_qinfo.end() );\r
+          if( qi->d_mg->isValid() ){\r
+            Trace("qcf-check") << "Check quantified formula ";\r
+            debugPrintQuant("qcf-check", q);\r
+            Trace("qcf-check") << " : " << q << "..." << std::endl;\r
+\r
+            Trace("qcf-check-debug") << "Reset round..." << std::endl;\r
+            qi->reset_round( this );\r
+            //try to make a matches making the body false\r
+            Trace("qcf-check-debug") << "Get next match..." << std::endl;\r
+            while( qi->d_mg->getNextMatch( this, qi ) ){\r
+              Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;\r
+              qi->debugPrintMatch("qcf-check");\r
+              Trace("qcf-check") << std::endl;\r
+              std::vector< int > assigned;\r
+              if( !qi->isMatchSpurious( this ) ){\r
+                if( qi->completeMatch( this, assigned ) ){\r
+                  std::vector< Node > terms;\r
+                  qi->getMatch( terms );\r
+                  if( !qi->isTConstraintSpurious( this, terms ) ){\r
+                    if( Debug.isOn("qcf-check-inst") ){\r
+                      //if( e==effort_conflict ){\r
+                      Node inst = d_quantEngine->getInstantiation( q, terms );\r
+                      Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;\r
+                      Assert( evaluate( inst )!=1 );\r
+                      Assert( evaluate( inst )==-1 || e>effort_conflict );\r
+                      //}\r
+                    }\r
+                    if( d_quantEngine->addInstantiation( q, terms, false ) ){\r
+                      Trace("qcf-check") << "   ... Added instantiation" << std::endl;\r
+                      Trace("qcf-inst") << "*** Was from effort " << e << " : " << std::endl;\r
+                      qi->debugPrintMatch("qcf-inst");\r
+                      Trace("qcf-inst") << std::endl;\r
+                      ++addedLemmas;\r
+                      if( e==effort_conflict ){\r
+                        d_quant_order.insert( d_quant_order.begin(), q );\r
+                        d_conflict.set( true );\r
+                        ++(d_statistics.d_conflict_inst);\r
+                        break;\r
+                      }else if( e==effort_prop_eq ){\r
+                        ++(d_statistics.d_prop_inst);\r
+                      }\r
+                    }else{\r
+                      Trace("qcf-check") << "   ... Failed to add instantiation" << std::endl;\r
+                      //Assert( false );\r
+                    }\r
+                  }\r
+                  //clean up assigned\r
+                  qi->revertMatch( assigned );\r
+                  d_tempCache.clear();\r
+                }else{\r
+                  Trace("qcf-check") << "   ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
+                }\r
+              }else{\r
+                Trace("qcf-check") << "   ... Spurious instantiation (match is inconsistent)" << std::endl;\r
+              }\r
+            }\r
+            if( d_conflict ){\r
+              break;\r
+            }\r
+          }\r
+        }\r
+        if( addedLemmas>0 ){\r
+          d_quantEngine->flushLemmas();\r
+          break;\r
+        }\r
+      }\r
+      if( Trace.isOn("qcf-engine") ){\r
+        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);\r
+        Trace("qcf-engine") << "Finished conflict find engine, time = " << (clSet2-clSet);\r
+        if( addedLemmas>0 ){\r
+          Trace("qcf-engine") << ", effort = " << ( d_effort==effort_conflict ? "conflict" : ( d_effort==effort_prop_eq ? "prop_eq" : "mc" ) );\r
+          Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;\r
+        }\r
+        Trace("qcf-engine") << std::endl;\r
+        int currEt = d_statistics.d_entailment_checks.getData();\r
+        if( currEt!=prevEt ){\r
+          Trace("qcf-engine") << "  Entailment checks = " << ( currEt - prevEt ) << std::endl;\r
+        }\r
+      }\r
+    }\r
+    Trace("qcf-check2") << "QCF : finished check : " << level << std::endl;\r
+  }\r
+}\r
+\r
+bool QuantConflictFind::needsCheck( Theory::Effort level ) {\r
+  d_performCheck = false;\r
+  if( options::quantConflictFind() && !d_conflict ){\r
+    if( level==Theory::EFFORT_LAST_CALL ){\r
+      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_LAST_CALL;\r
+    }else if( level==Theory::EFFORT_FULL ){\r
+      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_DEFAULT;\r
+    }else if( level==Theory::EFFORT_STANDARD ){\r
+      d_performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_STD;\r
+    }\r
+  }\r
+  return d_performCheck;\r
+}\r
+\r
+void QuantConflictFind::computeRelevantEqr() {\r
+  if( d_needs_computeRelEqr ){\r
+    d_needs_computeRelEqr = false;\r
+    Trace("qcf-check") << "Compute relevant equalities..." << std::endl;\r
+    //d_uf_terms.clear();\r
+    //d_eqc_uf_terms.clear();\r
+    d_eqcs.clear();\r
+    d_model_basis.clear();\r
+    //d_arg_reps.clear();\r
+    //double clSet = 0;\r
+    //if( Trace.isOn("qcf-opt") ){\r
+    //  clSet = double(clock())/double(CLOCKS_PER_SEC);\r
+    //}\r
+\r
+    //long nTermst = 0;\r
+    //long nTerms = 0;\r
+    //long nEqc = 0;\r
+\r
+    //which nodes are irrelevant for disequality matches\r
+    std::map< TNode, bool > irrelevant_dnode;\r
+    //now, store matches\r
+    eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );\r
+    while( !eqcs_i.isFinished() ){\r
+      //nEqc++;\r
+      Node r = (*eqcs_i);\r
+      TypeNode rtn = r.getType();\r
+      if( options::qcfMode()==QCF_MC ){\r
+        std::map< TypeNode, std::vector< TNode > >::iterator itt = d_eqcs.find( rtn );\r
+        if( itt==d_eqcs.end() ){\r
+          Node mb = getQuantifiersEngine()->getTermDatabase()->getModelBasisTerm( rtn );\r
+          if( !getEqualityEngine()->hasTerm( mb ) ){\r
+            Trace("qcf-warn") << "WARNING: Model basis term does not exist!" << std::endl;\r
+            Assert( false );\r
+          }\r
+          Node mbr = getRepresentative( mb );\r
+          if( mbr!=r ){\r
+            d_eqcs[rtn].push_back( mbr );\r
+          }\r
+          d_eqcs[rtn].push_back( r );\r
+          d_model_basis[rtn] = mb;\r
+        }else{\r
+          itt->second.push_back( r );\r
+        }\r
+      }else{\r
+        d_eqcs[rtn].push_back( r );\r
+      }\r
+      ++eqcs_i;\r
+    }\r
+    /*\r
+    if( Trace.isOn("qcf-opt") ){\r
+      double clSet2 = double(clock())/double(CLOCKS_PER_SEC);\r
+      Trace("qcf-opt") << "Compute rel eqc : " << std::endl;\r
+      Trace("qcf-opt") << "   " << nEqc << " equivalence classes. " << std::endl;\r
+      Trace("qcf-opt") << "   " << nTerms << " / " << nTermst << " terms." << std::endl;\r
+      Trace("qcf-opt") << "   Time : " << (clSet2-clSet) << std::endl;\r
+    }\r
+    */\r
+  }\r
+}\r
+\r
+\r
+//-------------------------------------------------- debugging\r
+\r
+\r
+void QuantConflictFind::debugPrint( const char * c ) {\r
+  //print the equivalance classes\r
+  Trace(c) << "----------EQ classes" << std::endl;\r
+  eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );\r
+  while( !eqcs_i.isFinished() ){\r
+    Node n = (*eqcs_i);\r
+    //if( !n.getType().isInteger() ){\r
+    Trace(c) << "  - " << n << " : {";\r
+    eq::EqClassIterator eqc_i = eq::EqClassIterator( n, getEqualityEngine() );\r
+    bool pr = false;\r
+    while( !eqc_i.isFinished() ){\r
+      Node nn = (*eqc_i);\r
+      if( nn.getKind()!=EQUAL && nn!=n ){\r
+        Trace(c) << (pr ? "," : "" ) << " " << nn;\r
+        pr = true;\r
+      }\r
+      ++eqc_i;\r
+    }\r
+    Trace(c) << (pr ? " " : "" ) << "}" << std::endl;\r
+    /*\r
+    EqcInfo * eqcn = getEqcInfo( n, false );\r
+    if( eqcn ){\r
+      Trace(c) << "    DEQ : {";\r
+      pr = false;\r
+      for( NodeBoolMap::iterator it = eqcn->d_diseq.begin(); it != eqcn->d_diseq.end(); ++it ){\r
+        if( (*it).second ){\r
+          Trace(c) << (pr ? "," : "" ) << " " << (*it).first;\r
+          pr = true;\r
+        }\r
+      }\r
+      Trace(c) << (pr ? " " : "" ) << "}" << std::endl;\r
+    }\r
+    //}\r
+    */\r
+    ++eqcs_i;\r
+  }\r
+}\r
+\r
+void QuantConflictFind::debugPrintQuant( const char * c, Node q ) {\r
+  Trace(c) << "Q" << d_quant_id[q];\r
+}\r
+\r
+void QuantConflictFind::debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum ) {\r
+  if( n.getNumChildren()==0 ){\r
+    Trace(c) << n;\r
+  }else if( doVarNum && d_qinfo[q].d_var_num.find( n )!=d_qinfo[q].d_var_num.end() ){\r
+    Trace(c) << "?x" << d_qinfo[q].d_var_num[n];\r
+  }else{\r
+    Trace(c) << "(";\r
+    if( n.getKind()==APPLY_UF ){\r
+      Trace(c) << n.getOperator();\r
+    }else{\r
+      Trace(c) << n.getKind();\r
+    }\r
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+      Trace(c) << " ";\r
+      debugPrintQuantBody( c, q, n[i] );\r
+    }\r
+    Trace(c) << ")";\r
+  }\r
+}\r
+\r
+QuantConflictFind::Statistics::Statistics():\r
+  d_inst_rounds("QuantConflictFind::Inst_Rounds", 0),\r
+  d_conflict_inst("QuantConflictFind::Instantiations_Conflict_Find", 0 ),\r
+  d_prop_inst("QuantConflictFind::Instantiations_Prop", 0 ),\r
+  d_entailment_checks("QuantConflictFind::Entailment_Checks",0)\r
+{\r
+  StatisticsRegistry::registerStat(&d_inst_rounds);\r
+  StatisticsRegistry::registerStat(&d_conflict_inst);\r
+  StatisticsRegistry::registerStat(&d_prop_inst);\r
+  StatisticsRegistry::registerStat(&d_entailment_checks);\r
+}\r
+\r
+QuantConflictFind::Statistics::~Statistics(){\r
+  StatisticsRegistry::unregisterStat(&d_inst_rounds);\r
+  StatisticsRegistry::unregisterStat(&d_conflict_inst);\r
+  StatisticsRegistry::unregisterStat(&d_prop_inst);\r
+  StatisticsRegistry::unregisterStat(&d_entailment_checks);\r
+}\r
+\r
+TNode QuantConflictFind::getZero( Kind k ) {\r
+  std::map< Kind, Node >::iterator it = d_zero.find( k );\r
+  if( it==d_zero.end() ){\r
+    Node nn;\r
+    if( k==PLUS ){\r
+      nn = NodeManager::currentNM()->mkConst( Rational(0) );\r
+    }\r
+    d_zero[k] = nn;\r
+    return nn;\r
+  }else{\r
+    return it->second;\r
+  }\r
+}\r
+\r
+\r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
index 0464c04..1f3635e
-/*********************                                                        */
-/*! \file quant_conflict_find.h
- ** \verbatim
- ** Original author: Andrew Reynolds
- ** Major contributors: Morgan Deters
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2014  New York University and The University of Iowa
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief quantifiers conflict find class
- **/
-
-#include "cvc4_private.h"
-
-#ifndef QUANT_CONFLICT_FIND
-#define QUANT_CONFLICT_FIND
-
-#include "context/cdhashmap.h"
-#include "context/cdchunk_list.h"
-#include "theory/quantifiers_engine.h"
-
-namespace CVC4 {
-namespace theory {
-namespace quantifiers {
-
-class QcfNode;
-
-class QuantConflictFind;
-
-class QcfNodeIndex {
-public:
-  std::map< TNode, QcfNodeIndex > d_children;
-  void clear() { d_children.clear(); }
-  void debugPrint( const char * c, int t );
-  Node existsTerm( TNode n, std::vector< TNode >& reps, int index = 0 );
-  Node addTerm( TNode n, std::vector< TNode >& reps, int index = 0 );
-};
-
-class QuantInfo;
-
-//match generator
-class MatchGen {
-  friend class QuantInfo;
-private:
-  //current children information
-  int d_child_counter;
-  //children of this object
-  std::vector< int > d_children_order;
-  unsigned getNumChildren() { return d_children.size(); }
-  MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; }
-  //MatchGen * getChild( int i ) { return &d_children[i]; }
-  //current matching information
-  std::vector< QcfNodeIndex * > d_qn;
-  std::vector< std::map< TNode, QcfNodeIndex >::iterator > d_qni;
-  bool doMatching( QuantConflictFind * p, QuantInfo * qi );
-  //for matching : each index is either a variable or a ground term
-  unsigned d_qni_size;
-  std::map< int, int > d_qni_var_num;
-  std::map< int, TNode > d_qni_gterm;
-  std::map< int, TNode > d_qni_gterm_rep;
-  std::map< int, int > d_qni_bound;
-  std::vector< int > d_qni_bound_except;
-  std::map< int, TNode > d_qni_bound_cons;
-  std::map< int, int > d_qni_bound_cons_var;
-  std::map< int, int >::iterator d_binding_it;
-  //std::vector< int > d_independent;
-  bool d_matched_basis;
-  bool d_binding;
-  //int getVarBindingVar();
-  std::map< int, Node > d_ground_eval;
-  //determine variable order
-  void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars );
-  void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars );
-public:
-  //type of the match generator
-  enum {
-    typ_invalid,
-    typ_ground,
-    typ_pred,
-    typ_eq,
-    typ_formula,
-    typ_var,
-    typ_ite_var,
-    typ_bool_var,
-    typ_tconstraint,
-    typ_tsym,
-  };
-  void debugPrintType( const char * c, short typ, bool isTrace = false );
-public:
-  MatchGen() : d_type( typ_invalid ){}
-  MatchGen( QuantInfo * qi, Node n, bool isVar = false );
-  bool d_tgt;
-  bool d_tgt_orig;
-  bool d_wasSet;
-  Node d_n;
-  std::vector< MatchGen > d_children;
-  short d_type;
-  bool d_type_not;
-  void reset_round( QuantConflictFind * p );
-  void reset( QuantConflictFind * p, bool tgt, QuantInfo * qi );
-  bool getNextMatch( QuantConflictFind * p, QuantInfo * qi );
-  bool getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp );
-  Node getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp );
-  bool isValid() { return d_type!=typ_invalid; }
-  void setInvalid();
-
-  // is this term treated as UF application?
-  static bool isHandledBoolConnective( TNode n );
-  static bool isHandledUfTerm( TNode n );
-  static Node getOperator( QuantConflictFind * p, Node n );
-  //can this node be handled by the algorithm
-  static bool isHandled( TNode n );
-};
-
-//info for quantifiers
-class QuantInfo {
-private:
-  void registerNode( Node n, bool hasPol, bool pol, bool beneathQuant = false );
-  void flatten( Node n, bool beneathQuant );
-private: //for completing match
-  std::vector< int > d_unassigned;
-  std::vector< TypeNode > d_unassigned_tn;
-  int d_unassigned_nvar;
-  int d_una_index;
-  std::vector< int > d_una_eqc_count;
-public:
-  QuantInfo() : d_mg( NULL ) {}
-  ~QuantInfo() { delete d_mg; }
-  std::vector< TNode > d_vars;
-  std::map< TNode, int > d_var_num;
-  std::vector< int > d_tsym_vars;
-  std::map< TNode, bool > d_inMatchConstraint;
-  std::map< int, std::vector< Node > > d_var_constraint[2];
-  int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }
-  bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }
-  int getNumVars() { return (int)d_vars.size(); }
-  TNode getVar( int i ) { return d_vars[i]; }
-
-  MatchGen * d_mg;
-  Node d_q;
-  std::map< int, MatchGen * > d_var_mg;
-  void reset_round( QuantConflictFind * p );
-public:
-  //initialize
-  void initialize( Node q, Node qn );
-  //current constraints
-  std::vector< TNode > d_match;
-  std::vector< TNode > d_match_term;
-  std::map< int, std::map< TNode, int > > d_curr_var_deq;
-  std::map< Node, bool > d_tconstraints;
-  int getCurrentRepVar( int v );
-  TNode getCurrentValue( TNode n );
-  TNode getCurrentExpValue( TNode n );
-  bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );
-  int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );
-  int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );
-  bool setMatch( QuantConflictFind * p, int v, TNode n );
-  bool isMatchSpurious( QuantConflictFind * p );
-  bool isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms );
-  bool entailmentTest( QuantConflictFind * p, Node lit, bool chEnt = true );
-  bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );
-  void revertMatch( std::vector< int >& assigned );
-  void debugPrintMatch( const char * c );
-  bool isConstrainedVar( int v );
-public:
-  void getMatch( std::vector< Node >& terms );
-};
-
-class QuantConflictFind : public QuantifiersModule
-{
-  friend class QcfNodeIndex;
-  friend class MatchGen;
-  friend class QuantInfo;
-  typedef context::CDChunkList<Node> NodeList;
-  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;
-private:
-  context::Context* d_c;
-  context::CDO< bool > d_conflict;
-  bool d_performCheck;
-  std::vector< Node > d_quant_order;
-  std::map< Kind, Node > d_zero;
-  //for storing nodes created during t-constraint solving (prevents memory leaks)
-  std::vector< Node > d_tempCache;
-private:
-  std::map< Node, Node > d_op_node;
-  int d_fid_count;
-  std::map< Node, int > d_fid;
-  Node mkEqNode( Node a, Node b );
-public:  //for ground terms
-  Node d_true;
-  Node d_false;
-  TNode getZero( Kind k );
-private:
-  Node evaluateTerm( Node n );
-  int evaluate( Node n, bool pref = false, bool hasPref = false );
-private:
-  //currently asserted quantifiers
-  NodeList d_qassert;
-  std::map< Node, QuantInfo > d_qinfo;
-private:  //for equivalence classes
-  eq::EqualityEngine * getEqualityEngine();
-  bool areDisequal( Node n1, Node n2 );
-  bool areEqual( Node n1, Node n2 );
-  Node getRepresentative( Node n );
-
-/*
-  class EqcInfo {
-  public:
-    EqcInfo( context::Context* c ) : d_diseq( c ) {}
-    NodeBoolMap d_diseq;
-    bool isDisequal( Node n ) { return d_diseq.find( n )!=d_diseq.end() && d_diseq[n]; }
-    void setDisequal( Node n, bool val = true ) { d_diseq[n] = val; }
-    //NodeBoolMap& getRelEqr( int index ) { return index==0 ? d_rel_eqr_e : d_rel_eqr_d; }
-  };
-  std::map< Node, EqcInfo * > d_eqc_info;
-  EqcInfo * getEqcInfo( Node n, bool doCreate = true );
-*/
-  // operator -> index(terms)
-  std::map< TNode, QcfNodeIndex > d_uf_terms;
-  // operator -> index(eqc -> terms)
-  std::map< TNode, QcfNodeIndex > d_eqc_uf_terms;
-  //get qcf node index
-  QcfNodeIndex * getQcfNodeIndex( Node eqc, Node f );
-  QcfNodeIndex * getQcfNodeIndex( Node f );
-  // type -> list(eqc)
-  std::map< TypeNode, std::vector< TNode > > d_eqcs;
-  std::map< TypeNode, Node > d_model_basis;
-  //mapping from UF terms to representatives of their arguments
-  std::map< TNode, std::vector< TNode > > d_arg_reps;
-  //compute arg reps
-  void computeArgReps( TNode n );
-  //compute
-  void computeUfTerms( TNode f );
-public:
-  enum {
-    effort_conflict,
-    effort_prop_eq,
-    effort_mc,
-  };
-  short d_effort;
-  void setEffort( int e ) { d_effort = e; }
-  static short getMaxQcfEffort();
-  bool areMatchEqual( TNode n1, TNode n2 );
-  bool areMatchDisequal( TNode n1, TNode n2 );
-public:
-  QuantConflictFind( QuantifiersEngine * qe, context::Context* c );
-  /** register quantifier */
-  void registerQuantifier( Node q );
-public:
-  /** assert quantifier */
-  void assertNode( Node q );
-  /** new node */
-  void newEqClass( Node n );
-  /** merge */
-  void merge( Node a, Node b );
-  /** assert disequal */
-  void assertDisequal( Node a, Node b );
-  /** reset round */
-  void reset_round( Theory::Effort level );
-  /** check */
-  void check( Theory::Effort level );
-  /** needs check */
-  bool needsCheck( Theory::Effort level );
-private:
-  bool d_needs_computeRelEqr;
-public:
-  void computeRelevantEqr();
-private:
-  void debugPrint( const char * c );
-  //for debugging
-  std::vector< Node > d_quants;
-  std::map< Node, int > d_quant_id;
-  void debugPrintQuant( const char * c, Node q );
-  void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );
-public:
-  /** statistics class */
-  class Statistics {
-  public:
-    IntStat d_inst_rounds;
-    IntStat d_conflict_inst;
-    IntStat d_prop_inst;
-    IntStat d_entailment_checks;
-    Statistics();
-    ~Statistics();
-  };
-  Statistics d_statistics;
-  /** Identify this module */
-  std::string identify() const { return "QcfEngine"; }
-};
-
-}
-}
-}
-
-#endif
+/*********************                                                        */\r
+/*! \file quant_conflict_find.h\r
+ ** \verbatim\r
+ ** Original author: Andrew Reynolds\r
+ ** Major contributors: none\r
+ ** Minor contributors (to current version): none\r
+ ** This file is part of the CVC4 project.\r
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
+ ** See the file COPYING in the top-level source directory for licensing\r
+ ** information.\endverbatim\r
+ **\r
+ ** \brief quantifiers conflict find class\r
+ **/\r
+\r
+#include "cvc4_private.h"\r
+\r
+#ifndef QUANT_CONFLICT_FIND\r
+#define QUANT_CONFLICT_FIND\r
+\r
+#include "context/cdhashmap.h"\r
+#include "context/cdchunk_list.h"\r
+#include "theory/quantifiers_engine.h"\r
+#include "theory/quantifiers/term_database.h"\r
+\r
+namespace CVC4 {\r
+namespace theory {\r
+namespace quantifiers {\r
+\r
+class QuantConflictFind;\r
+class QuantInfo;\r
+\r
+//match generator\r
+class MatchGen {\r
+  friend class QuantInfo;\r
+private:\r
+  //current children information\r
+  int d_child_counter;\r
+  //children of this object\r
+  std::vector< int > d_children_order;\r
+  unsigned getNumChildren() { return d_children.size(); }\r
+  MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; }\r
+  //MatchGen * getChild( int i ) { return &d_children[i]; }\r
+  //current matching information\r
+  std::vector< TermArgTrie * > d_qn;\r
+  std::vector< std::map< TNode, TermArgTrie >::iterator > d_qni;\r
+  bool doMatching( QuantConflictFind * p, QuantInfo * qi );\r
+  //for matching : each index is either a variable or a ground term\r
+  unsigned d_qni_size;\r
+  std::map< int, int > d_qni_var_num;\r
+  std::map< int, TNode > d_qni_gterm;\r
+  std::map< int, TNode > d_qni_gterm_rep;\r
+  std::map< int, int > d_qni_bound;\r
+  std::vector< int > d_qni_bound_except;\r
+  std::map< int, TNode > d_qni_bound_cons;\r
+  std::map< int, int > d_qni_bound_cons_var;\r
+  std::map< int, int >::iterator d_binding_it;\r
+  //std::vector< int > d_independent;\r
+  bool d_matched_basis;\r
+  bool d_binding;\r
+  //int getVarBindingVar();\r
+  std::map< int, Node > d_ground_eval;\r
+  //determine variable order\r
+  void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars );\r
+  void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars );\r
+public:\r
+  //type of the match generator\r
+  enum {\r
+    typ_invalid,\r
+    typ_ground,\r
+    typ_pred,\r
+    typ_eq,\r
+    typ_formula,\r
+    typ_var,\r
+    typ_ite_var,\r
+    typ_bool_var,\r
+    typ_tconstraint,\r
+    typ_tsym,\r
+  };\r
+  void debugPrintType( const char * c, short typ, bool isTrace = false );\r
+public:\r
+  MatchGen() : d_type( typ_invalid ){}\r
+  MatchGen( QuantInfo * qi, Node n, bool isVar = false );\r
+  bool d_tgt;\r
+  bool d_tgt_orig;\r
+  bool d_wasSet;\r
+  Node d_n;\r
+  std::vector< MatchGen > d_children;\r
+  short d_type;\r
+  bool d_type_not;\r
+  void reset_round( QuantConflictFind * p );\r
+  void reset( QuantConflictFind * p, bool tgt, QuantInfo * qi );\r
+  bool getNextMatch( QuantConflictFind * p, QuantInfo * qi );\r
+  bool getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp );\r
+  Node getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp );\r
+  bool isValid() { return d_type!=typ_invalid; }\r
+  void setInvalid();\r
+\r
+  // is this term treated as UF application?\r
+  static bool isHandledBoolConnective( TNode n );\r
+  static bool isHandledUfTerm( TNode n );\r
+  static Node getOperator( QuantConflictFind * p, Node n );\r
+  //can this node be handled by the algorithm\r
+  static bool isHandled( TNode n );\r
+};\r
+\r
+//info for quantifiers\r
+class QuantInfo {\r
+private:\r
+  void registerNode( Node n, bool hasPol, bool pol, bool beneathQuant = false );\r
+  void flatten( Node n, bool beneathQuant );\r
+private: //for completing match\r
+  std::vector< int > d_unassigned;\r
+  std::vector< TypeNode > d_unassigned_tn;\r
+  int d_unassigned_nvar;\r
+  int d_una_index;\r
+  std::vector< int > d_una_eqc_count;\r
+public:\r
+  QuantInfo() : d_mg( NULL ) {}\r
+  ~QuantInfo() { delete d_mg; }\r
+  std::vector< TNode > d_vars;\r
+  std::map< TNode, int > d_var_num;\r
+  std::vector< int > d_tsym_vars;\r
+  std::map< TNode, bool > d_inMatchConstraint;\r
+  std::map< int, std::vector< Node > > d_var_constraint[2];\r
+  int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }\r
+  bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }\r
+  int getNumVars() { return (int)d_vars.size(); }\r
+  TNode getVar( int i ) { return d_vars[i]; }\r
+\r
+  MatchGen * d_mg;\r
+  Node d_q;\r
+  std::map< int, MatchGen * > d_var_mg;\r
+  void reset_round( QuantConflictFind * p );\r
+public:\r
+  //initialize\r
+  void initialize( Node q, Node qn );\r
+  //current constraints\r
+  std::vector< TNode > d_match;\r
+  std::vector< TNode > d_match_term;\r
+  std::map< int, std::map< TNode, int > > d_curr_var_deq;\r
+  std::map< Node, bool > d_tconstraints;\r
+  int getCurrentRepVar( int v );\r
+  TNode getCurrentValue( TNode n );\r
+  TNode getCurrentExpValue( TNode n );\r
+  bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );\r
+  int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );\r
+  int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );\r
+  bool setMatch( QuantConflictFind * p, int v, TNode n );\r
+  bool isMatchSpurious( QuantConflictFind * p );\r
+  bool isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms );\r
+  bool entailmentTest( QuantConflictFind * p, Node lit, bool chEnt = true );\r
+  bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );\r
+  void revertMatch( std::vector< int >& assigned );\r
+  void debugPrintMatch( const char * c );\r
+  bool isConstrainedVar( int v );\r
+public:\r
+  void getMatch( std::vector< Node >& terms );\r
+};\r
+\r
+class QuantConflictFind : public QuantifiersModule\r
+{\r
+  friend class MatchGen;\r
+  friend class QuantInfo;\r
+  typedef context::CDChunkList<Node> NodeList;\r
+  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;\r
+private:\r
+  context::Context* d_c;\r
+  context::CDO< bool > d_conflict;\r
+  bool d_performCheck;\r
+  std::vector< Node > d_quant_order;\r
+  std::map< Kind, Node > d_zero;\r
+  //for storing nodes created during t-constraint solving (prevents memory leaks)\r
+  std::vector< Node > d_tempCache;\r
+private:\r
+  std::map< Node, Node > d_op_node;\r
+  int d_fid_count;\r
+  std::map< Node, int > d_fid;\r
+  Node mkEqNode( Node a, Node b );\r
+public:  //for ground terms\r
+  Node d_true;\r
+  Node d_false;\r
+  TNode getZero( Kind k );\r
+private:\r
+  Node evaluateTerm( Node n );\r
+  int evaluate( Node n, bool pref = false, bool hasPref = false );\r
+private:\r
+  //currently asserted quantifiers\r
+  NodeList d_qassert;\r
+  std::map< Node, QuantInfo > d_qinfo;\r
+private:  //for equivalence classes\r
+  eq::EqualityEngine * getEqualityEngine();\r
+  bool areDisequal( Node n1, Node n2 );\r
+  bool areEqual( Node n1, Node n2 );\r
+  Node getRepresentative( Node n );\r
+  TermDb* getTermDatabase();\r
+  // type -> list(eqc)\r
+  std::map< TypeNode, std::vector< TNode > > d_eqcs;\r
+  std::map< TypeNode, Node > d_model_basis;\r
+public:\r
+  enum {\r
+    effort_conflict,\r
+    effort_prop_eq,\r
+    effort_mc,\r
+  };\r
+  short d_effort;\r
+  void setEffort( int e ) { d_effort = e; }\r
+  static short getMaxQcfEffort();\r
+  bool areMatchEqual( TNode n1, TNode n2 );\r
+  bool areMatchDisequal( TNode n1, TNode n2 );\r
+public:\r
+  QuantConflictFind( QuantifiersEngine * qe, context::Context* c );\r
+  /** register quantifier */\r
+  void registerQuantifier( Node q );\r
+public:\r
+  /** assert quantifier */\r
+  void assertNode( Node q );\r
+  /** new node */\r
+  void newEqClass( Node n );\r
+  /** merge */\r
+  void merge( Node a, Node b );\r
+  /** assert disequal */\r
+  void assertDisequal( Node a, Node b );\r
+  /** reset round */\r
+  void reset_round( Theory::Effort level );\r
+  /** check */\r
+  void check( Theory::Effort level );\r
+  /** needs check */\r
+  bool needsCheck( Theory::Effort level );\r
+private:\r
+  bool d_needs_computeRelEqr;\r
+public:\r
+  void computeRelevantEqr();\r
+private:\r
+  void debugPrint( const char * c );\r
+  //for debugging\r
+  std::vector< Node > d_quants;\r
+  std::map< Node, int > d_quant_id;\r
+  void debugPrintQuant( const char * c, Node q );\r
+  void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );\r
+public:\r
+  /** statistics class */\r
+  class Statistics {\r
+  public:\r
+    IntStat d_inst_rounds;\r
+    IntStat d_conflict_inst;\r
+    IntStat d_prop_inst;\r
+    IntStat d_entailment_checks;\r
+    Statistics();\r
+    ~Statistics();\r
+  };\r
+  Statistics d_statistics;\r
+  /** Identify this module */\r
+  std::string identify() const { return "QcfEngine"; }\r
+};\r
+\r
+}\r
+}\r
+}\r
+\r
+#endif\r
index eb14b0abee7b2b9b310b28b7b8ff515a9c496c99..4c01e927df386a03f171d232947c844fdc9bb6a3 100644 (file)
@@ -1142,8 +1142,10 @@ Node QuantifiersRewriter::preSkolemizeQuantifiers( Node n, bool polarity, std::v
       //process body
       Node nn = preSkolemizeQuantifiers( n[1], polarity, fvTypes, fvs );
       std::vector< Node > sk;
+      Node sub;
+      std::vector< unsigned > sub_vars;
       //return skolemized body
-      return TermDb::mkSkolemizedBody( n, nn, fvTypes, fvs, sk );
+      return TermDb::mkSkolemizedBody( n, nn, fvTypes, fvs, sk, sub, sub_vars );
     }
   }else{
     //check if it contains a quantifier as a subterm
index 9ea9ee9626f104d501b453323497e20fe2afa3d1..0d5103db6b680d56b1cd883fff94e2e4600851ff 100644 (file)
@@ -31,25 +31,39 @@ using namespace CVC4::theory::quantifiers;
 
 using namespace CVC4::theory::inst;
 
-bool TermArgTrie::addTerm2( QuantifiersEngine* qe, Node n, int argIndex ){
-  if( argIndex<(int)n.getNumChildren() ){
-    Node r = qe->getEqualityQuery()->getRepresentative( n[ argIndex ] );
-    std::map< Node, TermArgTrie >::iterator it = d_data.find( r );
+TNode TermArgTrie::existsTerm( std::vector< TNode >& reps, int argIndex ) {
+  if( argIndex==(int)reps.size() ){
+    if( d_data.empty() ){
+      return Node::null();
+    }else{
+      return d_data.begin()->first;
+    }
+  }else{
+    std::map< TNode, TermArgTrie >::iterator it = d_data.find( reps[argIndex] );
     if( it==d_data.end() ){
-      d_data[r].addTerm2( qe, n, argIndex+1 );
+      return Node::null();
+    }else{
+      return it->second.existsTerm( reps, argIndex+1 );
+    }
+  }
+}
+
+bool TermArgTrie::addTerm( TNode n, std::vector< TNode >& reps, int argIndex ){
+  if( argIndex==(int)reps.size() ){
+    if( d_data.empty() ){
+      //store n in d_data (this should be interpretted as the "data" and not as a reference to a child)
+      d_data[n].clear();
       return true;
     }else{
-      return it->second.addTerm2( qe, n, argIndex+1 );
+      return false;
     }
   }else{
-    //store n in d_data (this should be interpretted as the "data" and not as a reference to a child)
-    d_data[n].d_data.clear();
-    return false;
+    return d_data[reps[argIndex]].addTerm( n, reps, argIndex+1 );
   }
 }
 
 void TermArgTrie::debugPrint( const char * c, Node n, unsigned depth ) {
-  for( std::map< Node, TermArgTrie >::iterator it = d_data.begin(); it != d_data.end(); ++it ){
+  for( std::map< TNode, TermArgTrie >::iterator it = d_data.begin(); it != d_data.end(); ++it ){
     for( unsigned i=0; i<depth; i++ ){ Debug(c) << "  "; }
     Debug(c) << it->first << std::endl;
     it->second.debugPrint( c, n, depth+1 );
@@ -57,7 +71,8 @@ void TermArgTrie::debugPrint( const char * c, Node n, unsigned depth ) {
 }
 
 TermDb::TermDb( context::Context* c, context::UserContext* u, QuantifiersEngine* qe ) : d_quantEngine( qe ), d_op_ccount( u ) {
-
+  d_true = NodeManager::currentNM()->mkConst( true );
+  d_false = NodeManager::currentNM()->mkConst( false );
 }
 
 /** ground terms */
@@ -143,65 +158,162 @@ void TermDb::addTerm( Node n, std::set< Node >& added, bool withinQuant ){
   }
 }
 
- void TermDb::reset( Theory::Effort effort ){
+void TermDb::computeArgReps( TNode n ) {
+  if( d_arg_reps.find( n )==d_arg_reps.end() ){
+    eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+    for( unsigned j=0; j<n.getNumChildren(); j++ ){
+      TNode r = ee->hasTerm( n[j] ) ? ee->getRepresentative( n[j] ) : n[j];
+      d_arg_reps[n].push_back( r );
+    }
+  }
+}
+
+void TermDb::computeUfEqcTerms( TNode f ) {
+  if( d_func_map_eqc_trie.find( f )==d_func_map_eqc_trie.end() ){
+    d_func_map_eqc_trie[f].clear();
+    eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+    for( unsigned i=0; i<d_op_map[f].size(); i++ ){
+      TNode n = d_op_map[f][i];
+      if( !n.getAttribute(NoMatchAttribute()) ){
+        computeArgReps( n );
+        TNode r = ee->hasTerm( n ) ? ee->getRepresentative( n ) : n;
+        d_func_map_eqc_trie[f].d_data[r].addTerm( n, d_arg_reps[n] );
+      }
+    }
+  }
+}
+
+TNode TermDb::evaluateTerm( TNode n, std::map< TNode, TNode >& subs, bool subsRep ) {
+  Trace("term-db-eval") << "evaluate term : " << n << std::endl;
+  eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+  if( ee->hasTerm( n ) ){
+    Trace("term-db-eval") << "...exists in ee, return rep " << std::endl;
+    return ee->getRepresentative( n );
+  }else if( n.getKind()==BOUND_VARIABLE ){
+    Assert( subs.find( n )!=subs.end() );
+    Trace("term-db-eval") << "...substitution is : " << subs[n] << std::endl;
+    if( subsRep ){
+      Assert( ee->hasTerm( subs[n] ) );
+      Assert( ee->getRepresentative( subs[n] )==subs[n] );
+      return subs[n];
+    }else{
+      return evaluateTerm( subs[n], subs, subsRep );
+    }
+  }else{
+    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], subs, subsRep );
+          if( c.isNull() ){
+            return TNode::null();
+          }
+          Trace("term-db-eval") << "Got child : " << c << std::endl;
+          args.push_back( c );
+        }
+        Trace("term-db-eval") << "Get term from DB" << std::endl;
+        TNode nn = d_func_map_trie[f].existsTerm( args );
+        Trace("term-db-eval") << "Got term " << nn << std::endl;
+        if( !nn.isNull() ){
+          if( ee->hasTerm( nn ) ){
+            Trace("term-db-eval") << "return rep " << std::endl;
+            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() );
+  if( n.getKind()==EQUAL ){
+    TNode n1 = evaluateTerm( n[0], subs, subsRep );
+    if( !n1.isNull() ){
+      TNode n2 = evaluateTerm( n[1], subs, subsRep );
+      if( !n2.isNull() ){
+        eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+        Assert( ee->hasTerm( n1 ) );
+        Assert( ee->hasTerm( n2 ) );
+        if( pol ){
+          return ee->areEqual( n1, n2 );
+        }else{
+          return ee->areDisequal( n1, n2, false );
+        }
+      }
+    }
+  }else if( n.getKind()==APPLY_UF ){
+    TNode n1 = evaluateTerm( n, subs, subsRep );
+    if( !n1.isNull() ){
+      eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+      Assert( ee->hasTerm( n1 ) );
+      TNode n2 = pol ? d_true : d_false;
+      if( ee->hasTerm( n2 ) ){
+        return ee->areEqual( n1, n2 );
+      }
+    }
+  }else if( n.getKind()==NOT ){
+    return isEntailed( n[0], subs, subsRep, !pol );
+  }else if( n.getKind()==OR || n.getKind()==AND ){
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      if( isEntailed( n[i], subs, subsRep, pol ) ){
+        if( ( pol && n.getKind()==OR ) || ( !pol && n.getKind()==AND ) ){
+          return true;
+        }
+      }else{
+        if( ( !pol && n.getKind()==OR ) || ( pol && n.getKind()==AND ) ){
+          return false;
+        }
+      }
+    }
+    return true;
+  }else if( n.getKind()==IFF || n.getKind()==ITE ){
+    for( unsigned i=0; i<2; i++ ){
+      if( isEntailed( n[0], subs, subsRep, i==0 ) ){
+        unsigned ch = ( n.getKind()==IFF || i==0 ) ? 1 : 2;
+        bool reqPol = ( n.getKind()==ITE || i==0 ) ? pol : !pol;
+        return isEntailed( n[ch], subs, subsRep, reqPol );
+      }
+    }
+  }
+  return false;
+}
+
+void TermDb::reset( Theory::Effort effort ){
    int nonCongruentCount = 0;
    int congruentCount = 0;
    int alreadyCongruentCount = 0;
+   d_op_nonred_count.clear();
+   d_arg_reps.clear();
+   d_func_map_trie.clear();
+   d_func_map_eqc_trie.clear();
    //rebuild d_func/pred_map_trie for each operation, this will calculate all congruent terms
    for( std::map< Node, std::vector< Node > >::iterator it = d_op_map.begin(); it != d_op_map.end(); ++it ){
      d_op_nonred_count[ it->first ] = 0;
      if( !it->second.empty() ){
-       if( it->second[0].getType().isBoolean() ){
-         d_pred_map_trie[ 0 ][ it->first ].d_data.clear();
-         d_pred_map_trie[ 1 ][ it->first ].d_data.clear();
-       }else{
-         d_func_map_trie[ it->first ].d_data.clear();
-         for( int i=0; i<(int)it->second.size(); i++ ){
-           Node n = it->second[i];
-           computeModelBasisArgAttribute( n );
-           if( !n.getAttribute(NoMatchAttribute()) ){
-             if( !d_func_map_trie[ it->first ].addTerm( d_quantEngine, n ) ){
-               NoMatchAttribute nma;
-               n.setAttribute(nma,true);
-               Debug("term-db-cong") << n << " is redundant." << std::endl;
-               congruentCount++;
-             }else{
-               nonCongruentCount++;
-               d_op_nonred_count[ it->first ]++;
-             }
-           }else{
+       for( unsigned i=0; i<it->second.size(); i++ ){
+         Node n = it->second[i];
+         computeModelBasisArgAttribute( n );
+         if( !n.getAttribute(NoMatchAttribute()) ){
+           computeArgReps( n );
+           if( !d_func_map_trie[ it->first ].addTerm( n, d_arg_reps[n] ) ){
+             NoMatchAttribute nma;
+             n.setAttribute(nma,true);
+             Debug("term-db-cong") << n << " is redundant." << std::endl;
              congruentCount++;
-             alreadyCongruentCount++;
-           }
-         }
-       }
-     }
-   }
-   for( int i=0; i<2; i++ ){
-     Node n = NodeManager::currentNM()->mkConst( i==1 );
-     if( d_quantEngine->getEqualityQuery()->getEngine()->hasTerm( n ) ){
-       eq::EqClassIterator eqc( d_quantEngine->getEqualityQuery()->getEngine()->getRepresentative( n ),
-                                d_quantEngine->getEqualityQuery()->getEngine() );
-       while( !eqc.isFinished() ){
-         Node en = (*eqc);
-         computeModelBasisArgAttribute( en );
-         if( en.getKind()==APPLY_UF && !TermDb::hasInstConstAttr(en) ){
-           if( !en.getAttribute(NoMatchAttribute()) ){
-             Node op = getOperator( en );
-             if( !d_pred_map_trie[i][op].addTerm( d_quantEngine, en ) ){
-               NoMatchAttribute nma;
-               en.setAttribute(nma,true);
-               Debug("term-db-cong") << en << " is redundant." << std::endl;
-               congruentCount++;
-             }else{
-               nonCongruentCount++;
-               d_op_nonred_count[ op ]++;
-             }
            }else{
-             alreadyCongruentCount++;
+             nonCongruentCount++;
+             d_op_nonred_count[ it->first ]++;
            }
+         }else{
+           congruentCount++;
+           alreadyCongruentCount++;
          }
-         ++eqc;
        }
      }
    }
@@ -219,6 +331,39 @@ void TermDb::addTerm( Node n, std::set< Node >& added, bool withinQuant ){
    }
 }
 
+TermArgTrie * TermDb::getTermArgTrie( Node f ) {
+  std::map< Node, TermArgTrie >::iterator itut = d_func_map_trie.find( f );
+  if( itut!=d_func_map_trie.end() ){
+    return &itut->second;
+  }else{
+    return NULL;
+  }
+}
+
+TermArgTrie * TermDb::getTermArgTrie( Node eqc, Node f ) {
+  computeUfEqcTerms( f );
+  std::map< Node, TermArgTrie >::iterator itut = d_func_map_eqc_trie.find( f );
+  if( itut==d_func_map_eqc_trie.end() ){
+    return NULL;
+  }else{
+    if( eqc.isNull() ){
+      return &itut->second;
+    }else{
+      std::map< TNode, TermArgTrie >::iterator itute = itut->second.d_data.find( eqc );
+      if( itute!=itut->second.d_data.end() ){
+        return &itute->second;
+      }else{
+        return NULL;
+      }
+    }
+  }
+}
+
+TNode TermDb::existsTerm( Node f, Node n ) {
+  computeArgReps( n );
+  return d_func_map_trie[f].existsTerm( d_arg_reps[n] );
+}
+
 Node TermDb::getModelBasisTerm( TypeNode tn, int i ){
   if( d_model_basis_term.find( tn )==d_model_basis_term.end() ){
     Node mbt;
@@ -448,14 +593,14 @@ void getSelfSel( const DatatypeConstructor& dc, Node n, TypeNode ntn, std::vecto
 
 
 Node TermDb::mkSkolemizedBody( Node f, Node n, std::vector< TypeNode >& argTypes, std::vector< TNode >& fvs,
-                               std::vector< Node >& sk ) {
+                               std::vector< Node >& sk, Node& sub, std::vector< unsigned >& sub_vars ) {
   //calculate the variables and substitution
   std::vector< TNode > ind_vars;
   std::vector< unsigned > ind_var_indicies;
   std::vector< TNode > vars;
   std::vector< unsigned > var_indicies;
   for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
-    if( options::dtStcInduction() && datatypes::DatatypesRewriter::isTermDatatype( f[0][i] ) ){
+    if( isInductionTerm( f[0][i] ) ){
       ind_vars.push_back( f[0][i] );
       ind_var_indicies.push_back( i );
     }else{
@@ -494,19 +639,19 @@ Node TermDb::mkSkolemizedBody( Node f, Node n, std::vector< TypeNode >& argTypes
     Node nret;
     Node n_str_ind;
     TypeNode tn = ind_vars[0].getType();
-    if( datatypes::DatatypesRewriter::isTypeDatatype(tn) ){
+    if( options::dtStcInduction() && datatypes::DatatypesRewriter::isTypeDatatype(tn) ){
       Node k = sk[ind_var_indicies[0]];
       const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
       std::vector< Node > disj;
       for( unsigned i=0; i<dt.getNumConstructors(); i++ ){
-       std::vector< Node > selfSel;
-       getSelfSel( dt[i], k, tn, selfSel );
-       std::vector< Node > conj;
-       conj.push_back( NodeManager::currentNM()->mkNode( APPLY_TESTER, Node::fromExpr( dt[i].getTester() ), k ).negate() );
-       for( unsigned j=0; j<selfSel.size(); j++ ){
-         conj.push_back( ret.substitute( ind_vars[0], selfSel[j] ).negate() );
-       }
-       disj.push_back( conj.size()==1 ? conj[0] : NodeManager::currentNM()->mkNode( OR, conj ) );
+        std::vector< Node > selfSel;
+        getSelfSel( dt[i], k, tn, selfSel );
+        std::vector< Node > conj;
+        conj.push_back( NodeManager::currentNM()->mkNode( APPLY_TESTER, Node::fromExpr( dt[i].getTester() ), k ).negate() );
+        for( unsigned j=0; j<selfSel.size(); j++ ){
+          conj.push_back( ret.substitute( ind_vars[0], selfSel[j] ).negate() );
+        }
+        disj.push_back( conj.size()==1 ? conj[0] : NodeManager::currentNM()->mkNode( OR, conj ) );
       }
       Assert( !disj.empty() );
       n_str_ind = disj.size()==1 ? disj[0] : NodeManager::currentNM()->mkNode( AND, disj );
@@ -516,12 +661,15 @@ Node TermDb::mkSkolemizedBody( Node f, Node n, std::vector< TypeNode >& argTypes
       Trace("stc-ind") << "Unknown induction for term : " << ind_vars[0] << ", type = " << tn << std::endl;
       Assert( false );
     }
-    
+
     std::vector< Node > rem_ind_vars;
     rem_ind_vars.insert( rem_ind_vars.end(), ind_vars.begin()+1, ind_vars.end() );
     if( !rem_ind_vars.empty() ){
       Node bvl = NodeManager::currentNM()->mkNode( BOUND_VAR_LIST, rem_ind_vars );
       nret = NodeManager::currentNM()->mkNode( FORALL, bvl, nret );
+      nret = Rewriter::rewrite( nret );
+      sub = nret;
+      sub_vars.insert( sub_vars.end(), ind_var_indicies.begin()+1, ind_var_indicies.end() );
       n_str_ind = NodeManager::currentNM()->mkNode( FORALL, bvl, n_str_ind.negate() ).negate();
     }
     ret = NodeManager::currentNM()->mkNode( OR, nret, n_str_ind );
@@ -535,7 +683,15 @@ Node TermDb::getSkolemizedBody( Node f ){
   if( d_skolem_body.find( f )==d_skolem_body.end() ){
     std::vector< TypeNode > fvTypes;
     std::vector< TNode > fvs;
-    d_skolem_body[ f ] = mkSkolemizedBody( f, f[1], fvTypes, fvs, d_skolem_constants[f] );
+    Node sub;
+    std::vector< unsigned > sub_vars;
+    d_skolem_body[ f ] = mkSkolemizedBody( f, f[1], fvTypes, fvs, d_skolem_constants[f], sub, sub_vars );
+    //store sub quantifier information
+    if( !sub.isNull() ){
+      Assert( sub[0].getNumChildren()==sub_vars.size() );
+      d_skolem_sub_quant[f] = sub;
+      d_skolem_sub_quant_vars[f].insert( d_skolem_sub_quant_vars[f].end(), sub_vars.begin(), sub_vars.end() );
+    }
     Assert( d_skolem_constants[f].size()==f[0].getNumChildren() );
     if( options::sortInference() ){
       for( unsigned i=0; i<d_skolem_constants[f].size(); i++ ){
@@ -547,6 +703,25 @@ Node TermDb::getSkolemizedBody( Node f ){
   return d_skolem_body[ f ];
 }
 
+void TermDb::getSkolemConstants( Node f, std::vector< Node >& sk, bool expSub ) {
+  std::map< Node, std::vector< Node > >::iterator it = d_skolem_constants.find( f );
+  if( it!=d_skolem_constants.end() ){
+    sk.insert( sk.end(), it->second.begin(), it->second.end() );
+    if( expSub ){
+      std::map< Node, Node >::iterator its = d_skolem_sub_quant.find( f );
+      if( its!=d_skolem_sub_quant.end() && !its->second.isNull() ){
+        std::vector< Node > ssk;
+        getSkolemConstants( its->second, ssk, true );
+        Assert( ssk.size()==d_skolem_sub_quant_vars[f].size() );
+        for( unsigned i=0; i<d_skolem_sub_quant_vars[f].size(); i++ ){
+          sk[d_skolem_sub_quant_vars[f][i]] = ssk[i];
+        }
+      }
+    }
+    Assert( sk.size()==f[0].getNumChildren() );
+  }
+}
+
 Node TermDb::getFreeVariableForInstConstant( Node n ){
   TypeNode tn = n.getType();
   if( d_free_vars.find( tn )==d_free_vars.end() ){
@@ -752,6 +927,14 @@ void TermDb::registerTrigger( theory::inst::Trigger* tr, Node op ){
   }
 }
 
+bool TermDb::isInductionTerm( Node n ) {
+  if( options::dtStcInduction() && datatypes::DatatypesRewriter::isTermDatatype( n ) ){
+    return true;
+  }
+  return false;
+}
+
+
 bool TermDb::isRewriteRule( Node q ) {
   return !getRewriteRule( q ).isNull();
 }
index c839d08d72ff547266d7da7dd80e3380782b6af9..d63f61ca885628daa800e3655238f2f0ebbc1cb2 100644 (file)
@@ -69,14 +69,14 @@ namespace rrinst{
 namespace quantifiers {
 
 class TermArgTrie {
-private:
-  bool addTerm2( QuantifiersEngine* qe, Node n, int argIndex );
 public:
   /** the data */
-  std::map< Node, TermArgTrie > d_data;
+  std::map< TNode, TermArgTrie > d_data;
 public:
-  bool addTerm( QuantifiersEngine* qe, Node n ) { return addTerm2( qe, n, 0 ); }
+  TNode existsTerm( std::vector< TNode >& reps, int argIndex = 0 );
+  bool addTerm( TNode n, std::vector< TNode >& reps, int argIndex = 0 );
   void debugPrint( const char * c, Node n, unsigned depth = 0 );
+  void clear() { d_data.clear(); }
 };/* class TermArgTrie */
 
 
@@ -103,6 +103,9 @@ private:
 public:
   TermDb( context::Context* c, context::UserContext* u, QuantifiersEngine* qe );
   ~TermDb(){}
+  /** boolean terms */
+  Node d_true;
+  Node d_false;
   /** ground terms */
   unsigned getNumGroundTerms( Node f );
   /** count number of non-redundant ground terms per operator */
@@ -111,16 +114,32 @@ public:
   std::map< Node, std::vector< Node > > d_op_map;
   /** map from APPLY_UF functions to trie */
   std::map< Node, TermArgTrie > d_func_map_trie;
-  /** map from APPLY_UF predicates to trie */
-  std::map< Node, TermArgTrie > d_pred_map_trie[2];
+  std::map< Node, TermArgTrie > d_func_map_eqc_trie;
+  /**mapping from UF terms to representatives of their arguments */
+  std::map< TNode, std::vector< TNode > > d_arg_reps;
   /** map from type nodes to terms of that type */
   std::map< TypeNode, std::vector< Node > > d_type_map;
   /** add a term to the database */
   void addTerm( Node n, std::set< Node >& added, bool withinQuant = false );
   /** reset (calculate which terms are active) */
   void reset( Theory::Effort effort );
-  /** get operation */
+  /** get operator*/
   Node getOperator( Node n );
+  /** get term arg index */
+  TermArgTrie * getTermArgTrie( Node f );
+  TermArgTrie * getTermArgTrie( Node eqc, Node f );
+  /** exists term */
+  TNode existsTerm( Node f, Node n );
+  /** compute arg reps */
+  void computeArgReps( TNode n );
+  /** compute uf eqc terms */
+  void computeUfEqcTerms( TNode f );
+  /** evaluate a term under a substitution.  Return representative in EE if possible.
+   * subsRep is whether subs contains only representatives
+   */
+  TNode evaluateTerm( TNode n, std::map< TNode, TNode >& subs, bool subsRep );
+  /** is entailed (incomplete check) */
+  bool isEntailed( TNode n, std::map< TNode, TNode >& subs, bool subsRep, bool pol );
 public:
   /** parent structure (for efficient E-matching):
       n -> op -> index -> L
@@ -204,11 +223,16 @@ private:
 public:
   /** map from universal quantifiers to the list of skolem constants */
   std::map< Node, std::vector< Node > > d_skolem_constants;
+  /** for quantified formulas whose skolemization was strengthened by induction */
+  std::map< Node, Node > d_skolem_sub_quant;
+  std::map< Node, std::vector< unsigned > > d_skolem_sub_quant_vars;
   /** make the skolemized body f[e/x] */
   static Node mkSkolemizedBody( Node f, Node n, std::vector< TypeNode >& fvTypes, std::vector< TNode >& fvs,
-                                std::vector< Node >& sk );
+                                std::vector< Node >& sk, Node& sub, std::vector< unsigned >& sub_vars );
   /** get the skolemized body */
   Node getSkolemizedBody( Node f);
+  /** get skolem constants */
+  void getSkolemConstants( Node f, std::vector< Node >& sk, bool expSub = false );
 
 //miscellaneous
 public:
@@ -245,11 +269,18 @@ public:
   int isInstanceOf( Node n1, Node n2 );
   /** filter all nodes that have instances */
   void filterInstances( std::vector< Node >& nodes );
-public:
+  
+public: //for induction
+  /** is induction variable */
+  static bool isInductionTerm( Node n );
+  
+  
+public: //general queries concerning quantified formulas wrt modules
   /** is quantifier treated as a rewrite rule? */
   static bool isRewriteRule( Node q );
   /** get the rewrite rule associated with the quanfied formula */
   static Node getRewriteRule( Node q );
+  
 };/* class TermDb */
 
 }/* CVC4::theory::quantifiers namespace */
index c55ffa2a6611a7d1a5e756f79521ec90ad48ffda..a4adf80541e497fa7238c35f2be2db3afd1d3950 100644 (file)
@@ -30,6 +30,7 @@
 #include "theory/quantifiers/bounded_integers.h"
 #include "theory/quantifiers/rewrite_engine.h"
 #include "theory/quantifiers/quant_conflict_find.h"
+#include "theory/quantifiers/conjecture_generator.h"
 #include "theory/quantifiers/relevant_domain.h"
 #include "theory/uf/options.h"
 #include "theory/uf/theory_uf.h"
@@ -83,6 +84,12 @@ d_lemmas_produced_c(u){
   }else{
     d_qcf = NULL;
   }
+  if( options::conjectureGen() ){
+    d_sg_gen = new quantifiers::ConjectureGenerator( this, c );
+    d_modules.push_back( d_sg_gen );
+  }else{
+    d_sg_gen = NULL;
+  }
   if( !options::finiteModelFind() || options::fmfInstEngine() ){
     //the instantiation must set incomplete flag unless finite model finding is turned on
     d_inst_engine = new quantifiers::InstantiationEngine( this, !options::finiteModelFind() );
@@ -167,6 +174,7 @@ void QuantifiersEngine::check( Theory::Effort e ){
   }
   if( needsCheck ){
     Trace("quant-engine") << "Quantifiers Engine check, level = " << e << std::endl;
+    Trace("quant-engine-debug") << "  # quantified formulas = " << d_model->getNumAssertedQuantifiers() << std::endl;
     if( !getMasterEqualityEngine()->consistent() ){
       Trace("quant-engine") << "Master equality engine not consistent, return." << std::endl;
       return;
@@ -179,6 +187,7 @@ void QuantifiersEngine::check( Theory::Effort e ){
     if( d_rel_dom ){
       d_rel_dom->reset();
     }
+    d_model->reset_round();
     for( int i=0; i<(int)d_modules.size(); i++ ){
       d_modules[i]->reset_round( e );
     }
@@ -551,9 +560,20 @@ bool QuantifiersEngine::addInstantiation( Node f, std::vector< Node >& terms, bo
       }
     }
   }
+  //check for entailment
+  if( options::instNoEntail() ){
+    std::map< TNode, TNode > subs;
+    for( unsigned i=0; i<terms.size(); i++ ){
+      subs[f[0][i]] = terms[i];
+    }
+    if( d_term_db->isEntailed( f[1], subs, false, true ) ){
+      Trace("inst-add-debug") << " -> Currently entailed." << std::endl;
+      Trace("inst-add-entail") << " -> instantiation for " << f[1] << " currently entailed." << std::endl;
+      return false;
+    }
+  }
 
   //check for duplication
-  ///*
   bool alreadyExists = false;
   if( options::incrementalSolving() ){
     Trace("inst-add-debug") << "Adding into context-dependent inst trie, modEq = " << modEq << ", modInst = " << modInst << std::endl;
@@ -575,7 +595,7 @@ bool QuantifiersEngine::addInstantiation( Node f, std::vector< Node >& terms, bo
     ++(d_statistics.d_inst_duplicate_eq);
     return false;
   }
-  //*/
+
 
   //add the instantiation
   bool addedInst = addInstantiation( f, d_term_db->d_vars[f], terms );
index 7786e0b70b03879e972f4a0c1c216e64d649f66f..220fa0b1fda833e7e451f13b57101c262771e595 100644 (file)
@@ -73,6 +73,7 @@ namespace quantifiers {
   class QuantConflictFind;
   class RewriteEngine;
   class RelevantDomain;
+  class ConjectureGenerator;
 }/* CVC4::theory::quantifiers */
 
 namespace inst {
@@ -112,6 +113,8 @@ private:
   quantifiers::QuantConflictFind* d_qcf;
   /** rewrite rules utility */
   quantifiers::RewriteEngine * d_rr_engine;
+  /** subgoal generator */
+  quantifiers::ConjectureGenerator * d_sg_gen;
 private:
   /** list of all quantifiers seen */
   std::vector< Node > d_quants;