Simplify the QCF algorithm by more aggressive flattening, removes EqRegistry approach...
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Fri, 24 Jan 2014 19:58:52 +0000 (13:58 -0600)
committerAndrew Reynolds <andrew.j.reynolds@gmail.com>
Fri, 24 Jan 2014 19:59:08 +0000 (13:59 -0600)
src/theory/quantifiers/instantiation_engine.cpp
src/theory/quantifiers/macros.cpp
src/theory/quantifiers/modes.h
src/theory/quantifiers/options
src/theory/quantifiers/options_handlers.h
src/theory/quantifiers/quant_conflict_find.cpp
src/theory/quantifiers/quant_conflict_find.h
src/theory/quantifiers/quantifiers_rewriter.cpp

index e3ed8d0e0ff295f6d5690297424cc490cdc60b71..c19172b3b246962b649e6d626e3de17340183f90 100644 (file)
@@ -195,7 +195,7 @@ bool InstantiationEngine::needsCheck( Theory::Effort e ){
 }
 
 void InstantiationEngine::check( Theory::Effort e ){
-  if( d_performCheck ){
+  if( d_performCheck && !d_quantEngine->hasAddedLemma() ){
     Debug("inst-engine") << "IE: Check " << e << " " << d_ierCounter << std::endl;
     double clSet = 0;
     if( Trace.isOn("inst-engine") ){
index 600f8c0b931af10102d2ca3667563dc784bab096..435bf7221708c5c0b1af07491ff5c8bd072d72c4 100644 (file)
@@ -124,7 +124,16 @@ bool QuantifierMacros::isMacroLiteral( Node n, bool pol ){
 
 void QuantifierMacros::getMacroCandidates( Node n, std::vector< Node >& candidates ){
   if( n.getKind()==APPLY_UF ){
-    candidates.push_back( n );
+    bool allBoundVar = true;
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      if( n[i].getKind()!=BOUND_VARIABLE ){
+        allBoundVar = false;
+        break;
+      }
+    }
+    if( allBoundVar ){
+      candidates.push_back( n );
+    }
   }else if( n.getKind()==PLUS ){
     for( size_t i=0; i<n.getNumChildren(); i++ ){
       getMacroCandidates( n[i], candidates );
index 4eb12c98d273c8b0c928c270c99fb1a069e98ae1..c36a565ea80fb1a1ead5f29e27d740e0ef9fffd0 100644 (file)
@@ -73,12 +73,21 @@ typedef enum {
 typedef enum {
   /** default, apply at full effort */
   QCF_WHEN_MODE_DEFAULT,
+  /** apply at last call */
+  QCF_WHEN_MODE_LAST_CALL,
   /** apply at standard effort */
   QCF_WHEN_MODE_STD,
   /** apply based on heuristics */
   QCF_WHEN_MODE_STD_H,
 } QcfWhenMode;
 
+typedef enum {
+  /** default, use qcf for conflicts only */
+  QCF_CONFLICT_ONLY,
+  /** use qcf for conflicts and propagations */
+  QCF_PROP_EQ,
+} QcfMode;
+
 typedef enum {
   /** default, use but do not trust */
   USER_PAT_MODE_DEFAULT,
index bfb1d6f6548f911f81f04de2e476ba1c27dfd288..00d3cf2341a9235418e889488dba83ac60ce7421 100644 (file)
@@ -121,6 +121,8 @@ option axiomInstMode --axiom-inst=MODE CVC4::theory::quantifiers::AxiomInstMode
 
 option quantConflictFind --quant-cf bool :default false
  enable conflict find mechanism for quantifiers
+option qcfMode --quant-cf-mode=MODE CVC4::theory::quantifiers::QcfMode :default CVC4::theory::quantifiers::QCF_CONFLICT_ONLY :include "theory/quantifiers/modes.h" :handler CVC4::theory::quantifiers::stringToQcfMode :handler-include "theory/quantifiers/options_handlers.h"
+ what effort to apply conflict find mechanism
 option qcfWhenMode --quant-cf-when=MODE CVC4::theory::quantifiers::QcfWhenMode :default CVC4::theory::quantifiers::QCF_WHEN_MODE_DEFAULT :include "theory/quantifiers/modes.h" :handler CVC4::theory::quantifiers::stringToQcfWhenMode :handler-include "theory/quantifiers/options_handlers.h"
  when to invoke conflict find mechanism for quantifiers
 
index 5bd710a79d63889d7b0127ac53b25261bdf09bc1..37362982c92f7dbe6f98f06454677c791b2ac0b3 100644 (file)
@@ -37,7 +37,8 @@ full-last-call\n\
   call.  In other words, interleave instantiation and theory combination.\n\
 \n\
 last-call\n\
-+ Run instantiation at last call effort, after theory combination.\n\
++ Run instantiation at last call effort, after theory combination and\n\
+  and theories report sat.\n\
 \n\
 ";
 
@@ -103,6 +104,10 @@ Quantifier conflict find modes currently supported by the --quant-cf-when option
 default \n\
 + Default, apply conflict finding at full effort.\n\
 \n\
+last-call \n\
++ Apply conflict finding at last call, after theory combination and \n\
+  and all theories report sat. \n\
+\n\
 std \n\
 + Apply conflict finding at standard effort.\n\
 \n\
@@ -110,6 +115,16 @@ std-h \n\
 + Apply conflict finding at standard effort when heuristic says to. \n\
 \n\
 ";
+static const std::string qcfModeHelp = "\
+Quantifier conflict find modes currently supported by the --quant-cf option:\n\
+\n\
+conflict \n\
++ Default, apply conflict finding for finding conflicts only.\n\
+\n\
+prop-eq \n\
++ Apply conflict finding to propagate equalities as well. \n\
+\n\
+";
 static const std::string userPatModeHelp = "\
 User pattern modes currently supported by the --user-pat option:\n\
 \n\
@@ -215,6 +230,8 @@ inline void checkMbqiMode(std::string option, MbqiMode mode, SmtEngine* smt) thr
 inline QcfWhenMode stringToQcfWhenMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) {
   if(optarg ==  "default") {
     return QCF_WHEN_MODE_DEFAULT;
+  } else if(optarg ==  "last-call") {
+    return QCF_WHEN_MODE_LAST_CALL;
   } else if(optarg ==  "std") {
     return QCF_WHEN_MODE_STD;
   } else if(optarg ==  "std-h") {
@@ -227,6 +244,19 @@ inline QcfWhenMode stringToQcfWhenMode(std::string option, std::string optarg, S
                           optarg + "'.  Try --quant-cf-when help.");
   }
 }
+inline QcfMode stringToQcfMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) {
+  if(optarg ==  "default" || optarg ==  "conflict") {
+    return QCF_CONFLICT_ONLY;
+  } else if(optarg ==  "prop-eq") {
+    return QCF_PROP_EQ;
+  } else if(optarg ==  "help") {
+    puts(qcfModeHelp.c_str());
+    exit(1);
+  } else {
+    throw OptionException(std::string("unknown option for --quant-cf-mode: `") +
+                          optarg + "'.  Try --quant-cf-mode help.");
+  }
+}
 
 inline UserPatMode stringToUserPatMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) {
   if(optarg ==  "default") {
index 66191107da51b3f8ef6a3ceefc09fb1d4a9f7343..198ec3bbf98c33764038847130ea12506e4e67b4 100755 (executable)
@@ -35,10 +35,11 @@ Node QcfNodeIndex::existsTerm( TNode n, std::vector< TNode >& reps, int index )
       return d_children.begin()->first;\r
     }\r
   }else{\r
-    if( d_children.find( reps[index] )==d_children.end() ){\r
+    std::map< TNode, QcfNodeIndex >::iterator it = d_children.find( reps[index] );\r
+    if( it==d_children.end() ){\r
       return Node::null();\r
     }else{\r
-      return d_children[reps[index]].existsTerm( n, reps, index+1 );\r
+      return it->second.existsTerm( n, reps, index+1 );\r
     }\r
   }\r
 }\r
@@ -56,16 +57,6 @@ Node QcfNodeIndex::addTerm( TNode n, std::vector< TNode >& reps, int index ) {
   }\r
 }\r
 \r
-bool QcfNodeIndex::addTermEq( TNode n1, TNode n2, std::vector< TNode >& reps1, std::vector< TNode >& reps2, int index ) {\r
-  if( index==(int)reps1.size() ){\r
-    Node n = addTerm( n2, reps2 );\r
-    return n==n2;\r
-  }else{\r
-    return d_children[reps1[index]].addTermEq( n1, n2, reps1, reps2, index+1 );\r
-  }\r
-}\r
-\r
-\r
 \r
 void QcfNodeIndex::debugPrint( const char * c, int t ) {\r
   for( std::map< TNode, QcfNodeIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){\r
@@ -77,19 +68,6 @@ void QcfNodeIndex::debugPrint( const char * c, int t ) {
   }\r
 }\r
 \r
-EqRegistry::EqRegistry( context::Context* c ) : d_active( c, false ){//: d_t_eqc( c ){\r
-\r
-}\r
-\r
-void EqRegistry::debugPrint( const char * c, int t ) {\r
-  d_qni.debugPrint( c, t );\r
-}\r
-\r
-//QcfNode::QcfNode( context::Context* c ) : d_parent( NULL ){\r
-//  d_reg[0] = NULL;\r
-//  d_reg[1] = NULL;\r
-//}\r
-\r
 QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :\r
 QuantifiersModule( qe ),\r
 d_c( c ),\r
@@ -98,39 +76,6 @@ d_qassert( c ) {
   d_fid_count = 0;\r
   d_true = NodeManager::currentNM()->mkConst<bool>(true);\r
   d_false = NodeManager::currentNM()->mkConst<bool>(false);\r
-  getFunctionId( d_true );\r
-  getFunctionId( d_false );\r
-}\r
-\r
-int QuantConflictFind::getFunctionId( Node f ) {\r
-  std::map< Node, int >::iterator it = d_fid.find( f );\r
-  if( it==d_fid.end() ){\r
-    d_fid[f] = d_fid_count;\r
-    d_fid_count++;\r
-    return d_fid[f];\r
-  }\r
-  return it->second;\r
-}\r
-\r
-bool QuantConflictFind::isLessThan( Node a, Node b ) {\r
-  //Assert( a.getKind()==APPLY_UF );\r
-  //Assert( b.getKind()==APPLY_UF );\r
-  /*\r
-  if( a.getOperator()==b.getOperator() ){\r
-    for( unsigned i=0; i<a.getNumChildren(); i++ ){\r
-      Node acr = getRepresentative( a[i] );\r
-      Node bcr = getRepresentative( b[i] );\r
-      if( acr<bcr ){\r
-        return true;\r
-      }else if( acr>bcr ){\r
-        return false;\r
-      }\r
-    }\r
-    return false;\r
-  }else{\r
-    */\r
-  return getFunctionId( a )<getFunctionId( b );\r
-  //}\r
 }\r
 \r
 Node QuantConflictFind::getFunction( Node n, int& index, bool isQuant ) {\r
@@ -159,15 +104,6 @@ Node QuantConflictFind::getFunction( Node n, int& index, bool isQuant ) {
   }\r
 }\r
 \r
-Node QuantConflictFind::getFv( TypeNode tn ) {\r
-  if( d_fv.find( tn )==d_fv.end() ){\r
-    std::stringstream ss;\r
-    ss << "_u";\r
-    d_fv[tn] = NodeManager::currentNM()->mkSkolem( ss.str(), tn, "is for QCF" );\r
-  }\r
-  return d_fv[tn];\r
-}\r
-\r
 Node QuantConflictFind::mkEqNode( Node a, Node b ) {\r
   if( a.getType().isBoolean() ){\r
     return a.iffNode( b );\r
@@ -178,47 +114,36 @@ Node QuantConflictFind::mkEqNode( Node a, Node b ) {
 \r
 //-------------------------------------------------- registration\r
 \r
-/*\r
-void QuantConflictFind::registerAssertions( std::vector< Node >& assertions ) {\r
-  for( unsigned i=0; i<assertions.size(); i++ ){\r
-    registerAssertion( assertions[i] );\r
-  }\r
-}\r
-\r
-void QuantConflictFind::registerAssertion( Node n ) {\r
-  if( n.getKind()==FORALL ){\r
-    registerNode( Node::null(), n[1], NULL, true, true );\r
-  }else{\r
-    if( n.getType().isBoolean() ){\r
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-        registerAssertion( n[i] );\r
-      }\r
-    }\r
-  }\r
-}\r
-*/\r
 void QuantConflictFind::registerNode( Node q, Node n, bool hasPol, bool pol ) {\r
   //qcf->d_node = n;\r
   bool recurse = true;\r
   if( n.getKind()!=OR && n.getKind()!=AND && n.getKind()!=IFF && n.getKind()!=ITE && n.getKind()!=NOT ){\r
     if( quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
       //literals\r
-      for( unsigned i=0; i<2; i++ ){\r
-        if( !hasPol || ( pol!=(i==0) ) ){\r
-          EqRegistry * eqr = getEqRegistry( i==0, n );\r
-          if( eqr ){\r
-            d_qinfo[q].d_rel_eqr[ eqr ] = true;\r
+\r
+      /*\r
+        if( n.getKind()==APPLY_UF || ( n.getKind()==EQUAL && ( n[0].getKind()==BOUND_VARIABLE || n[1].getKind()==BOUND_VARIABLE ) ) ){\r
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+            flatten( q, n[i] );\r
+          }\r
+        }else if( n.getKind()==EQUAL ){\r
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+            for( unsigned j=0; j<n[i].getNumChildren(); j++ ){\r
+              flatten( q, n[i][j] );\r
+            }\r
           }\r
         }\r
-      }\r
-      if( n.getKind()==APPLY_UF ||\r
-          ( n.getKind()==EQUAL && ( n[0].getKind()==BOUND_VARIABLE || n[1].getKind()==BOUND_VARIABLE ) ) ){\r
+\r
+        */\r
+\r
+      if( n.getKind()==APPLY_UF ){\r
         flatten( q, n );\r
-      }else{\r
+      }else if( n.getKind()==EQUAL ){\r
         for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
           flatten( q, n[i] );\r
         }\r
       }\r
+\r
     }else{\r
       Trace("qcf-qregister") << "    RegisterGroundLit : " << n;\r
     }\r
@@ -238,14 +163,14 @@ void QuantConflictFind::registerNode( Node q, Node n, bool hasPol, bool pol ) {
 }\r
 \r
 void QuantConflictFind::flatten( Node q, Node n ) {\r
-  for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-    if( quantifiers::TermDb::hasBoundVarAttr( n[i] ) && n.getKind()!=BOUND_VARIABLE ){\r
-      if( d_qinfo[q].d_var_num.find( n[i] )==d_qinfo[q].d_var_num.end() ){\r
-        //Trace("qcf-qregister") << "    Flatten term " << n[i] << std::endl;\r
-        d_qinfo[q].d_var_num[n[i]] = d_qinfo[q].d_vars.size();\r
-        d_qinfo[q].d_vars.push_back( n[i] );\r
-        flatten( q, n[i] );\r
-      }\r
+  if( quantifiers::TermDb::hasBoundVarAttr( n ) && n.getKind()!=BOUND_VARIABLE ){\r
+    if( d_qinfo[q].d_var_num.find( n )==d_qinfo[q].d_var_num.end() ){\r
+      //Trace("qcf-qregister") << "    Flatten term " << n[i] << std::endl;\r
+      d_qinfo[q].d_var_num[n] = d_qinfo[q].d_vars.size();\r
+      d_qinfo[q].d_vars.push_back( n );\r
+    }\r
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+      flatten( q, n[i] );\r
     }\r
   }\r
 }\r
@@ -296,82 +221,31 @@ void QuantConflictFind::registerQuantifier( Node q ) {
   Trace("qcf-qregister") << "Done registering quantifier." << std::endl;\r
 }\r
 \r
-EqRegistry * QuantConflictFind::getEqRegistry( bool polarity, Node lit, bool doCreate ) {\r
-  Assert( quantifiers::TermDb::hasBoundVarAttr( lit ) );\r
-  int i;\r
-  Node f1;\r
-  Node f2;\r
-  int f1Index;\r
-  int f2Index;\r
-  if( lit.getKind()==EQUAL ){\r
-    i = polarity ? 0 : 1;\r
-    f1 = getFunction( lit[0], f1Index, true );\r
-    f2 = getFunction( lit[1], f2Index, true );\r
-  }else if( lit.getKind()==APPLY_UF ){\r
-    i = 0;\r
-    f1 = getFunction( lit, f1Index, true );\r
-    f2 = polarity ? d_true : d_false;\r
-    f2Index = 0;\r
-  }\r
-  if( !f1.isNull() && !f2.isNull() ){\r
-    if( d_eqr[i][f1Index][f1][f2Index].find( f2 )==d_eqr[i][f1Index][f1][f2Index].end() ){\r
-      if( doCreate ){\r
-        Trace("qcf-register") << "RegisterEqr : " << f1 << " " << f2 << ", polarity = " << (i==0) << ", indices : " << f1Index << " " << f2Index << std::endl;\r
-        d_eqr[i][f1Index][f1][f2Index][f2] = new EqRegistry( d_c );\r
-        d_eqr[i][f2Index][f2][f1Index][f1] = d_eqr[i][f1Index][f1][f2Index][f2];\r
-      }else{\r
-        return NULL;\r
-      }\r
-    }\r
-    return d_eqr[i][f1Index][f1][f2Index][f2];\r
-  }else{\r
-    return NULL;\r
-  }\r
-}\r
-\r
-void QuantConflictFind::getEqRegistryApps( Node lit, std::vector< Node >& terms ) {\r
-  Assert( quantifiers::TermDb::hasBoundVarAttr( lit ) );\r
-  if( lit.getKind()==EQUAL ){\r
-    for( unsigned i=0; i<2; i++ ){\r
-      if( quantifiers::TermDb::hasBoundVarAttr( lit[i] ) ){\r
-        if( lit[i].getKind()==BOUND_VARIABLE ){\r
-          //do not handle variable equalities\r
-          terms.clear();\r
-          return;\r
-        }else{\r
-          terms.push_back( lit[i] );\r
-        }\r
-      }\r
-    }\r
-    if( terms.size()==2 && isLessThan( terms[1].getOperator(), terms[0].getOperator() ) ){\r
-      Node t = terms[0];\r
-      terms[0] = terms[1];\r
-      terms[1] = t;\r
-    }\r
-  }else if( lit.getKind()==APPLY_UF ){\r
-    terms.push_back( lit );\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 = getTerm( n[0] );\r
-    Node n2 = getTerm( n[1] );\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( n.getKind()==APPLY_UF ){  //predicate\r
-    Node nn = getTerm( n );\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
@@ -430,26 +304,19 @@ bool QuantConflictFind::isPropagationSet() {
 }\r
 \r
 bool QuantConflictFind::areMatchEqual( TNode n1, TNode n2 ) {\r
+  //if( d_effort==QuantConflictFind::effort_prop_deq ){\r
+  //  return n1==n2 || !areDisequal( n1, n2 );\r
+  //}else{\r
   return n1==n2;\r
-  /*\r
-  if( n1==n2 ){\r
-    return true;\r
-  }else if( isPropagationSet() && d_prop_pol ){\r
-    return ( d_prop_eq[0]==n1 && d_prop_eq[1]==n2 ) || ( d_prop_eq[0]==n2 && d_prop_eq[1]==n1 );\r
-  }\r
-  */\r
+  //}\r
 }\r
 \r
 bool QuantConflictFind::areMatchDisequal( TNode n1, TNode n2 ) {\r
-  //return n1!=n2;\r
-  return areDisequal( n1, n2 );\r
-  /*\r
-  if( n1!=n2 ){\r
-    return true;\r
-  }else if( isPropagationSet() && !d_prop_pol ){\r
-    return ( d_prop_eq[0]==n1 && d_prop_eq[1]==n2 ) || ( d_prop_eq[0]==n2 && d_prop_eq[1]==n1 );\r
-  }\r
-  */\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
@@ -460,9 +327,9 @@ void QuantConflictFind::assertNode( Node q ) {
   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
+  //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
 eq::EqualityEngine * QuantConflictFind::getEqualityEngine() {\r
@@ -482,17 +349,32 @@ Node QuantConflictFind::getRepresentative( Node n ) {
     return n;\r
   }\r
 }\r
-Node QuantConflictFind::getTerm( Node n ) {\r
+Node QuantConflictFind::evaluateTerm( Node n ) {\r
   if( isHandledUfTerm( n ) ){\r
-    computeArgReps( n );\r
-    Node nn = d_uf_terms[n.getOperator()].existsTerm( n, d_arg_reps[n] );\r
+    Node nn;\r
+    if( getEqualityEngine()->hasTerm( n ) ){\r
+      computeArgReps( n );\r
+      nn = d_uf_terms[n.getOperator()].existsTerm( n, d_arg_reps[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 = d_uf_terms[n.getOperator()].existsTerm( n, args );\r
+    }\r
     if( !nn.isNull() ){\r
-      return nn;\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
   }\r
-  return n;\r
+  return getRepresentative( n );\r
 }\r
 \r
+/*\r
 QuantConflictFind::EqcInfo * QuantConflictFind::getEqcInfo( Node n, bool doCreate ) {\r
   std::map< Node, EqcInfo * >::iterator it2 = d_eqc_info.find( n );\r
   if( it2==d_eqc_info.end() ){\r
@@ -506,13 +388,23 @@ QuantConflictFind::EqcInfo * QuantConflictFind::getEqcInfo( Node n, bool doCreat
   }\r
   return it2->second;\r
 }\r
+*/\r
 \r
 QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node eqc, Node f ) {\r
-  std::map< TNode, QcfNodeIndex >::iterator itut = d_eqc_uf_terms[ eqc ].find( f );\r
-  if( itut!=d_eqc_uf_terms[ eqc ].end() ){\r
-    return &itut->second;\r
-  }else{\r
+  std::map< TNode, QcfNodeIndex >::iterator itut = d_eqc_uf_terms.find( f );\r
+  if( itut==d_eqc_uf_terms.end() ){\r
     return NULL;\r
+  }else{\r
+    if( eqc.isNull() ){\r
+      return &itut->second;\r
+    }else{\r
+      std::map< TNode, QcfNodeIndex >::iterator itute = itut->second.d_children.find( eqc );\r
+      if( itute!=itut->second.d_children.end() ){\r
+        return &itute->second;\r
+      }else{\r
+        return NULL;\r
+      }\r
+    }\r
   }\r
 }\r
 \r
@@ -527,13 +419,13 @@ QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node f ) {
 \r
 /** new node */\r
 void QuantConflictFind::newEqClass( Node n ) {\r
-  Trace("qcf-proc-debug") << "QCF : newEqClass : " << n << std::endl;\r
-\r
-  Trace("qcf-proc2-debug") << "QCF : finished newEqClass : " << n << std::endl;\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
   if( b.getKind()==EQUAL ){\r
     if( a==d_true ){\r
       //will merge anyways\r
@@ -562,23 +454,23 @@ void QuantConflictFind::merge( Node a, Node b ) {
           eqc_n->setDisequal( b, false );\r
         }\r
       }\r
-      /*\r
-      //move all previous EqcRegistry's regarding equalities within b\r
-      for( NodeBoolMap::iterator it = eqc_b->d_rel_eqr_e.begin(); it != eqc_b->d_rel_eqr_e.end(); ++it ){\r
-        if( (*it).second ){\r
-          eqc_a->d_rel_eqr_e[(*it).first] = true;\r
-        }\r
-      }\r
-      */\r
+      ////move all previous EqcRegistry's regarding equalities within b\r
+      //for( NodeBoolMap::iterator it = eqc_b->d_rel_eqr_e.begin(); it != eqc_b->d_rel_eqr_e.end(); ++it ){\r
+      //  if( (*it).second ){\r
+      //    eqc_a->d_rel_eqr_e[(*it).first] = true;\r
+      //  }\r
+      //}\r
     }\r
     //process new equalities\r
     //setEqual( eqc_a, eqc_b, a, b, true );\r
     Trace("qcf-proc2") << "QCF : finished merge : " << a << " " << b << std::endl;\r
   }\r
+  */\r
 }\r
 \r
 /** assert disequal */\r
 void QuantConflictFind::assertDisequal( Node a, Node b ) {\r
+  /*\r
   a = getRepresentative( a );\r
   b = getRepresentative( b );\r
   Trace("qcf-proc") << "QCF : assert disequal : " << a << " " << b << std::endl;\r
@@ -591,6 +483,7 @@ void QuantConflictFind::assertDisequal( Node a, Node b ) {
     //setEqual( eqc_a, eqc_b, a, b, false );\r
   }\r
   Trace("qcf-proc2") << "QCF : finished assert disequal : " << a << " " << b << std::endl;\r
+  */\r
 }\r
 \r
 //-------------------------------------------------- check function\r
@@ -620,15 +513,15 @@ void QuantConflictFind::check( Theory::Effort level ) {
         debugPrint("qcf-debug");\r
         Trace("qcf-debug") << std::endl;\r
       }\r
-\r
-      for( short e = effort_conflict; e<=effort_conflict; e++ ){\r
+      short end_e = options::qcfMode()==QCF_CONFLICT_ONLY ? effort_conflict : effort_prop_eq;\r
+      for( short e = effort_conflict; e<=end_e; e++ ){\r
         d_effort = e;\r
-        if( e == effort_propagation ){\r
+        if( e == effort_prop_eq ){\r
           for( unsigned i=0; i<2; i++ ){\r
             d_prop_eq[i] = Node::null();\r
           }\r
         }\r
-        Trace("qcf-check") << "Checking quantified formulas..." << std::endl;\r
+        Trace("qcf-check") << "Checking quantified formulas at effort " << e << "..." << std::endl;\r
         for( unsigned j=0; j<d_qassert.size(); j++ ){\r
           Node q = d_qassert[j];\r
           Trace("qcf-check") << "Check quantified formula ";\r
@@ -642,7 +535,7 @@ void QuantConflictFind::check( Theory::Effort level ) {
             d_qinfo[q].d_mg->reset( this, false, q );\r
             while( d_qinfo[q].d_mg->getNextMatch( this, q ) ){\r
 \r
-              Trace("qcf-check") << "*** Produced match : " << std::endl;\r
+              Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;\r
               d_qinfo[q].debugPrintMatch("qcf-check");\r
               Trace("qcf-check") << std::endl;\r
 \r
@@ -651,14 +544,27 @@ void QuantConflictFind::check( Theory::Effort level ) {
                 if( d_qinfo[q].completeMatch( this, q, assigned ) ){\r
                   InstMatch m;\r
                   for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
-                    Node cv = d_qinfo[q].getCurrentValue( d_qinfo[q].d_match[i] );\r
+                    //Node cv = d_qinfo[q].getCurrentValue( d_qinfo[q].d_match[i] );\r
+                    int repVar = d_qinfo[q].getCurrentRepVar( i );\r
+                    Node cv;\r
+                    std::map< int, Node >::iterator itmt = d_qinfo[q].d_match_term.find( repVar );\r
+                    if( itmt!=d_qinfo[q].d_match_term.end() ){\r
+                      cv = itmt->second;\r
+                    }else{\r
+                      cv = d_qinfo[q].d_match[repVar];\r
+                    }\r
+\r
+\r
                     Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << d_qinfo[q].d_match[i] << std::endl;\r
                     m.set( d_quantEngine, q, i, cv );\r
                   }\r
                   if( Debug.isOn("qcf-check-inst") ){\r
+                    //if( e==effort_conflict ){\r
                     Node inst = d_quantEngine->getInstantiation( q, m );\r
                     Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;\r
-                    Assert( evaluate( inst )==-1 );\r
+                    Assert( evaluate( inst )!=1 );\r
+                    Assert( evaluate( inst )==-1 || e>effort_conflict );\r
+                    //}\r
                   }\r
                   if( d_quantEngine->addInstantiation( q, m ) ){\r
                     Trace("qcf-check") << "   ... Added instantiation" << std::endl;\r
@@ -667,7 +573,7 @@ void QuantConflictFind::check( Theory::Effort level ) {
                       d_conflict.set( true );\r
                       ++(d_statistics.d_conflict_inst);\r
                       break;\r
-                    }else if( e==effort_propagation ){\r
+                    }else if( e==effort_prop_eq ){\r
                       ++(d_statistics.d_prop_inst);\r
                     }\r
                   }else{\r
@@ -690,13 +596,19 @@ void QuantConflictFind::check( Theory::Effort level ) {
             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) << ", addedLemmas = " << addedLemmas << std::endl;\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" : "prop_deq" ) );\r
+          Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;\r
         }\r
+        Trace("qcf-engine") << std::endl;\r
       }\r
     }\r
     Trace("qcf-check2") << "QCF : finished check : " << level << std::endl;\r
@@ -706,7 +618,9 @@ void QuantConflictFind::check( Theory::Effort level ) {
 bool QuantConflictFind::needsCheck( Theory::Effort level ) {\r
   d_performCheck = false;\r
   if( !d_conflict ){\r
-    if( level==Theory::EFFORT_FULL ){\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
@@ -716,18 +630,6 @@ bool QuantConflictFind::needsCheck( Theory::Effort level ) {
 }\r
 \r
 void QuantConflictFind::computeRelevantEqr() {\r
-  //first, reset information\r
-  for( unsigned i=0; i<2; i++ ){\r
-    for( unsigned j=0; j<2; j++ ){\r
-      for( std::map< TNode, std::map< int, std::map< TNode, EqRegistry * > > >::iterator it = d_eqr[i][j].begin(); it != d_eqr[i][j].end(); ++it ){\r
-        for( unsigned jj=0; jj<2; jj++ ){\r
-          for( std::map< TNode, EqRegistry * >::iterator it2 = it->second[jj].begin(); it2 != it->second[jj].end(); ++it2 ){\r
-            it2->second->clear();\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
   d_uf_terms.clear();\r
   d_eqc_uf_terms.clear();\r
   d_eqcs.clear();\r
@@ -740,13 +642,6 @@ void QuantConflictFind::computeRelevantEqr() {
   long nTermst = 0;\r
   long nTerms = 0;\r
   long nEqc = 0;\r
-  long nEq1 = 0;\r
-  long nEq2 = 0;\r
-  long nEq1t = 0;\r
-  long nEq2t = 0;\r
-  long nComp = 0;\r
-  //relevant nodes for eq registries\r
-  std::map< TNode, std::map< TNode, std::vector< TNode > > > eqr_to_node[2];\r
 \r
   //which nodes are irrelevant for disequality matches\r
   std::map< TNode, bool > irrelevant_dnode;\r
@@ -756,8 +651,9 @@ void QuantConflictFind::computeRelevantEqr() {
     nEqc++;\r
     Node r = (*eqcs_i);\r
     d_eqcs[r.getType()].push_back( r );\r
-    EqcInfo * eqcir = getEqcInfo( r, false );\r
+    //EqcInfo * eqcir = getEqcInfo( r, false );\r
     //get relevant nodes that we are disequal from\r
+    /*\r
     std::vector< Node > deqc;\r
     if( eqcir ){\r
       for( NodeBoolMap::iterator it = eqcir->d_diseq.begin(); it != eqcir->d_diseq.end(); ++it ){\r
@@ -771,8 +667,7 @@ void QuantConflictFind::computeRelevantEqr() {
         }\r
       }\r
     }\r
-    //the relevant nodes in this eqc\r
-    std::vector< Node > eqc;\r
+    */\r
     //process disequalities\r
     eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );\r
     while( !eqc_i.isFinished() ){\r
@@ -793,7 +688,7 @@ void QuantConflictFind::computeRelevantEqr() {
           computeArgReps( n );\r
           it_na = d_arg_reps.find( n );\r
           Assert( it_na!=d_arg_reps.end() );\r
-          Node nadd = d_eqc_uf_terms[r][n.getOperator()].addTerm( n, d_arg_reps[n] );\r
+          Node nadd = d_eqc_uf_terms[n.getOperator()].d_children[r].addTerm( n, d_arg_reps[n] );\r
           isRedundant = (nadd!=n);\r
           d_uf_terms[n.getOperator()].addTerm( n, d_arg_reps[n] );\r
           if( !isRedundant ){\r
@@ -804,102 +699,6 @@ void QuantConflictFind::computeRelevantEqr() {
           isRedundant = false;\r
         }\r
         nTerms += isRedundant ? 0 : 1;\r
-\r
-        Trace("qcf-reqr") << "^ Process " << n << std::endl;\r
-        //process all relevant equalities and disequalities to n\r
-        for( unsigned index=0; index<2; index++ ){\r
-          std::map< TNode, std::map< int, std::map< TNode, EqRegistry * > > >::iterator itn[2];\r
-          itn[0] = d_eqr[index][0].find( n );\r
-          if( !fn.isNull() ){\r
-            itn[1] = d_eqr[index][1].find( fn );\r
-          }\r
-          //for n, fn...\r
-          bool relevant = false;\r
-          for( unsigned j=0; j<2; j++ ){\r
-            //if this node is relevant as an ground term or f-application\r
-            if( ( j==0 || !fn.isNull() ) && itn[j]!=d_eqr[index][j].end() ){\r
-              relevant = true;\r
-              for( unsigned jj=0; jj<2; jj++ ){\r
-                if( j==1 || jj==1 ){\r
-                  Trace("qcf-reqr") << "^^ " << index << " " << j << " " << jj << std::endl;\r
-                  //check with others\r
-                  for( std::map< TNode, EqRegistry * >::iterator itm = itn[j]->second[jj].begin(); itm != itn[j]->second[jj].end(); ++itm ){\r
-                    std::map< TNode, std::map< TNode, std::vector< TNode > > >::iterator itv = eqr_to_node[index].find( itm->first );\r
-                    if( itv!=eqr_to_node[index].end() ){\r
-                      //for( unsigned k=0; k<itv->second.size(); k++ ){\r
-                      for( std::map< TNode, std::vector< TNode > >::iterator itvr = itv->second.begin(); itvr != itv->second.end(); ++itvr ){\r
-                        TNode mr = itvr->first;\r
-                        //Assert( j==0 || getFunction( m )==itm->first );\r
-                        nComp++;\r
-                        //if it is equal or disequal to this\r
-                        if( ( index==0 && mr==r ) ||\r
-                            ( index==1 && std::find( deqc.begin(), deqc.end(), mr )!=deqc.end() ) ){\r
-                          Debug("qcf-reqr") << "^^ Check with : " << itv->first << ", # = " << itvr->second.size() << std::endl;\r
-                          for( unsigned k=0; k<itvr->second.size(); k++ ){\r
-                            TNode m = itvr->second[k];\r
-                            Debug("qcf-reqr") << "Comparing " << n << " and " << m << ", j = " << j << ", index = " << index << std::endl;\r
-                            Debug("qcf-reqr") << "Meets the criteria of " << itn[j]->first << " " << itm->first << std::endl;\r
-                            //process equality/disequality\r
-                            if( j==0 ){\r
-                              Assert( d_arg_reps.find( m )!=d_arg_reps.end() );\r
-                              //n with fm\r
-                              nEq1t++;\r
-                              if( itm->second->d_qni.addTerm( m, d_arg_reps[m] )==m ){\r
-                                nEq1++;\r
-                                Debug("qcf-reqr") << "Add relevant : " << n << (index==0?"":"!") << "=" << m << " for ";\r
-                                Debug("qcf-reqr") << n << " " << itm->first << std::endl;\r
-                              }\r
-                            }else{\r
-                              if( jj==0 ){\r
-                                //fn with m\r
-                                nEq1t++;\r
-                                if( itm->second->d_qni.addTerm( n, it_na->second )==n ){\r
-                                  nEq1++;\r
-                                  Debug("qcf-reqr") << "Add relevant : " << n << (index==0?"":"!") << "=" << m << " for ";\r
-                                  Debug("qcf-reqr") << fn << " " << m << std::endl;\r
-                                }\r
-                              }else{\r
-                                Assert( d_arg_reps.find( m )!=d_arg_reps.end() );\r
-                                //fn with fm\r
-                                bool mltn = isLessThan( itm->first, fn );\r
-                                for( unsigned i=0; i<2; i++ ){\r
-                                  if( i==0 || itm->first==fn ){\r
-                                    TNode am = ((i==0)==mltn) ? n : m;\r
-                                    TNode an = ((i==0)==mltn) ? m : n;\r
-                                    nEq2t++;\r
-                                    if( itm->second->d_qni.addTermEq( an, am, it_na->second, d_arg_reps[m] ) ){\r
-                                      nEq2++;\r
-                                      Debug("qcf-reqr") << "Add relevant (eq) : " << an << (index==0?"":"!") << "=" << am << " for ";\r
-                                      Debug("qcf-reqr") << fn << " " << itm->first << std::endl;\r
-                                    }\r
-                                  }\r
-                                }\r
-                              }\r
-                            }\r
-                          }\r
-                        }\r
-                      }\r
-                    }\r
-                  }\r
-                }\r
-              }\r
-              Trace("qcf-reqr") << "- Node " << n << " is relevant for " << (j==0 ? n : fn) << ", index = " << index << std::endl;\r
-              //add it to relevant\r
-              eqr_to_node[index][j==0 ? n : fn][r].push_back( n );\r
-            }\r
-          }\r
-          if( !relevant ){\r
-            //if not relevant for disequalities, store it\r
-            if( index==1 ){\r
-              irrelevant_dnode[n] = true;\r
-            }\r
-          }else{\r
-            //if relevant for equalities, store it\r
-            if( index==0 ){\r
-              eqc.push_back( n );\r
-            }\r
-          }\r
-        }\r
       }\r
       ++eqc_i;\r
     }\r
@@ -911,9 +710,6 @@ void QuantConflictFind::computeRelevantEqr() {
     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") << "   " << nEq1 << " / " << nEq1t << " pattern terms." << std::endl;\r
-    Trace("qcf-opt") << "   " << nEq2 << " / " << nEq2t << " pattern equalities." << std::endl;\r
-    Trace("qcf-opt") << "   " << nComp << " compares." << std::endl;\r
     Trace("qcf-opt") << "   Time : " << (clSet2-clSet) << std::endl;\r
   }\r
 }\r
@@ -932,6 +728,7 @@ bool QuantConflictFind::isHandledUfTerm( TNode n ) {
 \r
 void QuantConflictFind::QuantInfo::reset_round( QuantConflictFind * p ) {\r
   d_match.clear();\r
+  d_match_term.clear();\r
   d_curr_var_deq.clear();\r
   //add built-in variable constraints\r
   for( unsigned r=0; r<2; r++ ){\r
@@ -990,16 +787,16 @@ Node QuantConflictFind::QuantInfo::getCurrentValue( Node n ) {
   }\r
 }\r
 \r
-bool QuantConflictFind::QuantInfo::getCurrentCanBeEqual( QuantConflictFind * p, int v, Node n ) {\r
+bool QuantConflictFind::QuantInfo::getCurrentCanBeEqual( QuantConflictFind * p, int v, Node n, bool chDiseq ) {\r
   //check disequalities\r
   for( std::map< Node, int >::iterator it = d_curr_var_deq[v].begin(); it != d_curr_var_deq[v].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( !isVar( n ) && !isVar( cv ) ){\r
-      //they must actually be disequal\r
-      if( !p->areMatchDisequal( n, cv ) ){\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
         return false;\r
       }\r
     }\r
@@ -1148,6 +945,31 @@ int QuantConflictFind::QuantInfo::addConstraint( QuantConflictFind * p, int v, N
   }\r
 }\r
 \r
+bool QuantConflictFind::QuantInfo::isConstrainedVar( int v ) {\r
+  //if( options::qcfMode()==QCF_CONFLICT_ONLY ){\r
+  //  return true;\r
+  //}else{\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, Node >::iterator it = d_match.begin(); it != d_match.end(); ++it ){\r
+        if( it->second==vv ){\r
+          return true;\r
+        }\r
+      }\r
+      for( std::map< int, std::map< Node, int > >::iterator it = d_curr_var_deq.begin(); it != d_curr_var_deq.end(); ++it ){\r
+        for( std::map< Node, 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
+\r
 bool QuantConflictFind::QuantInfo::setMatch( QuantConflictFind * p, int v, Node 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
@@ -1162,7 +984,7 @@ bool QuantConflictFind::QuantInfo::isMatchSpurious( QuantConflictFind * p ) {
   for( int i=0; i<getNumVars(); i++ ){\r
     std::map< int, Node >::iterator it = d_match.find( i );\r
     if( it!=d_match.end() ){\r
-      if( !getCurrentCanBeEqual( p, i, it->second ) ){\r
+      if( !getCurrentCanBeEqual( p, i, it->second, p->d_effort==QuantConflictFind::effort_conflict ) ){\r
         return true;\r
       }\r
     }\r
@@ -1190,42 +1012,62 @@ bool QuantConflictFind::QuantInfo::completeMatch( QuantConflictFind * p, Node q,
       Trace("qcf-check") << "Assign to unassigned, rep = " << r << "..." << std::endl;\r
       int index = 0;\r
       std::vector< int > eqc_count;\r
+      bool doFail = false;\r
       do {\r
-        bool invalidMatch;\r
-        while( ( index>=0 && (int)index<(int)unassigned[r].size() ) || invalidMatch ){\r
+        bool invalidMatch = false;\r
+        while( ( index>=0 && (int)index<(int)unassigned[r].size() ) || invalidMatch || doFail ){\r
           invalidMatch = false;\r
-          if( index==(int)eqc_count.size() ){\r
+          if( !doFail && index==(int)eqc_count.size() ){\r
             //check if it has now been assigned\r
             if( r==0 ){\r
-              d_var_mg[ unassigned[r][index] ]->reset( p, true, q );\r
+              if( !isConstrainedVar( unassigned[r][index] ) ){\r
+                eqc_count.push_back( -1 );\r
+              }else{\r
+                d_var_mg[ unassigned[r][index] ]->reset( p, true, q );\r
+                eqc_count.push_back( 0 );\r
+              }\r
+            }else{\r
+              eqc_count.push_back( 0 );\r
             }\r
-            eqc_count.push_back( 0 );\r
           }else{\r
             if( r==0 ){\r
-              if( d_var_mg[unassigned[r][index]]->getNextMatch( p, q ) ){\r
-                Trace("qcf-check-unassign") << "Succeeded match with mg" << std::endl;\r
+              if( !doFail && !isConstrainedVar( unassigned[r][index] ) ){\r
+                Trace("qcf-check-unassign") << "Succeeded, variable unconstrained at " << index << std::endl;\r
+                index++;\r
+              }else if( !doFail && d_var_mg[unassigned[r][index]]->getNextMatch( p, q ) ){\r
+                Trace("qcf-check-unassign") << "Succeeded match with mg at " << index << std::endl;\r
                 index++;\r
               }else{\r
-                Trace("qcf-check-unassign") << "Failed match with mg" << std::endl;\r
-                eqc_count.pop_back();\r
-                index--;\r
+                Trace("qcf-check-unassign") << "Failed match with mg at " << index << std::endl;\r
+                do{\r
+                  if( !doFail ){\r
+                    eqc_count.pop_back();\r
+                  }else{\r
+                    doFail = false;\r
+                  }\r
+                  index--;\r
+                }while( index>=0 && eqc_count[index]==-1 );\r
               }\r
             }else{\r
               Assert( index==(int)eqc_count.size()-1 );\r
-              if( eqc_count[index]<(int)p->d_eqcs[unassigned_tn[r][index]].size() ){\r
+              if( !doFail && eqc_count[index]<(int)p->d_eqcs[unassigned_tn[r][index]].size() ){\r
                 int currIndex = eqc_count[index];\r
                 eqc_count[index]++;\r
                 Trace("qcf-check-unassign") << unassigned[r][index] << "->" << p->d_eqcs[unassigned_tn[r][index]][currIndex] << std::endl;\r
                 if( setMatch( p, unassigned[r][index], p->d_eqcs[unassigned_tn[r][index]][currIndex] ) ){\r
-                  Trace("qcf-check-unassign") << "Succeeded match" << std::endl;\r
+                  Trace("qcf-check-unassign") << "Succeeded match " << index << std::endl;\r
                   index++;\r
                 }else{\r
-                  Trace("qcf-check-unassign") << "Failed match" << std::endl;\r
+                  Trace("qcf-check-unassign") << "Failed match " << index << std::endl;\r
                   invalidMatch = true;\r
                 }\r
               }else{\r
-                Trace("qcf-check-unassign") << "No more matches" << std::endl;\r
-                eqc_count.pop_back();\r
+                Trace("qcf-check-unassign") << "No more matches " << index << std::endl;\r
+                if( !doFail ){\r
+                  eqc_count.pop_back();\r
+                }else{\r
+                  doFail = false;\r
+                }\r
                 index--;\r
               }\r
             }\r
@@ -1233,11 +1075,13 @@ bool QuantConflictFind::QuantInfo::completeMatch( QuantConflictFind * p, Node q,
         }\r
         success = index>=0;\r
         if( success ){\r
-          index = (int)unassigned[r].size()-1;\r
+          doFail = true;\r
           Trace("qcf-check-unassign") << "  Try: " << std::endl;\r
           for( unsigned i=0; i<unassigned[r].size(); i++ ){\r
             int ui = unassigned[r][i];\r
-            Trace("qcf-check-unassign") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;\r
+            if( d_match.find( ui )!=d_match.end() ){\r
+              Trace("qcf-check-unassign") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;\r
+            }\r
           }\r
         }\r
       }while( success && isMatchSpurious( p ) );\r
@@ -1289,11 +1133,23 @@ QuantConflictFind::MatchGen::MatchGen( QuantConflictFind * p, Node q, Node n, bo
   if( isVar ){\r
     Assert( p->d_qinfo[q].d_var_num.find( n )!=p->d_qinfo[q].d_var_num.end() );\r
     if( p->isHandledUfTerm( n ) ){\r
+      d_qni_var_num[0] = p->d_qinfo[q].getVarNum( n );\r
+      d_qni_size++;\r
       d_type = typ_var;\r
-      //d_type_not = true;  //implicit disequality, in disjunction at top level\r
       d_type_not = false;\r
       d_n = n;\r
-      qni_apps.push_back( 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( p->d_qinfo[q].isVar( nn ) ){\r
+          Trace("qcf-qregister-debug") << " is var #" << p->d_qinfo[q].d_var_num[nn] << std::endl;\r
+          d_qni_var_num[d_qni_size] = p->d_qinfo[q].d_var_num[nn];\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
     }else{\r
       //for now, unknown term\r
       d_type = typ_invalid;\r
@@ -1305,13 +1161,15 @@ QuantConflictFind::MatchGen::MatchGen( QuantConflictFind * p, Node q, Node n, bo
       d_type_not = n.getKind()==NOT;\r
       if( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF || d_n.getKind()==ITE ){\r
         //non-literals\r
-        d_type = typ_valid;\r
+        d_type = typ_formula;\r
         for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
           d_children.push_back( MatchGen( p, q, d_n[i] ) );\r
           if( d_children[d_children.size()-1].d_type==typ_invalid ){\r
             setInvalid();\r
             break;\r
-          }else if( isTop && n.getKind()==OR && d_children[d_children.size()-1].d_type==typ_var_eq ){\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
@@ -1329,39 +1187,21 @@ QuantConflictFind::MatchGen::MatchGen( QuantConflictFind * p, Node q, Node n, bo
             }\r
             d_children.pop_back();\r
           }\r
+          */\r
         }\r
       }else{\r
         d_type = typ_invalid;\r
         //literals\r
-        if( d_n.getKind()==APPLY_UF || d_n.getKind()==EQUAL ){\r
-          //get the applications (in order) that will be matching\r
-          p->getEqRegistryApps( d_n, qni_apps );\r
-          bool isValid = true;\r
-          if( qni_apps.size()>0 ){\r
-            for( unsigned i=0; i<qni_apps.size(); i++ ){\r
-              if( !p->isHandledUfTerm( qni_apps[i] ) ){\r
-                //for now, cannot handle anything besides uf\r
-                isValid = false;\r
-                qni_apps.clear();\r
-                break;\r
-              }\r
-            }\r
-            if( isValid ){\r
-              d_type = typ_valid_lit;\r
-            }\r
-          }else if( d_n.getKind()==EQUAL ){\r
-            for( unsigned i=0; i<2; i++ ){\r
-              if( quantifiers::TermDb::hasBoundVarAttr( d_n[i] ) && !p->d_qinfo[q].isVar( d_n[i] ) ){\r
-                isValid = false;\r
-                break;\r
-              }\r
-            }\r
-            if( isValid ){\r
-              Assert( p->d_qinfo[q].isVar( d_n[0] ) || p->d_qinfo[q].isVar( d_n[1] ) );\r
-              // variable equality\r
-              d_type = typ_var_eq;\r
+        if( d_n.getKind()==APPLY_UF ){\r
+          Assert( p->d_qinfo[q].isVar( d_n ) );\r
+          d_type = typ_pred;\r
+        }else if( d_n.getKind()==EQUAL ){\r
+          for( unsigned i=0; i<2; i++ ){\r
+            if( quantifiers::TermDb::hasBoundVarAttr( d_n[i] ) ){\r
+              Assert( p->d_qinfo[q].isVar( d_n[i] ) );\r
             }\r
           }\r
+          d_type = typ_eq;\r
         }\r
       }\r
     }else{\r
@@ -1384,37 +1224,33 @@ QuantConflictFind::MatchGen::MatchGen( QuantConflictFind * p, Node q, Node n, bo
       //}\r
     //}\r
   }\r
-  if( d_type!=typ_invalid ){\r
-    if( !qni_apps.empty() ){\r
-      Trace("qcf-qregister-debug") << "Initialize matching..." << std::endl;\r
-      for( unsigned i=0; i<qni_apps.size(); i++ ){\r
-        for( unsigned j=0; j<qni_apps[i].getNumChildren(); j++ ){\r
-          Node nn = qni_apps[i][j];\r
-          Trace("qcf-qregister-debug") << "  " << d_qni_size;\r
-          if( p->d_qinfo[q].isVar( nn ) ){\r
-            Trace("qcf-qregister-debug") << " is var #" << p->d_qinfo[q].d_var_num[nn] << std::endl;\r
-            d_qni_var_num[d_qni_size] = p->d_qinfo[q].d_var_num[nn];\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
-    }\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 QuantConflictFind::MatchGen::reset_round( QuantConflictFind * p ) {\r
+  for( unsigned i=0; i<d_children.size(); i++ ){\r
+    d_children[i].reset_round( p );\r
+  }\r
   for( std::map< int, Node >::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
-  for( unsigned i=0; i<d_children.size(); i++ ){\r
-    d_children[i].reset_round( p );\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( !quantifiers::TermDb::hasBoundVarAttr( d_n[i] ) ){\r
+        d_ground_eval[i] = p->evaluateTerm( d_n[i] );\r
+      }\r
+    }\r
   }\r
 }\r
 \r
@@ -1430,63 +1266,67 @@ void QuantConflictFind::MatchGen::reset( QuantConflictFind * p, bool tgt, Node q
 \r
   //set up processing matches\r
   if( d_type==typ_ground ){\r
-    if( p->evaluate( d_n, d_tgt, true )==( d_tgt ? 1 : -1 ) ){\r
-      //store dummy variable\r
-      d_qn.push_back( NULL );\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_var ){\r
-    //check if variable is bound by now\r
-    int vi = p->d_qinfo[q].getVarNum( d_n );\r
-    Assert( vi!=-1 );\r
-    int repVar = p->d_qinfo[q].getCurrentRepVar( vi );\r
     Assert( p->isHandledUfTerm( d_n ) );\r
     Node f = d_n.getOperator();\r
-    std::map< int, Node >::iterator it = p->d_qinfo[q].d_match.find( repVar );\r
-    if( it!=p->d_qinfo[q].d_match.end() && d_tgt ) {\r
-      Debug("qcf-match") << "       will be matching var within eqc = " << it->second << std::endl;\r
-      //f-applications in the equivalence class in match[ repVar ]\r
-      QcfNodeIndex * qni = p->getQcfNodeIndex( it->second, f );\r
-      if( qni ){\r
-        d_qn.push_back( qni );\r
-      }\r
+    Debug("qcf-match-debug") << "       reset: Var will match operators of " << f << std::endl;\r
+    QcfNodeIndex * qni = p->getQcfNodeIndex( Node::null(), f );\r
+    if( qni!=NULL ){\r
+      d_qn.push_back( qni );\r
+    }\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] = p->d_qinfo[q].getCurrentValue( d_n );\r
+      vn[0] = p->d_qinfo[q].getCurrentRepVar( p->d_qinfo[q].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
-      Debug("qcf-match") << "       will be matching var within any eqc." << std::endl;\r
-      //we are binding rep var\r
-      d_qni_bound_cons[repVar] = Node::null();\r
-      //must look at all f-applications\r
-      QcfNodeIndex * qni = p->getQcfNodeIndex( f );\r
-      if( qni ){\r
-        d_qn.push_back( qni );\r
+      for( unsigned i=0; i<2; i++ ){\r
+        nn[i] = p->d_qinfo[q].getCurrentValue( d_n[i] );\r
+        vn[i] = p->d_qinfo[q].getCurrentRepVar( p->d_qinfo[q].getVarNum( nn[i] ) );\r
       }\r
     }\r
-  }else if( d_type==typ_var_eq ){\r
-    bool success = false;\r
-    for( unsigned i=0; i<2; i++ ){\r
-      int var = p->d_qinfo[q].getVarNum( d_n[i] );\r
-      if( var!=-1 ){\r
-        int repVar = p->d_qinfo[q].getCurrentRepVar( var );\r
-        Node o = d_n[ i==0 ? 1 : 0 ];\r
-        o = p->d_qinfo[q].getCurrentValue( o );\r
-        int vo = p->d_qinfo[q].getCurrentRepVar( p->d_qinfo[q].getVarNum( o ) );\r
-        int addCons = p->d_qinfo[q].addConstraint( p, repVar, o, vo, d_tgt, false );\r
-        success = addCons!=-1;\r
-        //if successful and non-redundant, store that we need to cleanup this\r
-        if( addCons==1 ){\r
-          d_qni_bound_cons[repVar] = o;\r
-          d_qni_bound[repVar] = vo;\r
+    bool success;\r
+    if( vn[0]==-1 && vn[1]==-1 ){\r
+      Debug("qcf-match-debug") << "       reset: check ground values " << nn[0] << " " << nn[1] << " (" << d_tgt << ")" << std::endl;\r
+      //just compare values\r
+      success = d_tgt ? p->areMatchEqual( nn[0], nn[1] ) : p->areMatchDisequal( nn[0], nn[1] );\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 = p->d_qinfo[q].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
+        for( unsigned i=0; i<2; i++ ){\r
+          if( vn[i]!=-1 ){\r
+            d_qni_bound[vn[i]] = vn[i];\r
+          }\r
         }\r
-        break;\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
-      //store dummy\r
       d_qn.push_back( NULL );\r
     }\r
-  }else if( d_type==typ_valid_lit ){\r
-    //literal\r
-    EqRegistry * er = p->getEqRegistry( d_tgt, d_n, false );\r
-    Assert( er );\r
-    d_qn.push_back( &(er->d_qni) );\r
   }else{\r
     if( d_children.empty() ){\r
       //add dummy\r
@@ -1497,76 +1337,120 @@ void QuantConflictFind::MatchGen::reset( QuantConflictFind * p, bool tgt, Node q
       getChild( d_child_counter )->reset( p, d_tgt, q );\r
     }\r
   }\r
-  Debug("qcf-match") << "     Finished reset for " << d_n << ", success = " << ( !d_qn.empty() || d_child_counter!=-1 ) << std::endl;\r
+  d_binding = false;\r
+  Debug("qcf-match") << "     reset: Finished reset for " << d_n << ", success = " << ( !d_qn.empty() || d_child_counter!=-1 ) << std::endl;\r
 }\r
 \r
 bool QuantConflictFind::MatchGen::getNextMatch( QuantConflictFind * p, Node q ) {\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() << std::endl;\r
-  if( d_children.empty() ){\r
-    bool success = doMatching( p, q );\r
-    if( success ){\r
-      Debug("qcf-match") << "     Produce matches for bound variables..." << std::endl;\r
-\r
-      //also need to create match for each variable we bound\r
-      std::map< int, int >::iterator it = d_qni_bound.begin();\r
-      bool doReset = true;\r
-      while( success && it!=d_qni_bound.end() ){\r
-        std::map< int, MatchGen * >::iterator itm = p->d_qinfo[q].d_var_mg.find( it->second );\r
-        if( itm!=p->d_qinfo[q].d_var_mg.end() ){\r
-          Debug("qcf-match-debug") << "       process variable " << it->second << ", reset = " << doReset << std::endl;\r
-          if( doReset ){\r
-            itm->second->reset( p, true, q );\r
+  Debug("qcf-match") << ", children = " << d_children.size() << ", binding = " << d_binding << std::endl;\r
+  if( d_type==typ_ground ){\r
+    if( d_child_counter==0 ){\r
+      d_child_counter = -1;\r
+      return true;\r
+    }else{\r
+      return false;\r
+    }\r
+  }else if( d_type==typ_var || d_type==typ_eq || d_type==typ_pred ){\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, q ) ){\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
+        }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", 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 = p->d_qinfo[q].d_var_mg.find( d_binding_it->second );\r
           }\r
-          if( !itm->second->getNextMatch( p, q ) ){\r
-            do {\r
-              if( it==d_qni_bound.begin() ){\r
-                Debug("qcf-match-debug") << "       failed." << std::endl;\r
-                success = false;\r
-              }else{\r
-                Debug("qcf-match-debug") << "       decrement..." << std::endl;\r
-                --it;\r
-              }\r
-            }while( success && p->d_qinfo[q].d_var_mg.find( it->second )==p->d_qinfo[q].d_var_mg.end() );\r
-            doReset = false;\r
+          if( doFail || ( d_binding_it->first!=0 && itm!=p->d_qinfo[q].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, q );\r
+            }\r
+            if( doFail || !itm->second->getNextMatch( p, q ) ){\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
+                  Debug("qcf-match-debug") << "       decrement..." << std::endl;\r
+                  --d_binding_it;\r
+                }\r
+              }while( success && ( d_binding_it->first==0 || p->d_qinfo[q].d_var_mg.find( d_binding_it->second )==p->d_qinfo[q].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") << "       increment..." << std::endl;\r
-            ++it;\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
-          Debug("qcf-match-debug") << "       skip..." << std::endl;\r
-          ++it;\r
-          doReset = true;\r
+          terminate = true;\r
+          if( d_binding_it==d_qni_bound.begin() ){\r
+            d_binding = false;\r
+          }\r
         }\r
       }\r
-    }\r
+    }while( !terminate );\r
     //if not successful, clean up the variables you bound\r
     if( !success ){\r
-      for( std::map< int, Node >::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.find( it->first );\r
-          int vn = itb!=d_qni_bound.end() ? itb->second : -1;\r
-          p->d_qinfo[q].addConstraint( p, it->first, it->second, vn, d_tgt, true );\r
-          if( vn!=-1 ){\r
-            d_qni_bound.erase( vn );\r
+      if( d_type==typ_eq || d_type==typ_pred ){\r
+        for( std::map< int, Node >::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
+            p->d_qinfo[q].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 match : remove equalities/disequalities\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<p->d_qinfo[q].getNumVars() );\r
+          p->d_qinfo[q].d_match.erase( it->second );\r
+          p->d_qinfo[q].d_match_term.erase( it->second );\r
+        }\r
+        d_qni_bound.clear();\r
       }\r
-      d_qni_bound_cons.clear();\r
-      //clean up the match : remove equalities/disequalities\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<p->d_qinfo[q].getNumVars() );\r
-        p->d_qinfo[q].d_match.erase( it->second );\r
-      }\r
-      d_qni_bound.clear();\r
     }\r
     Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;\r
     return success;\r
-  }else{\r
+  }else if( d_type==typ_formula ){\r
     if( d_child_counter!=-1 ){\r
       bool success = false;\r
       while( !success && d_child_counter>=0 ){\r
@@ -1664,7 +1548,7 @@ bool QuantConflictFind::MatchGen::doMatching( QuantConflictFind * p, Node q ) {
       bool invalidMatch;\r
       do {\r
         invalidMatch = false;\r
-        Debug("qcf-match-debug") << "       Do matching " << d_qn.size() << " " << d_qni.size() << std::endl;\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
@@ -1721,7 +1605,6 @@ bool QuantConflictFind::MatchGen::doMatching( QuantConflictFind * p, Node q ) {
               Debug("qcf-match-debug") << "       Failed to match" << std::endl;\r
               d_qn.pop_back();\r
             }\r
-            //TODO : if it is equal to something else, also try that\r
           }\r
         }else{\r
           Assert( d_qn.size()==d_qni.size() );\r
@@ -1754,35 +1637,23 @@ bool QuantConflictFind::MatchGen::doMatching( QuantConflictFind * p, Node q ) {
             d_qni.pop_back();\r
           }\r
         }\r
-        if( d_type==typ_var ){\r
-          if( !invalidMatch && d_qni.size()==d_qni_size ){\r
-            //if in the act of binding the variable by this term, bind the variable\r
-            std::map< int, Node >::iterator itb = d_qni_bound_cons.begin();\r
-            if( itb!=d_qni_bound_cons.end() ){\r
-              QcfNodeIndex * v_qni = &d_qni[d_qni.size()-1]->second;\r
-              Assert( v_qni->d_children.begin()!=v_qni->d_children.end() );\r
-              Node vb = v_qni->d_children.begin()->first;\r
-              Assert( !vb.isNull() );\r
-              vb = p->getRepresentative( vb );\r
-              Debug("qcf-match-debug") << "       For var, require binding " << itb->first << " to " << vb << ", d_tgt = " << d_tgt << std::endl;\r
-              if( !itb->second.isNull() ){\r
-                p->d_qinfo[q].addConstraint( p, itb->first, itb->second, -1, d_tgt, true );\r
-              }\r
-              int addCons = p->d_qinfo[q].addConstraint( p, itb->first, vb, -1, d_tgt, false );\r
-              if( addCons==-1 ){\r
-                Debug("qcf-match-debug") << "       Failed set for var." << std::endl;\r
-                invalidMatch = true;\r
-                d_qni_bound_cons[itb->first] = Node::null();\r
-              }else{\r
-                Debug("qcf-match-debug") << "       Succeeded set for var." << std::endl;\r
-                if( addCons==1 ){\r
-                  d_qni_bound_cons[itb->first] = vb;\r
-                }\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_children.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_children.empty() );\r
+        Node t = d_qni[d_qni.size()-1]->second.d_children.begin()->first;\r
+        Debug("qcf-match-debug") << "       We matched " << t << std::endl;\r
+        //set the match terms\r
+        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){\r
+          if( it->second<(int)q[0].getNumChildren() ){   //if it is an actual variable, we are interested in knowing the actual term\r
+            Assert( it->first>0 );\r
+            Assert( p->d_qinfo[q].d_match.find( it->second )!=p->d_qinfo[q].d_match.end() );\r
+            Assert( p->areEqual( t[it->first-1], p->d_qinfo[q].d_match[ it->second ] ) );\r
+            p->d_qinfo[q].d_match_term[it->second] = t[it->first-1];\r
           }\r
         }\r
-      }while( ( !d_qn.empty() && d_qni.size()!=d_qni_size ) || invalidMatch );\r
+      }\r
     }\r
   }\r
   return !d_qn.empty();\r
@@ -1793,20 +1664,20 @@ void QuantConflictFind::MatchGen::debugPrintType( const char * c, short typ, boo
     switch( typ ){\r
     case typ_invalid: Trace(c) << "invalid";break;\r
     case typ_ground: Trace(c) << "ground";break;\r
-    case typ_valid_lit: Trace(c) << "valid_lit";break;\r
-    case typ_valid: Trace(c) << "valid";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_var_eq: Trace(c) << "var_eq";break;\r
     case typ_top: Trace(c) << "top";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_valid_lit: Debug(c) << "valid_lit";break;\r
-    case typ_valid: Debug(c) << "valid";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_var_eq: Debug(c) << "var_eq";break;\r
     case typ_top: Debug(c) << "top";break;\r
     }\r
   }\r
@@ -1827,79 +1698,36 @@ void QuantConflictFind::debugPrint( const char * c ) {
   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
+    //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
-        ++eqc_i;\r
       }\r
       Trace(c) << (pr ? " " : "" ) << "}" << std::endl;\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
+    */\r
     ++eqcs_i;\r
   }\r
-  std::map< Node, std::map< Node, bool > > printed;\r
-  //print the equality registries\r
-  for( unsigned i=0; i<2; i++ ){\r
-    printed.clear();\r
-    Trace(c) << "----------EQR, polarity = " << (i==0) << std::endl;\r
-    for( unsigned j=0; j<2; j++ ){\r
-      for( std::map< TNode, std::map< int, std::map< TNode, EqRegistry * > > >::iterator it = d_eqr[i][j].begin(); it != d_eqr[i][j].end(); ++it ){\r
-        bool prHead = false;\r
-        for( unsigned jj=0; jj<2; jj++ ){\r
-          for( std::map< TNode, EqRegistry * >::iterator it2 = it->second[jj].begin(); it2 != it->second[jj].end(); ++it2 ){\r
-            bool print;\r
-            if( isHandledUfTerm( it->first ) && isHandledUfTerm( it2->first ) &&\r
-                it->first.getOperator()!=it2->first.getOperator() ){\r
-              print = isLessThan( it->first.getOperator(), it2->first.getOperator() );\r
-            }else{\r
-              print = printed[it->first].find( it2->first )==printed[it->first].end();\r
-            }\r
-            if( print ){\r
-              printed[it->first][it2->first] = true;\r
-              printed[it2->first][it->first] = true;\r
-              if( !prHead ){\r
-                Trace(c) << "- " << it->first << std::endl;\r
-                prHead = true;\r
-              }\r
-              Trace(c) << "    " << it2->first << ", terms : " << std::endl;\r
-\r
-              /*\r
-              Trace(c) << "    " << it2->first << " : {";\r
-              bool pr = false;\r
-              for( NodeBoolMap::iterator it3 = it2->second->d_t_eqc.begin(); it3 != it2->second->d_t_eqc.end(); ++it3 ){\r
-                if( (*it3).second ){\r
-                  Trace(c) << (pr ? "," : "" ) << " " << (*it3).first;\r
-                  pr = true;\r
-                }\r
-              }\r
-              Trace(c) << (pr ? " " : "" ) << "}" << std::endl;\r
-              */\r
-              //print qni structure\r
-              it2->second->debugPrint( c, 3 );\r
-            }\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
 }\r
 \r
 void QuantConflictFind::debugPrintQuant( const char * c, Node q ) {\r
index 15923b0badf83ebd61edc815e435e4c1b73d3bd7..d8fe1e8083f0ab00a0cfa045584dbc8c8fa08d14 100755 (executable)
@@ -33,46 +33,11 @@ class QcfNodeIndex {
 public:\r
   std::map< TNode, QcfNodeIndex > d_children;\r
   void clear() { d_children.clear(); }\r
-  //Node existsTerm( QuantConflictFind * qcf, Node n, int index = 0 );\r
-  //Node addTerm( QuantConflictFind * qcf, Node n, int index = 0 );\r
-  //bool addTermEq( QuantConflictFind * qcf, Node n1, Node n2, int index = 0 );\r
   void debugPrint( const char * c, int t );\r
-  //optimized versions\r
   Node existsTerm( TNode n, std::vector< TNode >& reps, int index = 0 );\r
   Node addTerm( TNode n, std::vector< TNode >& reps, int index = 0 );\r
-  bool addTermEq( TNode n1, TNode n2, std::vector< TNode >& reps1, std::vector< TNode >& reps2, int index = 0 );\r
 };\r
 \r
-class EqRegistry {\r
-  typedef context::CDChunkList<Node> NodeList;\r
-  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;\r
-public:\r
-  EqRegistry( context::Context* c );\r
-  //active\r
-  context::CDO< bool > d_active;\r
-  //NodeIndex describing pairs that meet the criteria of the EqRegistry\r
-  QcfNodeIndex d_qni;\r
-\r
-  //qcf nodes that this helps to 1:satisfy -1:falsify 0:both a quantifier conflict node\r
-  //std::map< QcfNode *, int > d_qcf;\r
-  //has eqc\r
-  //bool hasEqc( Node n ) { return d_t_eqc.find( n )!=d_t_eqc.end() && d_t_eqc[n]; }\r
-  //void setEqc( Node n, bool val = true ) { d_t_eqc[n] = val; }\r
-  void clear() { d_qni.clear(); }\r
-  void debugPrint( const char * c, int t );\r
-};\r
-\r
-/*\r
-class QcfNode {\r
-public:\r
-  QcfNode( context::Context* c );\r
-  QcfNode * d_parent;\r
-  std::map< int, QcfNode * > d_child;\r
-  Node d_node;\r
-  EqRegistry * d_reg[2];\r
-};\r
-*/\r
-\r
 class QuantConflictFind : public QuantifiersModule\r
 {\r
   friend class QcfNodeIndex;\r
@@ -86,21 +51,16 @@ private:
   void registerNode( Node q, Node n, bool hasPol, bool pol );\r
   void flatten( Node q, Node n );\r
 private:\r
-  std::map< TypeNode, Node > d_fv;\r
-  Node getFv( TypeNode tn );\r
   std::map< Node, Node > d_op_node;\r
-  int getFunctionId( Node f );\r
-  bool isLessThan( Node a, Node b );\r
   Node getFunction( Node n, int& index, bool isQuant = false );\r
   int d_fid_count;\r
   std::map< Node, int > d_fid;\r
   Node mkEqNode( Node a, Node b );\r
-private:  //for ground terms\r
+public:  //for ground terms\r
   Node d_true;\r
   Node d_false;\r
-  std::map< int, std::map< TNode, std::map< int, std::map< TNode, EqRegistry * > > > > d_eqr[2];\r
-  EqRegistry * getEqRegistry( bool polarity, Node lit, bool doCreate = true );\r
-  void getEqRegistryApps( Node lit, std::vector< Node >& terms );\r
+private:\r
+  Node evaluateTerm( Node n );\r
   int evaluate( Node n, bool pref = false, bool hasPref = false );\r
 public:  //for quantifiers\r
   //match generator\r
@@ -124,14 +84,19 @@ public:  //for quantifiers
     std::map< int, Node > d_qni_gterm_rep;\r
     std::map< int, int > d_qni_bound;\r
     std::map< int, Node > d_qni_bound_cons;\r
+    std::map< int, int > d_qni_bound_cons_var;\r
+    std::map< int, int >::iterator d_binding_it;\r
+    bool d_binding;\r
+    //int getVarBindingVar();\r
+    std::map< int, Node > d_ground_eval;\r
   public:\r
     //type of the match generator\r
     enum {\r
       typ_invalid,\r
       typ_ground,\r
-      typ_var_eq,\r
-      typ_valid_lit,\r
-      typ_valid,\r
+      typ_pred,\r
+      typ_eq,\r
+      typ_formula,\r
       typ_var,\r
       typ_top,\r
     };\r
@@ -159,7 +124,7 @@ private:
     QuantInfo() : d_mg( NULL ) {}\r
     std::vector< Node > d_vars;\r
     std::map< Node, int > d_var_num;\r
-    std::map< EqRegistry *, bool > d_rel_eqr;\r
+    //std::map< EqRegistry *, bool > d_rel_eqr;\r
     std::map< int, std::vector< Node > > d_var_constraint[2];\r
     int getVarNum( Node v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }\r
     bool isVar( Node v ) { return d_var_num.find( v )!=d_var_num.end(); }\r
@@ -171,16 +136,18 @@ private:
   public:\r
     //current constraints\r
     std::map< int, Node > d_match;\r
+    std::map< int, Node > d_match_term;\r
     std::map< int, std::map< Node, int > > d_curr_var_deq;\r
     int getCurrentRepVar( int v );\r
     Node getCurrentValue( Node n );\r
-    bool getCurrentCanBeEqual( QuantConflictFind * p, int v, Node n );\r
+    bool getCurrentCanBeEqual( QuantConflictFind * p, int v, Node n, bool chDiseq = false );\r
     int addConstraint( QuantConflictFind * p, int v, Node n, bool polarity );\r
     int addConstraint( QuantConflictFind * p, int v, Node n, int vn, bool polarity, bool doRemove );\r
     bool setMatch( QuantConflictFind * p, int v, Node n );\r
     bool isMatchSpurious( QuantConflictFind * p );\r
     bool completeMatch( QuantConflictFind * p, Node q, std::vector< int >& assigned );\r
     void debugPrintMatch( const char * c );\r
+    bool isConstrainedVar( int v );\r
   };\r
   std::map< Node, QuantInfo > d_qinfo;\r
 private:  //for equivalence classes\r
@@ -188,8 +155,8 @@ private:  //for equivalence classes
   bool areDisequal( Node n1, Node n2 );\r
   bool areEqual( Node n1, Node n2 );\r
   Node getRepresentative( Node n );\r
-  Node getTerm( Node n );\r
 \r
+/*\r
   class EqcInfo {\r
   public:\r
     EqcInfo( context::Context* c ) : d_diseq( c ) {}\r
@@ -200,10 +167,12 @@ private:  //for equivalence classes
   };\r
   std::map< Node, EqcInfo * > d_eqc_info;\r
   EqcInfo * getEqcInfo( Node n, bool doCreate = true );\r
+*/\r
   // operator -> index(terms)\r
   std::map< TNode, QcfNodeIndex > d_uf_terms;\r
-  // eqc x operator -> index(terms)\r
-  std::map< TNode, std::map< TNode, QcfNodeIndex > > d_eqc_uf_terms;\r
+  // operator -> index(eqc -> terms)\r
+  std::map< TNode, QcfNodeIndex > d_eqc_uf_terms;\r
+  //get qcf node index\r
   QcfNodeIndex * getQcfNodeIndex( Node eqc, Node f );\r
   QcfNodeIndex * getQcfNodeIndex( Node f );\r
   // type -> list(eqc)\r
@@ -217,7 +186,8 @@ private:  //for equivalence classes
 public:\r
   enum {\r
     effort_conflict,\r
-    effort_propagation,\r
+    effort_prop_eq,\r
+    effort_prop_deq,\r
   };\r
   short d_effort;\r
   //for effort_prop\r
index 3a6785d009add2b3050d1ccdf171ec6ea69e81be..ac847678d4f635ea99c7cad6926a11da9572cf6e 100644 (file)
@@ -269,7 +269,7 @@ Node QuantifiersRewriter::computeNNF( Node body ){
           children.push_back( computeNNF( body[0][i].notNode() ) );
         }
         k = body[0].getKind()==AND ? OR : AND;
-      }else if( body[0].getKind()==XOR || body[0].getKind()==IFF ){
+      }else if( body[0].getKind()==IFF ){
         for( int i=0; i<2; i++ ){
           Node nn = i==0 ? body[0][i] : body[0][i].notNode();
           children.push_back( computeNNF( nn ) );