More optimization of QCF. Fixed InstMatchTrie for caching instantiations. Use non...
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Sun, 26 Jan 2014 20:23:51 +0000 (14:23 -0600)
committerAndrew Reynolds <andrew.j.reynolds@gmail.com>
Sun, 26 Jan 2014 20:24:02 +0000 (14:24 -0600)
15 files changed:
src/theory/quantifiers/inst_match.cpp
src/theory/quantifiers/inst_match.h
src/theory/quantifiers/inst_strategy_e_matching.cpp
src/theory/quantifiers/inst_strategy_e_matching.h
src/theory/quantifiers/instantiation_engine.cpp
src/theory/quantifiers/model_engine.cpp
src/theory/quantifiers/model_engine.h
src/theory/quantifiers/options
src/theory/quantifiers/quant_conflict_find.cpp
src/theory/quantifiers/quant_conflict_find.h
src/theory/quantifiers/relevant_domain.cpp
src/theory/quantifiers/relevant_domain.h
src/theory/quantifiers_engine.cpp
src/theory/quantifiers_engine.h
test/regress/regress0/quantifiers/Makefile.am

index ebe58776504131b4ce5cf27265cf92b00ecb22f4..8428069aae6b49e2d724fa32fc4468235322719e 100644 (file)
@@ -158,7 +158,10 @@ void InstMatch::set( QuantifiersEngine* qe, Node f, int i, TNode n ) {
   set( qe->getTermDatabase()->getInstantiationConstant( f, i ), n );
 }
 
-/** add match m for quantifier f starting at index, take into account equalities q, return true if successful */
+
+
+
+/*
 void InstMatchTrie::addInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, int index, ImtIndexOrder* imtio ){
   if( long(index)<long(f[0].getNumChildren()) && ( !imtio || long(index)<long(imtio->d_order.size()) ) ){
     int i_index = imtio ? imtio->d_order[index] : index;
@@ -167,7 +170,6 @@ void InstMatchTrie::addInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m,
   }
 }
 
-/** exists match */
 bool InstMatchTrie::existsInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, bool modInst, int index, ImtIndexOrder* imtio ){
   if( long(index)==long(f[0].getNumChildren()) || ( imtio && long(index)==long(imtio->d_order.size()) ) ){
     return true;
@@ -227,49 +229,96 @@ bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, b
     return false;
   }
 }
+*/
 
 
 
-/** add match m for quantifier f starting at index, take into account equalities q, return true if successful */
-void CDInstMatchTrie::addInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, int index, ImtIndexOrder* imtio ){
-  if( long(index)<long(f[0].getNumChildren()) && ( !imtio || long(index)<long(imtio->d_order.size()) ) ){
+
+bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, bool modInst, ImtIndexOrder* imtio, bool onlyExist, int index ){
+  if( index==(int)f[0].getNumChildren() || ( imtio && index==(int)imtio->d_order.size() ) ){
+    return false;
+  }else{
     int i_index = imtio ? imtio->d_order[index] : index;
     Node n = m.getValue( qe->getTermDatabase()->getInstantiationConstant( f, i_index ) );
-    std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
+    std::map< Node, InstMatchTrie >::iterator it = d_data.find( n );
     if( it!=d_data.end() ){
-      it->second->addInstMatch2( qe, f, m, c, index+1, imtio );
+      return it->second.addInstMatch( qe, f, m, modEq, modInst, imtio, onlyExist, index+1 );
     }else{
-      CDInstMatchTrie* imt = new CDInstMatchTrie( c );
-      d_data[n] = imt;
-      imt->d_valid = true;
-      imt->addInstMatch2( qe, f, m, c, index+1, imtio );
+
+      /*
+      //check if m is an instance of another instantiation if modInst is true
+      if( modInst ){
+        if( !n.isNull() ){
+          Node nl;
+          std::map< Node, InstMatchTrie >::iterator itm = d_data.find( nl );
+          if( itm!=d_data.end() ){
+            if( !itm->second.addInstMatch( qe, f, m, modEq, modInst, imtio, true, index+1 ) ){
+              return false;
+            }
+          }
+        }
+      }
+      */
+      /*
+      if( modEq ){
+        //check modulo equality if any other instantiation match exists
+        if( !n.isNull() && qe->getEqualityQuery()->getEngine()->hasTerm( n ) ){
+          eq::EqClassIterator eqc( qe->getEqualityQuery()->getEngine()->getRepresentative( n ),
+                                   qe->getEqualityQuery()->getEngine() );
+          while( !eqc.isFinished() ){
+            Node en = (*eqc);
+            if( en!=n ){
+              std::map< Node, InstMatchTrie >::iterator itc = d_data.find( en );
+              if( itc!=d_data.end() ){
+                if( itc->second.addInstMatch( qe, f, m, modEq, modInst, imtio, true, index+1 ) ){
+                  return false;
+                }
+              }
+            }
+            ++eqc;
+          }
+        }
+      }
+      */
+      if( !onlyExist ){
+        d_data[n].addInstMatch( qe, f, m, modEq, modInst, imtio, false, index+1 );
+      }
+      return true;
     }
   }
 }
 
+
+
 /** exists match */
-bool CDInstMatchTrie::existsInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, bool modInst, int index, ImtIndexOrder* imtio ){
-  if( !d_valid ){
-    return false;
-  }else if( long(index)==long(f[0].getNumChildren()) || ( imtio && long(index)==long(imtio->d_order.size()) ) ){
+bool CDInstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, bool modEq, bool modInst, int index, bool onlyExist ){
+  if( !d_valid.get() ){
+    if( onlyExist ){
+      return false;
+    }else{
+      d_valid.set( true );
+    }
+  }
+  if( index==(int)f[0].getNumChildren() ){
     return true;
   }else{
-    int i_index = imtio ? imtio->d_order[index] : index;
-    Node n = m.getValue( qe->getTermDatabase()->getInstantiationConstant( f, i_index ) );
-    std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
-    if( it!=d_data.end() ){
-      if( it->second->existsInstMatch2( qe, f, m, modEq, modInst, index+1, imtio ) ){
-        return true;
+    Node n = m.getValue( qe->getTermDatabase()->getInstantiationConstant( f, index ) );
+    if( onlyExist ){
+      std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
+      if( it!=d_data.end() ){
+        if( !it->second->addInstMatch( qe, f, m, c, modEq, modInst, index+1, true ) ){
+          return false;
+        }
       }
     }
     //check if m is an instance of another instantiation if modInst is true
     if( modInst ){
       if( !n.isNull() ){
         Node nl;
-        it = d_data.find( nl );
-        if( it!=d_data.end() ){
-          if( it->second->existsInstMatch2( qe, f, m, modEq, modInst, index+1, imtio ) ){
-            return true;
+        std::map< Node, CDInstMatchTrie* >::iterator itm = d_data.find( nl );
+        if( itm!=d_data.end() ){
+          if( !itm->second->addInstMatch( qe, f, m, c, modEq, modInst, index+1, true ) ){
+            return false;
           }
         }
       }
@@ -284,8 +333,8 @@ bool CDInstMatchTrie::existsInstMatch2( QuantifiersEngine* qe, Node f, InstMatch
           if( en!=n ){
             std::map< Node, CDInstMatchTrie* >::iterator itc = d_data.find( en );
             if( itc!=d_data.end() ){
-              if( itc->second->existsInstMatch2( qe, f, m, modEq, modInst, index+1, imtio ) ){
-                return true;
+              if( itc->second->addInstMatch( qe, f, m, c, modEq, modInst, index+1, true ) ){
+                return false;
               }
             }
           }
@@ -293,24 +342,22 @@ bool CDInstMatchTrie::existsInstMatch2( QuantifiersEngine* qe, Node f, InstMatch
         }
       }
     }
+    if( !onlyExist ){
+      std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
+      CDInstMatchTrie* imt;
+      if( it!=d_data.end() ){
+        imt = it->second;
+        it->second->d_valid.set( true );
+      }else{
+        imt = new CDInstMatchTrie( c );
+        d_data[n] = imt;
+      }
+      return imt->addInstMatch( qe, f, m, c, modEq, modInst, index+1, false );
+    }
     return false;
   }
 }
 
-bool CDInstMatchTrie::existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, bool modInst, ImtIndexOrder* imtio ){
-  return existsInstMatch2( qe, f, m, modEq, modInst, 0, imtio );
-}
-
-bool CDInstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, Context* c, bool modEq, bool modInst, ImtIndexOrder* imtio ){
-  if( !existsInstMatch( qe, f, m, modEq, modInst, imtio ) ){
-    addInstMatch2( qe, f, m, c, 0, imtio );
-    return true;
-  }else{
-    return false;
-  }
-}
-
-
 }/* CVC4::theory::inst namespace */
 }/* CVC4::theory namespace */
 }/* CVC4 namespace */
index 72447fd662e0d44cd14ae4c00367d6cc41277fa5..2cf33bc8e584c28cc16b97a5675cfe63c285807b 100644 (file)
@@ -119,11 +119,6 @@ public:
   public:
     std::vector< int > d_order;
   };/* class InstMatchTrie ImtIndexOrder */
-private:
-  /** add match m for quantifier f starting at index, take into account equalities q, return true if successful */
-  void addInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, int index, ImtIndexOrder* imtio );
-  /** exists match */
-  bool existsInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, bool modInst, int index, ImtIndexOrder* imtio );
 public:
   /** the data */
   std::map< Node, InstMatchTrie > d_data;
@@ -136,16 +131,20 @@ public:
         modInst is if we return true if m is an instance of a match that exists
    */
   bool existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false,
-                        bool modInst = false, ImtIndexOrder* imtio = NULL );
+                        bool modInst = false, ImtIndexOrder* imtio = NULL, int index = 0 ) {
+    return !addInstMatch( qe, f, m, modEq, modInst, imtio, true, index );
+  }
   /** add match m for quantifier f, take into account equalities if modEq = true,
       if imtio is non-null, this is the order to add to trie
       return true if successful
   */
   bool addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false,
-                     bool modInst = false, ImtIndexOrder* imtio = NULL );
+                     bool modInst = false, ImtIndexOrder* imtio = NULL, bool onlyExist = false, int index = 0 );
 };/* class InstMatchTrie */
 
 
+#if 0
+
 /** trie for InstMatch objects */
 class CDInstMatchTrie {
 public:
@@ -181,6 +180,37 @@ public:
                      bool modInst = false, ImtIndexOrder* imtio = NULL );
 };/* class CDInstMatchTrie */
 
+#else
+
+
+/** trie for InstMatch objects */
+class CDInstMatchTrie {
+public:
+  /** the data */
+  std::map< Node, CDInstMatchTrie* > d_data;
+  /** is valid */
+  context::CDO< bool > d_valid;
+public:
+  CDInstMatchTrie( context::Context* c ) : d_valid( c, false ){}
+  ~CDInstMatchTrie(){}
+public:
+  /** return true if m exists in this trie
+        modEq is if we check modulo equality
+        modInst is if we return true if m is an instance of a match that exists
+   */
+  bool existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, bool modEq = false,
+                        bool modInst = false, int index = 0 ) {
+    return !addInstMatch( qe, f, m, c, modEq, modInst, index, true );
+  }
+  /** add match m for quantifier f, take into account equalities if modEq = true,
+      if imtio is non-null, this is the order to add to trie
+      return true if successful
+  */
+  bool addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, bool modEq = false,
+                     bool modInst = false, int index = 0, bool onlyExist = false );
+};/* class CDInstMatchTrie */
+
+
 class InstMatchTrieOrdered{
 private:
   InstMatchTrie::ImtIndexOrder* d_imtio;
@@ -202,6 +232,9 @@ public:
   }
 };/* class InstMatchTrieOrdered */
 
+#endif
+
+
 }/* CVC4::theory::inst namespace */
 
 typedef CVC4::theory::inst::InstMatch InstMatch;
index 9acdf61522815c492c584bf7ac1d39698c60f1e9..6a9327967d77c1fbd7be9d6744e1dfdda2bad766 100644 (file)
@@ -18,6 +18,7 @@
 #include "theory/quantifiers/options.h"
 #include "theory/quantifiers/term_database.h"
 #include "theory/quantifiers/inst_match_generator.h"
+#include "theory/quantifiers/relevant_domain.h"
 
 using namespace std;
 using namespace CVC4;
@@ -60,6 +61,8 @@ int InstStrategyUserPatterns::process( Node f, Theory::Effort effort, int e ){
     return STATUS_UNFINISHED;
   }else if( e==1 ){
     d_counter[f]++;
+      Trace("inst-alg") << "-> User-provided instantiate " << f << "..." << std::endl;
+
     Debug("quant-uf-strategy") << "Try user-provided patterns..." << std::endl;
     //Notice() << "Try user-provided patterns..." << std::endl;
     for( int i=0; i<(int)d_user_gen[f].size(); i++ ){
@@ -150,6 +153,7 @@ int InstStrategyAutoGenTriggers::process( Node f, Theory::Effort effort, int e )
           Trace("no-trigger") << "Could not find trigger for " << f << std::endl;
         }
       }
+      Trace("inst-alg") << "-> Auto-gen instantiate " << f << "..." << std::endl;
 
       //if( e==4 ){
       //  d_processed_trigger.clear();
@@ -250,7 +254,7 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f, Theory::Effort effor
   if( !patTerms.empty() ){
     Trace("auto-gen-trigger") << "Generate trigger for " << f << std::endl;
     //sort terms based on relevance
-    if( d_rlv_strategy==RELEVANCE_DEFAULT ){
+    if( options::relevantTriggers() ){
       sortQuantifiersForSymbol sqfs;
       sqfs.d_qe = d_quantEngine;
       //sort based on # occurrences (this will cause Trigger to select rarer symbols)
@@ -317,12 +321,16 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f, Theory::Effort effor
         if( index<(int)patTerms.size() ){
           //Notice() << "check add additional" << std::endl;
           //check if similar patterns exist, and if so, add them additionally
-          int nqfs_curr = d_quantEngine->getQuantifierRelevance()->getNumQuantifiersForSymbol( patTerms[0].getOperator() );
+          int nqfs_curr = 0;
+          if( options::relevantTriggers() ){
+            nqfs_curr = d_quantEngine->getQuantifierRelevance()->getNumQuantifiersForSymbol( patTerms[0].getOperator() );
+          }
           index++;
           bool success = true;
           while( success && index<(int)patTerms.size() && d_is_single_trigger[ patTerms[index] ] ){
             success = false;
-            if( d_quantEngine->getQuantifierRelevance()->getNumQuantifiersForSymbol( patTerms[index].getOperator() )<=nqfs_curr ){
+            if( !options::relevantTriggers() ||
+                d_quantEngine->getQuantifierRelevance()->getNumQuantifiersForSymbol( patTerms[index].getOperator() )<=nqfs_curr ){
               d_single_trigger_gen[ patTerms[index] ] = true;
               Trigger* tr2 = Trigger::mkTrigger( d_quantEngine, f, patTerms[index], matchOption, false, Trigger::TR_RETURN_NULL,
                                                  options::smartTriggers() );
@@ -342,20 +350,6 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f, Theory::Effort effor
     }
   }
 }
-/*
-InstStrategyAutoGenTriggers::Statistics::Statistics():
-  d_instantiations("InstStrategyAutoGenTriggers::Instantiations", 0),
-  d_instantiations_min("InstStrategyAutoGenTriggers::Instantiations_min", 0)
-{
-  StatisticsRegistry::registerStat(&d_instantiations);
-  StatisticsRegistry::registerStat(&d_instantiations_min);
-}
-
-InstStrategyAutoGenTriggers::Statistics::~Statistics(){
-  StatisticsRegistry::unregisterStat(&d_instantiations);
-  StatisticsRegistry::unregisterStat(&d_instantiations_min);
-}
-*/
 
 void InstStrategyFreeVariable::processResetInstantiationRound( Theory::Effort effort ){
 }
@@ -364,26 +358,55 @@ int InstStrategyFreeVariable::process( Node f, Theory::Effort effort, int e ){
   if( e<5 ){
     return STATUS_UNFINISHED;
   }else{
+    //first, try from relevant domain
+    Trace("inst-alg") << "-> Relevant domain instantiate " << f << "..." << std::endl;
+    bool success;
+    ///*  TODO: add back
+    RelevantDomain * rd = d_quantEngine->getRelevantDomain();
+    if( rd ){
+      rd->compute();
+      std::vector< unsigned > childIndex;
+      int index = 0;
+      do {
+        while( index>=0 && index<(int)f[0].getNumChildren() ){
+          if( index==(int)childIndex.size() ){
+            childIndex.push_back( -1 );
+          }else{
+            Assert( index==(int)(childIndex.size())-1 );
+            if( (childIndex[index]+1)<rd->getRDomain( f, index )->d_terms.size() ){
+              childIndex[index]++;
+              index++;
+            }else{
+              childIndex.pop_back();
+              index--;
+            }
+          }
+        }
+        success = index>=0;
+        if( success ){
+          index--;
+          //try instantiation
+          InstMatch m;
+          for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
+            m.set( d_quantEngine, f, i, rd->getRDomain( f, i )->d_terms[childIndex[i]] );
+          }
+          if( d_quantEngine->addInstantiation( f, m, true, false, false ) ){
+            ++(d_quantEngine->getInstantiationEngine()->d_statistics.d_instantiations_guess);
+            return STATUS_UNKNOWN;
+          }
+        }
+      }while( success );
+    }
+    //*/
+
     if( d_guessed.find( f )==d_guessed.end() ){
+      Trace("inst-alg") << "-> Guess instantiate " << f << "..." << std::endl;
       d_guessed[f] = true;
-      Debug("quant-uf-alg") << "Add guessed instantiation" << std::endl;
       InstMatch m;
       if( d_quantEngine->addInstantiation( f, m ) ){
         ++(d_quantEngine->getInstantiationEngine()->d_statistics.d_instantiations_guess);
-        //d_quantEngine->d_hasInstantiated[f] = true;
       }
     }
     return STATUS_UNKNOWN;
   }
 }
-/*
-InstStrategyFreeVariable::Statistics::Statistics():
-  d_instantiations("InstStrategyGuess::Instantiations", 0)
-{
-  StatisticsRegistry::registerStat(&d_instantiations);
-}
-
-InstStrategyFreeVariable::Statistics::~Statistics(){
-  StatisticsRegistry::unregisterStat(&d_instantiations);
-}
-*/
index c73186dbb93a5ad6c844d57e727e0870a598acec..24470c58b1fac607c1fc3bdadfd99c280d694d2f 100644 (file)
@@ -65,8 +65,6 @@ public:
 private:
   /** trigger generation strategy */
   int d_tr_strategy;
-  /** relevance strategy */
-  int d_rlv_strategy;
   /** regeneration */
   bool d_regenerate;
   int d_regenerate_frequency;
@@ -92,8 +90,8 @@ public:
   /** tstrt is the type of triggers to use (maximum depth, minimum depth, or all)
       rstrt is the relevance setting for trigger (use only relevant triggers vs. use all)
       rgfr is the frequency at which triggers are generated */
-  InstStrategyAutoGenTriggers( QuantifiersEngine* qe, int tstrt, int rstrt, int rgfr = -1 ) :
-      InstStrategy( qe ), d_tr_strategy( tstrt ), d_rlv_strategy( rstrt ), d_generate_additional( false ){
+  InstStrategyAutoGenTriggers( QuantifiersEngine* qe, int tstrt,  int rgfr = -1 ) :
+      InstStrategy( qe ), d_tr_strategy( tstrt ), d_generate_additional( false ){
     setRegenerateFrequency( rgfr );
   }
   ~InstStrategyAutoGenTriggers(){}
index c19172b3b246962b649e6d626e3de17340183f90..41198c1f48f19b89f9708d871f4714c3ef9d5d9a 100644 (file)
@@ -48,8 +48,7 @@ void InstantiationEngine::finishInit(){
     }else{
       d_isup = NULL;
     }
-    int rlv = options::relevantTriggers() ? InstStrategyAutoGenTriggers::RELEVANCE_DEFAULT : InstStrategyAutoGenTriggers::RELEVANCE_NONE;
-    InstStrategyAutoGenTriggers* i_ag = new InstStrategyAutoGenTriggers( d_quantEngine, Trigger::TS_ALL, rlv, 3 );
+    InstStrategyAutoGenTriggers* i_ag = new InstStrategyAutoGenTriggers( d_quantEngine, Trigger::TS_ALL, 3 );
     i_ag->setGenerateAdditional( true );
     addInstStrategy( i_ag );
     //addInstStrategy( new InstStrategyAddFailSplits( this, ie ) );
@@ -250,8 +249,10 @@ void InstantiationEngine::check( Theory::Effort e ){
         Debug("quantifiers") << "  Active : " << n << ", no ce assigned." << std::endl;
       }
       Debug("quantifiers-relevance")  << "Quantifier : " << n << std::endl;
-      Debug("quantifiers-relevance")  << "   Relevance : " << d_quantEngine->getQuantifierRelevance()->getRelevance( n ) << std::endl;
-      Debug("quantifiers") << "   Relevance : " << d_quantEngine->getQuantifierRelevance()->getRelevance( n ) << std::endl;
+      if( options::relevantTriggers() ){
+        Debug("quantifiers-relevance")  << "   Relevance : " << d_quantEngine->getQuantifierRelevance()->getRelevance( n ) << std::endl;
+        Debug("quantifiers") << "   Relevance : " << d_quantEngine->getQuantifierRelevance()->getRelevance( n ) << std::endl;
+      }
       Trace("inst-engine-debug") << "Process : " << n << " " << d_quant_active[n] << std::endl;
     }
     if( quantActive ){
index 9e3e77c8e5a10d19fa4d7b1495a6b99d6ce9df67..ef4e67a6891574345c6a7b8e167ba3d7d622f45e 100644 (file)
@@ -50,12 +50,6 @@ QuantifiersModule( qe ){
     Trace("model-engine-debug") << "...make default model builder." << std::endl;
     d_builder = new QModelBuilderDefault( c, qe );
   }
-
-  if( options::fmfRelevantDomain() ){
-    d_rel_dom = new RelevantDomain( qe, qe->getModel() );
-  }else{
-    d_rel_dom = NULL;
-  }
 }
 
 void ModelEngine::check( Theory::Effort e ){
@@ -192,10 +186,6 @@ int ModelEngine::checkModel(){
       }
     }
   }
-  //relevant domain?
-  if( d_rel_dom ){
-    d_rel_dom->compute();
-  }
 
   d_triedLemmas = 0;
   d_addedLemmas = 0;
index ba54d7ba4ebec6f0236c12f2bd045ecedead5b29..cf770a7b93d33dfe766492d1bd8599569f0e6ce6 100644 (file)
@@ -20,7 +20,6 @@
 #include "theory/quantifiers_engine.h"
 #include "theory/quantifiers/model_builder.h"
 #include "theory/theory_model.h"
-#include "theory/quantifiers/relevant_domain.h"
 
 namespace CVC4 {
 namespace theory {
@@ -32,8 +31,6 @@ class ModelEngine : public QuantifiersModule
 private:
   /** builder class */
   QModelBuilder* d_builder;
-private:    //analysis of current model:
-  RelevantDomain* d_rel_dom;
 private:
   //options
   bool optOneQuantPerRound();
@@ -52,8 +49,6 @@ private:
 public:
   ModelEngine( context::Context* c, QuantifiersEngine* qe );
   ~ModelEngine(){}
-  //get relevant domain
-  RelevantDomain * getRelevantDomain() { return d_rel_dom; }
   //get the builder
   QModelBuilder* getModelBuilder() { return d_builder; }
 public:
index 00d3cf2341a9235418e889488dba83ac60ce7421..8962104e17092e236d7eee45ad757e4e8d5e3409 100644 (file)
@@ -103,8 +103,6 @@ option fmfOneQuantPerRound --mbqi-one-quant-per-round bool :default false
 
 option fmfInstEngine --fmf-inst-engine bool :default false
  use instantiation engine in conjunction with finite model finding
-option fmfRelevantDomain --fmf-relevant-domain bool :default false
- use relevant domain computation, similar to complete instantiation (Ge, deMoura 09)
 option fmfInstGen /--disable-fmf-inst-gen bool :default true
  disable Inst-Gen instantiation techniques for finite model finding
 option fmfInstGenOneQuantPerRound --fmf-inst-gen-one-quant-per-round bool :default false
index 198ec3bbf98c33764038847130ea12506e4e67b4..665ae53296d1552e9f5863cea39e1b13e29ceb35 100755 (executable)
@@ -68,1624 +68,1644 @@ void QcfNodeIndex::debugPrint( const char * c, int t ) {
   }\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::getFunction( Node n, int& index, bool isQuant ) {\r
-  if( isQuant && !quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
-    index = 0;\r
-    return n;\r
-  }else if( isHandledUfTerm( n ) ){\r
-    /*\r
-    std::map< Node, Node >::iterator it = d_op_node.find( n.getOperator() );\r
-    if( it==d_op_node.end() ){\r
-      std::vector< Node > children;\r
-      children.push_back( n.getOperator() );\r
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-        children.push_back( getFv( n[i].getType() ) );\r
+void 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
+    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
-      Node nn = NodeManager::currentNM()->mkNode( n.getKind(), children );\r
-      d_op_node[n.getOperator()] = nn;\r
-      return nn;\r
-    }else{\r
-      return it->second;\r
-    }*/\r
-    index = 1;\r
-    return n.getOperator();\r
-  }else{\r
-    return Node::null();\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
 }\r
 \r
-Node QuantConflictFind::mkEqNode( Node a, Node b ) {\r
-  if( a.getType().isBoolean() ){\r
-    return a.iffNode( b );\r
+int QuantInfo::getCurrentRepVar( int v ) {\r
+  std::map< int, TNode >::iterator it = d_match.find( v );\r
+  if( it!=d_match.end() ){\r
+    int vn = getVarNum( it->second );\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
-    return a.eqNode( b );\r
+    std::map< int, TNode >::iterator it = d_match.find( v );\r
+    if( it==d_match.end() ){\r
+      return n;\r
+    }else{\r
+      Assert( getVarNum( it->second )!=v );\r
+      return getCurrentValue( it->second );\r
+    }\r
   }\r
 }\r
 \r
-//-------------------------------------------------- registration\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
+          return false;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  return true;\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
+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
-      /*\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
+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( itmn!=d_match.end() && itmn->second==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.erase( v );\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( itm==d_match.end() ){\r
+            //setting variables equal\r
+            bool alreadySet = false;\r
+            if( itmn!=d_match.end() ){\r
+              alreadySet = true;\r
+              Assert( !itmn->second.isNull() && !isVar( itmn->second ) );\r
+            }\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( itmn->second, 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( itmn==d_match.end() ){\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( itm->second, itmn->second ) ? 0 : -1;\r
+            }\r
+          }\r
+        }else{\r
+          Debug("qcf-match-debug") << "  ...Variable bound to ground" << std::endl;\r
+          if( itm==d_match.end() ){\r
 \r
-      if( n.getKind()==APPLY_UF ){\r
-        flatten( q, n );\r
-      }else if( n.getKind()==EQUAL ){\r
-        for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-          flatten( q, n[i] );\r
+          }else{\r
+            //compare ground values\r
+            Debug("qcf-match-debug") << "  -> Ground value, compare " << itm->second << " "<< n << std::endl;\r
+            return p->areMatchEqual( itm->second, 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
-\r
     }else{\r
-      Trace("qcf-qregister") << "    RegisterGroundLit : " << n;\r
+      Debug("qcf-match-debug") << "  -> redundant, variable identity" << std::endl;\r
+      return 0;\r
     }\r
-    recurse = false;\r
-  }\r
-  if( recurse ){\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( q, n[i], newHasPol, newPol );\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( itm!=d_match.end() ){\r
+            TNode nv = getCurrentValue( n );\r
+            if( !p->areMatchDisequal( nv, itm->second ) ){\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
-void QuantConflictFind::flatten( Node q, Node n ) {\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
+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
+      if( it->second==vv ){\r
+        return true;\r
+      }\r
     }\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      flatten( q, n[i] );\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
-void QuantConflictFind::registerQuantifier( Node 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
-\r
-  //register the variables\r
-  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
-    d_qinfo[q].d_var_num[q[0][i]] = i;\r
-    d_qinfo[q].d_vars.push_back( q[0][i] );\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
-  //make QcfNode structure\r
-  Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;\r
-  //d_qinfo[q].d_cf = new QcfNode( d_c );\r
-  registerNode( q, q[1], true, true );\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") << "- Make match gen structure..." << std::endl;\r
-  d_qinfo[q].d_mg = new MatchGen( this, q, q[1], true );\r
-\r
-  for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){\r
-    d_qinfo[q].d_var_mg[j] = new MatchGen( this, q, d_qinfo[q].d_vars[j], false, true );\r
-    if( !d_qinfo[q].d_var_mg[j]->isValid() ){\r
-      d_qinfo[q].d_mg->setInvalid();\r
-      break;\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( it!=d_match.end() ){\r
+      if( !getCurrentCanBeEqual( p, i, it->second, p->d_effort==QuantConflictFind::effort_conflict ) ){\r
+        return true;\r
+      }\r
     }\r
   }\r
-\r
-  Trace("qcf-qregister") << "Done registering quantifier." << std::endl;\r
+  return false;\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( n.getKind()==APPLY_UF ){  //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
+bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assigned ) {\r
+  //assign values for variables that were unassigned (usually not necessary, but handles corner cases)\r
+  Trace("qcf-check") << std::endl;\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.find( i )==d_match.end() ){\r
+      //Assert( i<(int)q[0].getNumChildren() );\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
-    //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
+  bool success = true;\r
+  for( unsigned r=0; r<2; r++ ){\r
+    if( success && !unassigned[r].empty() ){\r
+      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 = false;\r
+        while( ( index>=0 && (int)index<(int)unassigned[r].size() ) || invalidMatch || doFail ){\r
+          invalidMatch = false;\r
+          if( !doFail && index==(int)eqc_count.size() ){\r
+            //check if it has now been assigned\r
+            if( r==0 ){\r
+              if( !isConstrainedVar( unassigned[r][index] ) ){\r
+                eqc_count.push_back( -1 );\r
+              }else{\r
+                d_var_mg[ unassigned[r][index] ]->reset( p, true, this );\r
+                eqc_count.push_back( 0 );\r
+              }\r
+            }else{\r
+              eqc_count.push_back( 0 );\r
+            }\r
+          }else{\r
+            if( r==0 ){\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, this ) ){\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 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( !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 " << index << std::endl;\r
+                  index++;\r
+                }else{\r
+                  Trace("qcf-check-unassign") << "Failed match " << index << std::endl;\r
+                  invalidMatch = true;\r
+                }\r
+              }else{\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
+          }\r
         }\r
-      }\r
-    }\r
-    if( ret==0 && cevc[0]!=0 && cevc[0]==cevc[1] ){\r
-      ret = cevc[0];\r
+        success = index>=0;\r
+        if( success ){\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
+            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
     }\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
+  if( success ){\r
+    return true;\r
+  }else{\r
+    for( unsigned i=0; i<assigned.size(); i++ ){\r
+      d_match.erase( assigned[i] );\r
     }\r
+    assigned.clear();\r
+    return false;\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
+void QuantInfo::debugPrintMatch( const char * c ) {\r
+  for( int i=0; i<getNumVars(); i++ ){\r
+    Trace(c) << "  " << d_vars[i] << " -> ";\r
+    if( d_match.find( i )!=d_match.end() ){\r
+      Trace(c) << d_match[i];\r
+    }else{\r
+      Trace(c) << "(unassigned) ";\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
+    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( ret==0 && !isUnk ){\r
-      ret = -ssval;\r
-    }\r
+    Trace(c) << std::endl;\r
   }\r
-  Debug("qcf-eval") << "Evaluate " << n << " to " << ret << std::endl;\r
-  return ret;\r
-}\r
-\r
-bool QuantConflictFind::isPropagationSet() {\r
-  return !d_prop_eq[0].isNull();\r
-}\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
-}\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
-  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
+struct MatchGenSort {\r
+  MatchGen * d_mg;\r
+  bool operator() (int i,int j) {\r
+    return d_mg->d_children[i].d_type<d_mg->d_children[j].d_type;\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 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
-Node QuantConflictFind::evaluateTerm( Node n ) {\r
-  if( isHandledUfTerm( 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
+MatchGen::MatchGen( QuantConflictFind * p, Node q, Node n, bool isTop, bool isVar ){\r
+  Trace("qcf-qregister-debug") << "Make match gen for " << n << ", top/var = " << isTop << " " << isVar << std::endl;\r
+  std::vector< Node > qni_apps;\r
+  d_qni_size = 0;\r
+  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 = false;\r
+      d_n = 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
-      nn = d_uf_terms[n.getOperator()].existsTerm( n, 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
-  }\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
-    if( doCreate ){\r
-      EqcInfo * eqci = new EqcInfo( d_c );\r
-      d_eqc_info[n] = eqci;\r
-      return eqci;\r
     }else{\r
-      return NULL;\r
+      //for now, unknown term\r
+      d_type = typ_invalid;\r
     }\r
-  }\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.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
+    if( quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
+      //we handle not immediately\r
+      d_n = n.getKind()==NOT ? n[0] : n;\r
+      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_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
+          }\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
-        return NULL;\r
+        d_type = typ_invalid;\r
+        //literals\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
+      //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
-QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node f ) {\r
-  std::map< TNode, QcfNodeIndex >::iterator itut = d_uf_terms.find( f );\r
-  if( itut!=d_uf_terms.end() ){\r
-    return &itut->second;\r
-  }else{\r
-    return NULL;\r
-  }\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
-  if( b.getKind()==EQUAL ){\r
-    if( a==d_true ){\r
-      //will merge anyways\r
-      //merge( b[0], b[1] );\r
-    }else if( a==d_false ){\r
-      assertDisequal( b[0], b[1] );\r
+void 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, 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{\r
-    Trace("qcf-proc") << "QCF : merge : " << a << " " << b << std::endl;\r
-    EqcInfo * eqc_b = getEqcInfo( b, false );\r
-    EqcInfo * eqc_a = NULL;\r
-    if( eqc_b ){\r
-      eqc_a = getEqcInfo( a );\r
-      //move disequalities of b into a\r
-      for( NodeBoolMap::iterator it = eqc_b->d_diseq.begin(); it != eqc_b->d_diseq.end(); ++it ){\r
-        if( (*it).second ){\r
-          Node n = (*it).first;\r
-          EqcInfo * eqc_n = getEqcInfo( n, false );\r
-          Assert( eqc_n );\r
-          if( !eqc_n->isDisequal( a ) ){\r
-            Assert( !eqc_a->isDisequal( n ) );\r
-            eqc_n->setDisequal( a );\r
-            eqc_a->setDisequal( n );\r
-            //setEqual( eqc_a, eqc_b, a, n, false );\r
-          }\r
-          eqc_n->setDisequal( b, 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
-      ////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
-  EqcInfo * eqc_a = getEqcInfo( a );\r
-  EqcInfo * eqc_b = getEqcInfo( b );\r
-  if( !eqc_a->isDisequal( b ) ){\r
-    Assert( !eqc_b->isDisequal( a ) );\r
-    eqc_b->setDisequal( a );\r
-    eqc_a->setDisequal( b );\r
-    //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
+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() << std::endl;\r
+  d_qn.clear();\r
+  d_qni.clear();\r
+  d_qni_bound.clear();\r
+  d_child_counter = -1;\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
-      Assert( false );\r
+  //set up processing matches\r
+  if( d_type==typ_invalid ){\r
+    //d_child_counter = 0;\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{\r
-    int addedLemmas = 0;\r
-    if( d_performCheck ){\r
-      ++(d_statistics.d_inst_rounds);\r
-      double clSet = 0;\r
-      if( Trace.isOn("qcf-engine") ){\r
-        clSet = double(clock())/double(CLOCKS_PER_SEC);\r
-        Trace("qcf-engine") << "---Conflict Find Engine Round, effort = " << level << "---" << std::endl;\r
+  }else if( d_type==typ_var ){\r
+    Assert( p->isHandledUfTerm( d_n ) );\r
+    Node f = d_n.getOperator();\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] = 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
+        nn[i] = qi->getCurrentValue( d_n[i] );\r
+        vn[i] = qi->getCurrentRepVar( qi->getVarNum( nn[i] ) );\r
       }\r
-      Trace("qcf-check") << "Compute relevant equalities..." << std::endl;\r
-      computeRelevantEqr();\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
+    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
+      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
-      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_prop_eq ){\r
-          for( unsigned i=0; i<2; i++ ){\r
-            d_prop_eq[i] = Node::null();\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
+        for( unsigned i=0; i<2; i++ ){\r
+          if( vn[i]!=-1 ){\r
+            d_qni_bound[vn[i]] = vn[i];\r
           }\r
         }\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
-          debugPrintQuant("qcf-check", q);\r
-          Trace("qcf-check") << " : " << q << "..." << std::endl;\r
-\r
-          Assert( d_qinfo.find( q )!=d_qinfo.end() );\r
-          if( d_qinfo[q].d_mg->isValid() ){\r
-            d_qinfo[q].reset_round( this );\r
-            //try to make a matches making the body false\r
-            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 at effort " << e << " : " << std::endl;\r
-              d_qinfo[q].debugPrintMatch("qcf-check");\r
-              Trace("qcf-check") << std::endl;\r
-\r
-              if( !d_qinfo[q].isMatchSpurious( this ) ){\r
-                std::vector< int > assigned;\r
-                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
-                    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
+        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
+      //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
+  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 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
+      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, 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
+        }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
-                    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 || e>effort_conflict );\r
-                    //}\r
-                  }\r
-                  if( d_quantEngine->addInstantiation( q, m ) ){\r
-                    Trace("qcf-check") << "   ... Added instantiation" << std::endl;\r
-                    ++addedLemmas;\r
-                    if( e==effort_conflict ){\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
-                  //clean up assigned\r
-                  for( unsigned i=0; i<assigned.size(); i++ ){\r
-                    d_qinfo[q].d_match.erase( assigned[i] );\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
-                  Trace("qcf-check") << "   ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
+                  Debug("qcf-match-debug") << "       decrement..." << std::endl;\r
+                  --d_binding_it;\r
                 }\r
-              }else{\r
-                Trace("qcf-check") << "   ... Spurious instantiation (does not meet variable constraints)" << 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
-          }\r
-          if( d_conflict ){\r
-            break;\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( addedLemmas>0 ){\r
-          d_quantEngine->flushLemmas();\r
-          break;\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
-      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
+    }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
+        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
+            qi->addConstraint( p, it->first, it->second, vn, d_tgt, true );\r
+          }\r
         }\r
-        Trace("qcf-engine") << std::endl;\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<qi->getNumVars() );\r
+          qi->d_match.erase( it->second );\r
+          qi->d_match_term.erase( it->second );\r
+        }\r
+        d_qni_bound.clear();\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( !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
-  d_uf_terms.clear();\r
-  d_eqc_uf_terms.clear();\r
-  d_eqcs.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
-    d_eqcs[r.getType()].push_back( r );\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
-        if( (*it).second ){\r
-          //Node rd = (*it).first;\r
-          //if( rd!=getRepresentative( rd ) ){\r
-          //  std::cout << "Bad rep!" << std::endl;\r
-          //  exit( 0 );\r
-          //}\r
-          deqc.push_back( (*it).first );\r
+    Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;\r
+    return success;\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
+        //transition system based on d_child_counter\r
+        if( d_type==typ_top || 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
+              d_child_counter--;\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%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==0) ? 1 : 2) )->reset( p, d_tgt, qi );\r
+            }else{\r
+              if( d_child_counter==4 ){\r
+                d_child_counter = -1;\r
+              }else{\r
+                d_child_counter +=2;\r
+                getChild( d_child_counter==4 ? 1 : 0 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );\r
+              }\r
+            }\r
+          }\r
+          if( d_child_counter%2==1 ){\r
+            int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==0) ? 1 : 2);\r
+            if( getChild( index2 )->getNextMatch( p, qi ) ){\r
+              success = true;\r
+            }else{\r
+              d_child_counter--;\r
+            }\r
+          }\r
         }\r
       }\r
+      Debug("qcf-match") << "    ...finished construct match for " << d_n << ", success = " << success << std::endl;\r
+      return success;\r
     }\r
-    */\r
-    //process disequalities\r
-    eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );\r
-    while( !eqc_i.isFinished() ){\r
-      TNode n = (*eqc_i);\r
-      if( n.getKind()!=EQUAL ){\r
-        nTermst++;\r
-        //node_to_rep[n] = r;\r
-        //if( n.getNumChildren()>0 ){\r
-        //  if( n.getKind()!=APPLY_UF ){\r
-        //    std::cout << n.getKind() << " " << n.getOperator() << " " << n << std::endl;\r
-        //  }\r
-        //}\r
+  }\r
+  Debug("qcf-match") << "    ...already finished for " << d_n << std::endl;\r
+  return false;\r
+}\r
 \r
-        bool isRedundant;\r
-        std::map< TNode, std::vector< TNode > >::iterator it_na;\r
-        TNode fn;\r
-        if( isHandledUfTerm( n ) ){\r
-          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[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
-            int jindex;\r
-            fn = getFunction( n, jindex );\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
+          Node 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( itm!=qi->d_match.end() ){\r
+              val = itm->second;\r
+              Assert( !val.isNull() );\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, QcfNodeIndex >::iterator it = d_qn[index]->d_children.begin();\r
+              if( it != d_qn[index]->d_children.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, QcfNodeIndex >::iterator it = d_qn[index]->d_children.find( val );\r
+            if( it!=d_qn[index]->d_children.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
-          isRedundant = false;\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_children.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
+              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_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") << "       " << d_n << " 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
+          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() && it->first>0 ){   //if it is an actual variable, we are interested in knowing the actual term\r
+            Assert( qi->d_match.find( it->second )!=qi->d_match.end() );\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
-        nTerms += isRedundant ? 0 : 1;\r
       }\r
-      ++eqc_i;\r
     }\r
-    //process_eqc[r] = true;\r
-    ++eqcs_i;\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
+  return !d_qn.empty();\r
 }\r
 \r
-void QuantConflictFind::computeArgReps( TNode n ) {\r
-  if( d_arg_reps.find( n )==d_arg_reps.end() ){\r
-    Assert( isHandledUfTerm( n ) );\r
-    for( unsigned j=0; j<n.getNumChildren(); j++ ){\r
-      d_arg_reps[n].push_back( getRepresentative( n[j] ) );\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_top: Trace(c) << "top";break;\r
     }\r
-  }\r
-}\r
-bool QuantConflictFind::isHandledUfTerm( TNode n ) {\r
-  return n.getKind()==APPLY_UF;\r
-}\r
-\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
-    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
+  }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_top: Debug(c) << "top";break;\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
 }\r
 \r
-int QuantConflictFind::QuantInfo::getCurrentRepVar( int v ) {\r
-  std::map< int, Node >::iterator it = d_match.find( v );\r
-  if( it!=d_match.end() ){\r
-    int vn = getVarNum( it->second );\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
+void MatchGen::setInvalid() {\r
+  d_type = typ_invalid;\r
+  d_children.clear();\r
 }\r
 \r
-Node QuantConflictFind::QuantInfo::getCurrentValue( Node n ) {\r
-  int v = getVarNum( n );\r
-  if( v==-1 ){\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::getFunction( Node n, int& index, bool isQuant ) {\r
+  if( isQuant && !quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
+    index = 0;\r
     return n;\r
-  }else{\r
-    std::map< int, Node >::iterator it = d_match.find( v );\r
-    if( it==d_match.end() ){\r
-      return n;\r
+  }else if( isHandledUfTerm( n ) ){\r
+    /*\r
+    std::map< Node, Node >::iterator it = d_op_node.find( n.getOperator() );\r
+    if( it==d_op_node.end() ){\r
+      std::vector< Node > children;\r
+      children.push_back( n.getOperator() );\r
+      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+        children.push_back( getFv( n[i].getType() ) );\r
+      }\r
+      Node nn = NodeManager::currentNM()->mkNode( n.getKind(), children );\r
+      d_op_node[n.getOperator()] = nn;\r
+      return nn;\r
     }else{\r
-      Assert( getVarNum( it->second )!=v );\r
-      return getCurrentValue( it->second );\r
-    }\r
+      return it->second;\r
+    }*/\r
+    index = 1;\r
+    return n.getOperator();\r
+  }else{\r
+    return Node::null();\r
   }\r
 }\r
 \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( 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
+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
-  return true;\r
 }\r
 \r
-int QuantConflictFind::QuantInfo::addConstraint( QuantConflictFind * p, int v, Node 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
+//-------------------------------------------------- registration\r
 \r
-int QuantConflictFind::QuantInfo::addConstraint( QuantConflictFind * p, int v, Node 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, Node >::iterator itmn = d_match.find( vn );\r
-          if( itmn!=d_match.end() && itmn->second==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< Node, 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< Node > remDeq;\r
-              for( std::map< Node, 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.erase( v );\r
-        return 1;\r
-      }else{\r
-        std::map< int, Node >::iterator itm = d_match.find( v );\r
+void QuantConflictFind::registerNode( Node q, Node n, bool hasPol, bool pol ) {\r
+  if( n.getKind()==FORALL ){\r
+    //do nothing\r
+  }else{\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
 \r
-        if( vn!=-1 ){\r
-          Debug("qcf-match-debug") << "  ...Variable bound to variable" << std::endl;\r
-          std::map< int, Node >::iterator itmn = d_match.find( vn );\r
-          if( itm==d_match.end() ){\r
-            //setting variables equal\r
-            bool alreadySet = false;\r
-            if( itmn!=d_match.end() ){\r
-              alreadySet = true;\r
-              Assert( !itmn->second.isNull() && !isVar( itmn->second ) );\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
-\r
-            //copy or check disequalities\r
-            std::map< int, std::map< Node, int > >::iterator itd = d_curr_var_deq.find( v );\r
-            if( itd!=d_curr_var_deq.end() ){\r
-              for( std::map< Node, 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( itmn->second, dv ) ){\r
-                    Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
-                    return -1;\r
-                  }\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
-            if( alreadySet ){\r
-              n = getCurrentValue( n );\r
-            }\r
-          }else{\r
-            if( itmn==d_match.end() ){\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( itm->second, itmn->second ) ? 0 : -1;\r
-            }\r
           }\r
-        }else{\r
-          Debug("qcf-match-debug") << "  ...Variable bound to ground" << std::endl;\r
-          if( itm==d_match.end() ){\r
 \r
-          }else{\r
-            //compare ground values\r
-            Debug("qcf-match-debug") << "  -> Ground value, compare " << itm->second << " "<< n << std::endl;\r
-            return p->areMatchEqual( itm->second, n ) ? 0 : -1;\r
+          */\r
+\r
+        if( n.getKind()==APPLY_UF ){\r
+          flatten( q, n );\r
+        }else if( n.getKind()==EQUAL ){\r
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+            flatten( q, n[i] );\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
+        Trace("qcf-qregister") << "    RegisterGroundLit : " << n;\r
       }\r
-    }else{\r
-      Debug("qcf-match-debug") << "  -> redundant, variable identity" << std::endl;\r
-      return 0;\r
+      recurse = false;\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, Node >::iterator itm = d_match.find( v );\r
-          if( itm!=d_match.end() ){\r
-            Node nv = getCurrentValue( n );\r
-            if( !p->areMatchDisequal( nv, itm->second ) ){\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
+    if( recurse ){\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( q, n[i], newHasPol, newPol );\r
       }\r
     }\r
   }\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
+void QuantConflictFind::flatten( Node q, Node n ) {\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
-\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
-    d_match[v] = n;\r
-    return true;\r
-  }else{\r
-    return false;\r
   }\r
 }\r
 \r
-bool QuantConflictFind::QuantInfo::isMatchSpurious( QuantConflictFind * p ) {\r
-  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, p->d_effort==QuantConflictFind::effort_conflict ) ){\r
-        return true;\r
-      }\r
+void QuantConflictFind::registerQuantifier( Node q ) {\r
+  d_quants.push_back( q );\r
+  d_quant_id[q] = d_quants.size();\r
+  d_qinfo[q].d_q = q;\r
+  Trace("qcf-qregister") << "Register ";\r
+  debugPrintQuant( "qcf-qregister", q );\r
+  Trace("qcf-qregister") << " : " << q << std::endl;\r
+\r
+  //register the variables\r
+  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
+    d_qinfo[q].d_var_num[q[0][i]] = i;\r
+    d_qinfo[q].d_vars.push_back( q[0][i] );\r
+  }\r
+\r
+  //make QcfNode structure\r
+  Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;\r
+  //d_qinfo[q].d_cf = new QcfNode( d_c );\r
+  registerNode( q, q[1], true, true );\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
-  return false;\r
-}\r
 \r
-bool QuantConflictFind::QuantInfo::completeMatch( QuantConflictFind * p, Node q, std::vector< int >& assigned ) {\r
-  //assign values for variables that were unassigned (usually not necessary, but handles corner cases)\r
-  Trace("qcf-check") << std::endl;\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.find( i )==d_match.end() ){\r
-      //Assert( i<(int)q[0].getNumChildren() );\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
+  Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;\r
+  d_qinfo[q].d_mg = new MatchGen( this, q, q[1], true );\r
+\r
+  for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){\r
+    d_qinfo[q].d_var_mg[j] = new MatchGen( this, q, d_qinfo[q].d_vars[j], false, true );\r
+    if( !d_qinfo[q].d_var_mg[j]->isValid() ){\r
+      d_qinfo[q].d_mg->setInvalid();\r
+      break;\r
     }\r
   }\r
-  bool success = true;\r
-  for( unsigned r=0; r<2; r++ ){\r
-    if( success && !unassigned[r].empty() ){\r
-      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 = false;\r
-        while( ( index>=0 && (int)index<(int)unassigned[r].size() ) || invalidMatch || doFail ){\r
-          invalidMatch = false;\r
-          if( !doFail && index==(int)eqc_count.size() ){\r
-            //check if it has now been assigned\r
-            if( r==0 ){\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
-          }else{\r
-            if( r==0 ){\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 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( !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 " << index << std::endl;\r
-                  index++;\r
-                }else{\r
-                  Trace("qcf-check-unassign") << "Failed match " << index << std::endl;\r
-                  invalidMatch = true;\r
-                }\r
-              }else{\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
-          }\r
-        }\r
-        success = index>=0;\r
-        if( success ){\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
-            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
+  Trace("qcf-qregister") << "Done registering quantifier." << std::endl;\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( n.getKind()==APPLY_UF ){  //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
-      }while( success && isMatchSpurious( p ) );\r
+      }\r
     }\r
-  }\r
-  if( success ){\r
-    return true;\r
-  }else{\r
-    for( unsigned i=0; i<assigned.size(); i++ ){\r
-      d_match.erase( assigned[i] );\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
-    assigned.clear();\r
-    return false;\r
-  }\r
-}\r
 \r
-void QuantConflictFind::QuantInfo::debugPrintMatch( const char * c ) {\r
-  for( int i=0; i<getNumVars(); i++ ){\r
-    Trace(c) << "  " << d_vars[i] << " -> ";\r
-    if( d_match.find( i )!=d_match.end() ){\r
-      Trace(c) << d_match[i];\r
-    }else{\r
-      Trace(c) << "(unassigned) ";\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
-    if( !d_curr_var_deq[i].empty() ){\r
-      Trace(c) << ", DEQ{ ";\r
-      for( std::map< Node, int >::iterator it = d_curr_var_deq[i].begin(); it != d_curr_var_deq[i].end(); ++it ){\r
-        Trace(c) << it->first << " ";\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
-      Trace(c) << "}";\r
     }\r
-    Trace(c) << std::endl;\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
-/*\r
-struct MatchGenSort {\r
-  QuantConflictFind::MatchGen * d_mg;\r
-  bool operator() (int i,int j) {\r
-    return d_mg->d_children[i].d_type<d_mg->d_children[j].d_type;\r
-  }\r
-};\r
-*/\r
+bool QuantConflictFind::isPropagationSet() {\r
+  return !d_prop_eq[0].isNull();\r
+}\r
 \r
-QuantConflictFind::MatchGen::MatchGen( QuantConflictFind * p, Node q, Node n, bool isTop, bool isVar ){\r
-  Trace("qcf-qregister-debug") << "Make match gen for " << n << ", top/var = " << isTop << " " << isVar << std::endl;\r
-  std::vector< Node > qni_apps;\r
-  d_qni_size = 0;\r
-  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 = false;\r
-      d_n = 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
-    }\r
-  }else{\r
-    if( quantifiers::TermDb::hasBoundVarAttr( n ) ){\r
-      //we handle not immediately\r
-      d_n = n.getKind()==NOT ? n[0] : n;\r
-      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_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
-          }\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( 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
-      //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
+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
 }\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
-  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
+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
-void QuantConflictFind::MatchGen::reset( QuantConflictFind * p, bool tgt, Node q ) {\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() << std::endl;\r
-  d_qn.clear();\r
-  d_qni.clear();\r
-  d_qni_bound.clear();\r
-  d_child_counter = -1;\r
+//-------------------------------------------------- handling assertions / eqc\r
 \r
-  //set up processing matches\r
-  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_var ){\r
-    Assert( p->isHandledUfTerm( d_n ) );\r
-    Node f = d_n.getOperator();\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
+void QuantConflictFind::assertNode( Node 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
+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 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
+Node QuantConflictFind::evaluateTerm( Node n ) {\r
+  if( isHandledUfTerm( 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
-      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
+      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
-    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
+    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
-      //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
-        d_qni_bound_cons[vn[0]] = nn[1];\r
-        d_qni_bound_cons_var[vn[0]] = vn[1];\r
-      }\r
+      Debug("qcf-eval") << "GT: No term for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;\r
+      return n;\r
     }\r
-    //if successful, we will bind values to variables\r
-    if( success ){\r
-      d_qn.push_back( NULL );\r
+  }\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
+    if( doCreate ){\r
+      EqcInfo * eqci = new EqcInfo( d_c );\r
+      d_eqc_info[n] = eqci;\r
+      return eqci;\r
+    }else{\r
+      return NULL;\r
     }\r
+  }\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.find( f );\r
+  if( itut==d_eqc_uf_terms.end() ){\r
+    return NULL;\r
   }else{\r
-    if( d_children.empty() ){\r
-      //add dummy\r
-      d_qn.push_back( NULL );\r
+    if( eqc.isNull() ){\r
+      return &itut->second;\r
     }else{\r
-      //reset the first child to d_tgt\r
-      d_child_counter = 0;\r
-      getChild( d_child_counter )->reset( p, d_tgt, q );\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
-  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() << ", 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
+QcfNodeIndex * QuantConflictFind::getQcfNodeIndex( Node f ) {\r
+  std::map< TNode, QcfNodeIndex >::iterator itut = d_uf_terms.find( f );\r
+  if( itut!=d_uf_terms.end() ){\r
+    return &itut->second;\r
+  }else{\r
+    return NULL;\r
+  }\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
+  if( b.getKind()==EQUAL ){\r
+    if( a==d_true ){\r
+      //will merge anyways\r
+      //merge( b[0], b[1] );\r
+    }else if( a==d_false ){\r
+      assertDisequal( b[0], b[1] );\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
+  }else{\r
+    Trace("qcf-proc") << "QCF : merge : " << a << " " << b << std::endl;\r
+    EqcInfo * eqc_b = getEqcInfo( b, false );\r
+    EqcInfo * eqc_a = NULL;\r
+    if( eqc_b ){\r
+      eqc_a = getEqcInfo( a );\r
+      //move disequalities of b into a\r
+      for( NodeBoolMap::iterator it = eqc_b->d_diseq.begin(); it != eqc_b->d_diseq.end(); ++it ){\r
+        if( (*it).second ){\r
+          Node n = (*it).first;\r
+          EqcInfo * eqc_n = getEqcInfo( n, false );\r
+          Assert( eqc_n );\r
+          if( !eqc_n->isDisequal( a ) ){\r
+            Assert( !eqc_a->isDisequal( n ) );\r
+            eqc_n->setDisequal( a );\r
+            eqc_a->setDisequal( n );\r
+            //setEqual( eqc_a, eqc_b, a, n, false );\r
+          }\r
+          eqc_n->setDisequal( b, false );\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
+      ////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
-        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( 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") << "       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
+/** 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
+  EqcInfo * eqc_a = getEqcInfo( a );\r
+  EqcInfo * eqc_b = getEqcInfo( b );\r
+  if( !eqc_a->isDisequal( b ) ){\r
+    Assert( !eqc_b->isDisequal( a ) );\r
+    eqc_b->setDisequal( a );\r
+    eqc_a->setDisequal( b );\r
+    //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
+\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
+      if( Trace.isOn("qcf-engine") ){\r
+        clSet = double(clock())/double(CLOCKS_PER_SEC);\r
+        Trace("qcf-engine") << "---Conflict Find Engine Round, effort = " << level << "---" << std::endl;\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
-        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
+      Trace("qcf-check") << "Compute relevant equalities..." << std::endl;\r
+      computeRelevantEqr();\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
-    }\r
-    Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;\r
-    return success;\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
-        //transition system based on d_child_counter\r
-        if( d_type==typ_top || 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, q ) ){\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, q );\r
-              }else{\r
-                success = true;\r
-              }\r
-            }else{\r
-              d_child_counter--;\r
-            }\r
-          }else{\r
-            //one child must match\r
-            if( !getChild( d_child_counter )->getNextMatch( p, q ) ){\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, q );\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, q ) ){\r
-              d_child_counter++;\r
-              getChild( 1 )->reset( p, d_child_counter==1, q );\r
-            }else{\r
-              if( d_child_counter==0 ){\r
-                d_child_counter = 2;\r
-                getChild( 0 )->reset( p, !d_tgt, q );\r
-              }else{\r
-                d_child_counter = -1;\r
-              }\r
-            }\r
-          }\r
-          if( d_child_counter%2==1 ){\r
-            if( getChild( 1 )->getNextMatch( p, q ) ){\r
-              success = true;\r
-            }else{\r
-              d_child_counter--;\r
-            }\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_prop_eq ){\r
+          for( unsigned i=0; i<2; i++ ){\r
+            d_prop_eq[i] = Node::null();\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, q ) ){\r
-              d_child_counter++;\r
-              getChild( d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==0) ? 1 : 2) )->reset( p, d_tgt, q );\r
-            }else{\r
-              if( d_child_counter==4 ){\r
-                d_child_counter = -1;\r
+        }\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
+          QuantInfo * qi = &d_qinfo[q];\r
+          Trace("qcf-check") << "Check quantified formula ";\r
+          debugPrintQuant("qcf-check", q);\r
+          Trace("qcf-check") << " : " << q << "..." << std::endl;\r
+\r
+          Assert( d_qinfo.find( q )!=d_qinfo.end() );\r
+          if( qi->d_mg->isValid() ){\r
+            qi->reset_round( this );\r
+            //try to make a matches making the body false\r
+            qi->d_mg->reset( this, false, qi );\r
+            while( qi->d_mg->getNextMatch( this, qi ) ){\r
+\r
+              Trace("qcf-check") << "*** Produced match at effort " << e << " : " << std::endl;\r
+              qi->debugPrintMatch("qcf-check");\r
+              Trace("qcf-check") << std::endl;\r
+\r
+              if( !qi->isMatchSpurious( this ) ){\r
+                std::vector< int > assigned;\r
+                if( qi->completeMatch( this, assigned ) ){\r
+                  InstMatch m;\r
+                  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
+                    //Node cv = qi->getCurrentValue( qi->d_match[i] );\r
+                    int repVar = qi->getCurrentRepVar( i );\r
+                    Node cv;\r
+                    std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );\r
+                    if( itmt!=qi->d_match_term.end() ){\r
+                      cv = itmt->second;\r
+                    }else{\r
+                      cv = qi->d_match[repVar];\r
+                    }\r
+\r
+\r
+                    Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << qi->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 || e>effort_conflict );\r
+                    //}\r
+                  }\r
+                  if( d_quantEngine->addInstantiation( q, m ) ){\r
+                    Trace("qcf-check") << "   ... Added instantiation" << std::endl;\r
+                    ++addedLemmas;\r
+                    if( e==effort_conflict ){\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
+                  //clean up assigned\r
+                  for( unsigned i=0; i<assigned.size(); i++ ){\r
+                    qi->d_match.erase( assigned[i] );\r
+                  }\r
+                }else{\r
+                  Trace("qcf-check") << "   ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
+                }\r
               }else{\r
-                d_child_counter +=2;\r
-                getChild( d_child_counter==4 ? 1 : 0 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, q );\r
+                Trace("qcf-check") << "   ... Spurious instantiation (does not meet variable constraints)" << std::endl;\r
               }\r
             }\r
           }\r
-          if( d_child_counter%2==1 ){\r
-            int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==0) ? 1 : 2);\r
-            if( getChild( index2 )->getNextMatch( p, q ) ){\r
-              success = true;\r
-            }else{\r
-              d_child_counter--;\r
-            }\r
+          if( d_conflict ){\r
+            break;\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" : "prop_deq" ) );\r
+          Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;\r
+        }\r
+        Trace("qcf-engine") << std::endl;\r
       }\r
-      Debug("qcf-match") << "    ...finished construct match for " << d_n << ", success = " << success << std::endl;\r
-      return success;\r
     }\r
+    Trace("qcf-check2") << "QCF : finished check : " << level << std::endl;\r
   }\r
-  Debug("qcf-match") << "    ...already finished for " << d_n << std::endl;\r
-  return false;\r
 }\r
 \r
-bool QuantConflictFind::MatchGen::doMatching( QuantConflictFind * p, Node q ) {\r
-  if( !d_qn.empty() ){\r
-    if( d_qn[0]==NULL ){\r
-      d_qn.clear();\r
-      return true;\r
-    }else{\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
-          Node 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 = p->d_qinfo[q].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, Node >::iterator itm = p->d_qinfo[q].d_match.find( repVar );\r
-            if( itm!=p->d_qinfo[q].d_match.end() ){\r
-              val = itm->second;\r
-              Assert( !val.isNull() );\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, QcfNodeIndex >::iterator it = d_qn[index]->d_children.begin();\r
-              if( it != d_qn[index]->d_children.end() ) {\r
-                d_qni.push_back( it );\r
-                //set the match\r
-                if( p->d_qinfo[q].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, QcfNodeIndex >::iterator it = d_qn[index]->d_children.find( val );\r
-            if( it!=d_qn[index]->d_children.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_children.end() ){\r
-              success = true;\r
-              if( p->d_qinfo[q].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
-              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
+bool QuantConflictFind::needsCheck( Theory::Effort level ) {\r
+  d_performCheck = false;\r
+  if( !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
+  d_uf_terms.clear();\r
+  d_eqc_uf_terms.clear();\r
+  d_eqcs.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
+    d_eqcs[r.getType()].push_back( r );\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
+        if( (*it).second ){\r
+          //Node rd = (*it).first;\r
+          //if( rd!=getRepresentative( rd ) ){\r
+          //  std::cout << "Bad rep!" << std::endl;\r
+          //  exit( 0 );\r
+          //}\r
+          deqc.push_back( (*it).first );\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
+    */\r
+    //process disequalities\r
+    eq::EqClassIterator eqc_i = eq::EqClassIterator( r, getEqualityEngine() );\r
+    while( !eqc_i.isFinished() ){\r
+      TNode n = (*eqc_i);\r
+      if( n.getKind()!=EQUAL ){\r
+        nTermst++;\r
+        //node_to_rep[n] = r;\r
+        //if( n.getNumChildren()>0 ){\r
+        //  if( n.getKind()!=APPLY_UF ){\r
+        //    std::cout << n.getKind() << " " << n.getOperator() << " " << n << std::endl;\r
+        //  }\r
+        //}\r
+\r
+        bool isRedundant;\r
+        std::map< TNode, std::vector< TNode > >::iterator it_na;\r
+        TNode fn;\r
+        if( isHandledUfTerm( n ) ){\r
+          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[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
+            int jindex;\r
+            fn = getFunction( n, jindex );\r
           }\r
+        }else{\r
+          isRedundant = false;\r
         }\r
+        nTerms += isRedundant ? 0 : 1;\r
       }\r
+      ++eqc_i;\r
     }\r
+    //process_eqc[r] = true;\r
+    ++eqcs_i;\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
-  return !d_qn.empty();\r
 }\r
 \r
-void QuantConflictFind::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_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_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_top: Debug(c) << "top";break;\r
+void QuantConflictFind::computeArgReps( TNode n ) {\r
+  if( d_arg_reps.find( n )==d_arg_reps.end() ){\r
+    Assert( isHandledUfTerm( n ) );\r
+    for( unsigned j=0; j<n.getNumChildren(); j++ ){\r
+      d_arg_reps[n].push_back( getRepresentative( n[j] ) );\r
     }\r
   }\r
 }\r
-\r
-void QuantConflictFind::MatchGen::setInvalid() {\r
-  d_type = typ_invalid;\r
-  d_children.clear();\r
+bool QuantConflictFind::isHandledUfTerm( TNode n ) {\r
+  return n.getKind()==APPLY_UF;\r
 }\r
 \r
 \r
index d8fe1e8083f0ab00a0cfa045584dbc8c8fa08d14..5ba7684efb925e37f08f5c5d72a1804d0d188152 100755 (executable)
@@ -38,9 +38,99 @@ public:
   Node addTerm( TNode n, std::vector< TNode >& reps, int index = 0 );\r
 };\r
 \r
+class QuantInfo;\r
+\r
+//match generator\r
+class MatchGen {\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< QcfNodeIndex * > d_qn;\r
+  std::vector< std::map< TNode, QcfNodeIndex >::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::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
+  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_pred,\r
+    typ_eq,\r
+    typ_formula,\r
+    typ_var,\r
+    typ_top,\r
+  };\r
+  void debugPrintType( const char * c, short typ, bool isTrace = false );\r
+public:\r
+  MatchGen() : d_type( typ_invalid ){}\r
+  MatchGen( QuantConflictFind * p, Node q, Node n, bool isTop = false, bool isVar = false );\r
+  bool d_tgt;\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 isValid() { return d_type!=typ_invalid; }\r
+  void setInvalid();\r
+};\r
+\r
+//info for quantifiers\r
+class QuantInfo {\r
+public:\r
+  QuantInfo() : d_mg( NULL ) {}\r
+  std::vector< TNode > d_vars;\r
+  std::map< TNode, int > d_var_num;\r
+  //std::map< EqRegistry *, bool > d_rel_eqr;\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
+  MatchGen * d_mg;\r
+  Node d_q;\r
+  std::map< int, MatchGen * > d_var_mg;\r
+  void reset_round( QuantConflictFind * p );\r
+public:\r
+  //current constraints\r
+  std::map< int, TNode > d_match;\r
+  std::map< int, TNode > d_match_term;\r
+  std::map< int, std::map< TNode, int > > d_curr_var_deq;\r
+  int getCurrentRepVar( int v );\r
+  TNode getCurrentValue( 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 completeMatch( QuantConflictFind * p, std::vector< int >& assigned );\r
+  void debugPrintMatch( const char * c );\r
+  bool isConstrainedVar( int v );\r
+};\r
+\r
 class QuantConflictFind : public QuantifiersModule\r
 {\r
   friend class QcfNodeIndex;\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
@@ -62,93 +152,9 @@ public:  //for ground terms
 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
-  class MatchGen {\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< QcfNodeIndex * > d_qn;\r
-    std::vector< std::map< TNode, QcfNodeIndex >::iterator > d_qni;\r
-    bool doMatching( QuantConflictFind * p, Node q );\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, Node > d_qni_gterm;\r
-    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_pred,\r
-      typ_eq,\r
-      typ_formula,\r
-      typ_var,\r
-      typ_top,\r
-    };\r
-    void debugPrintType( const char * c, short typ, bool isTrace = false );\r
-  public:\r
-    MatchGen() : d_type( typ_invalid ){}\r
-    MatchGen( QuantConflictFind * p, Node q, Node n, bool isTop = false, bool isVar = false );\r
-    bool d_tgt;\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, Node q );\r
-    bool getNextMatch( QuantConflictFind * p, Node q );\r
-    bool isValid() { return d_type!=typ_invalid; }\r
-    void setInvalid();\r
-  };\r
 private:\r
   //currently asserted quantifiers\r
   NodeList d_qassert;\r
-  //info for quantifiers\r
-  class QuantInfo {\r
-  public:\r
-    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< 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
-    int getNumVars() { return (int)d_vars.size(); }\r
-    Node getVar( int i ) { return d_vars[i]; }\r
-    MatchGen * d_mg;\r
-    std::map< int, MatchGen * > d_var_mg;\r
-    void reset_round( QuantConflictFind * p );\r
-  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, 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
   eq::EqualityEngine * getEqualityEngine();\r
index b079ae75cb45866f4b964dcde46a45f2c42e7e8b..33d658e0a568423a148d490db6323c8660d8ad59 100644 (file)
@@ -70,7 +70,7 @@ void RelevantDomain::RDomain::removeRedundantTerms( FirstOrderModel * fm ) {
 
 
 RelevantDomain::RelevantDomain( QuantifiersEngine* qe, FirstOrderModel* m ) : d_qe( qe ), d_model( m ){
-
+   d_is_computed = false;
 }
 
 RelevantDomain::RDomain * RelevantDomain::getRDomain( Node n, int i ) {
@@ -82,52 +82,59 @@ RelevantDomain::RDomain * RelevantDomain::getRDomain( Node n, int i ) {
   return d_rel_doms[n][i]->getParent();
 }
 
+void RelevantDomain::reset(){
+  d_is_computed = false;
+}
+
 void RelevantDomain::compute(){
-  for( std::map< Node, std::map< int, RDomain * > >::iterator it = d_rel_doms.begin(); it != d_rel_doms.end(); ++it ){
-    for( std::map< int, RDomain * >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
-      it2->second->reset();
+  if( !d_is_computed ){
+    d_is_computed = true;
+    for( std::map< Node, std::map< int, RDomain * > >::iterator it = d_rel_doms.begin(); it != d_rel_doms.end(); ++it ){
+      for( std::map< int, RDomain * >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
+        it2->second->reset();
+      }
+    }
+    for( int i=0; i<(int)d_model->getNumAssertedQuantifiers(); i++ ){
+      Node f = d_model->getAssertedQuantifier( i );
+      Node icf = d_qe->getTermDatabase()->getInstConstantBody( f );
+      Trace("rel-dom-debug") << "compute relevant domain for " << icf << std::endl;
+      computeRelevantDomain( icf, true, true );
     }
-  }
-  for( int i=0; i<(int)d_model->getNumAssertedQuantifiers(); i++ ){
-    Node f = d_model->getAssertedQuantifier( i );
-    Node icf = d_qe->getTermDatabase()->getInstConstantBody( f );
-    Trace("rel-dom-debug") << "compute relevant domain for " << icf << std::endl;
-    computeRelevantDomain( icf, true, true );
-  }
 
-  Trace("rel-dom-debug") << "account for ground terms" << std::endl;
-  for( std::map< Node, std::vector< Node > >::iterator it = d_model->d_uf_terms.begin(); it != d_model->d_uf_terms.end(); ++it ){
-    Node op = it->first;
-    for( unsigned i=0; i<it->second.size(); i++ ){
-      Node n = it->second[i];
-      //if it is a non-redundant term
-      if( !n.getAttribute(NoMatchAttribute()) ){
-        for( unsigned j=0; j<n.getNumChildren(); j++ ){
-          RDomain * rf = getRDomain( op, j );
-          rf->addTerm( n[j] );
+    Trace("rel-dom-debug") << "account for ground terms" << std::endl;
+    TermDb * db = d_qe->getTermDatabase();
+    for( std::map< Node, std::vector< Node > >::iterator it = db->d_op_map.begin(); it != db->d_op_map.end(); ++it ){
+      Node op = it->first;
+      for( unsigned i=0; i<it->second.size(); i++ ){
+        Node n = it->second[i];
+        //if it is a non-redundant term
+        if( !n.getAttribute(NoMatchAttribute()) ){
+          for( unsigned j=0; j<n.getNumChildren(); j++ ){
+            RDomain * rf = getRDomain( op, j );
+            rf->addTerm( n[j] );
+          }
         }
       }
     }
-  }
-  //print debug
-  for( std::map< Node, std::map< int, RDomain * > >::iterator it = d_rel_doms.begin(); it != d_rel_doms.end(); ++it ){
-    Trace("rel-dom") << "Relevant domain for " << it->first << " : " << std::endl;
-    for( std::map< int, RDomain * >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
-      Trace("rel-dom") << "   " << it2->first << " : ";
-      RDomain * r = it2->second;
-      RDomain * rp = r->getParent();
-      if( r==rp ){
-        r->removeRedundantTerms( d_model );
-        for( unsigned i=0; i<r->d_terms.size(); i++ ){
-          Trace("rel-dom") << r->d_terms[i] << " ";
+    //print debug
+    for( std::map< Node, std::map< int, RDomain * > >::iterator it = d_rel_doms.begin(); it != d_rel_doms.end(); ++it ){
+      Trace("rel-dom") << "Relevant domain for " << it->first << " : " << std::endl;
+      for( std::map< int, RDomain * >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
+        Trace("rel-dom") << "   " << it2->first << " : ";
+        RDomain * r = it2->second;
+        RDomain * rp = r->getParent();
+        if( r==rp ){
+          r->removeRedundantTerms( d_model );
+          for( unsigned i=0; i<r->d_terms.size(); i++ ){
+            Trace("rel-dom") << r->d_terms[i] << " ";
+          }
+        }else{
+          Trace("rel-dom") << "Dom( " << d_rn_map[rp] << ", " << d_ri_map[rp] << " ) ";
         }
-      }else{
-        Trace("rel-dom") << "Dom( " << d_rn_map[rp] << ", " << d_ri_map[rp] << " ) ";
+        Trace("rel-dom") << std::endl;
       }
-      Trace("rel-dom") << std::endl;
     }
   }
-
 }
 
 void RelevantDomain::computeRelevantDomain( Node n, bool hasPol, bool pol ) {
index c4345f8287fbb0065d403c37f791b2a0afb54571..0f5afcaddd689626aa047ebc028acf6f3b3b4965 100644 (file)
@@ -42,16 +42,18 @@ private:
   std::map< Node, std::map< int, RDomain * > > d_rel_doms;
   std::map< RDomain *, Node > d_rn_map;
   std::map< RDomain *, int > d_ri_map;
-  RDomain * getRDomain( Node n, int i );
   QuantifiersEngine* d_qe;
   FirstOrderModel* d_model;
   void computeRelevantDomain( Node n, bool hasPol, bool pol );
+  bool d_is_computed;
 public:
   RelevantDomain( QuantifiersEngine* qe, FirstOrderModel* m );
   virtual ~RelevantDomain(){}
+  void reset();
   //compute the relevant domain
   void compute();
 
+  RDomain * getRDomain( Node n, int i );
   Node getRelevantTerm( Node f, int i, Node r );
 };/* class RelevantDomain */
 
index 001d8b2b6956a78ae87a64418bdd3a9ae93177b8..111aa9ac5fef3779a4d59833f7c0b2041b68d8c6 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/relevant_domain.h"
 #include "theory/uf/options.h"
 
 using namespace std;
@@ -41,7 +42,6 @@ using namespace CVC4::theory::inst;
 
 QuantifiersEngine::QuantifiersEngine(context::Context* c, context::UserContext* u, TheoryEngine* te):
 d_te( te ),
-d_quant_rel( false ),
 d_lemmas_produced_c(u){
   d_eq_query = new EqualityQueryQuantifiersEngine( this );
   d_term_db = new quantifiers::TermDb( this );
@@ -51,6 +51,7 @@ d_lemmas_produced_c(u){
   d_hasAddedLemma = false;
 
   Trace("quant-engine-debug") << "Initialize model, mbqi : " << options::mbqiMode() << std::endl;
+
   //the model object
   if( options::mbqiMode()==quantifiers::MBQI_FMC ||
       options::mbqiMode()==quantifiers::MBQI_FMC_INTERVAL || options::fmfBoundInt() ){
@@ -60,6 +61,16 @@ d_lemmas_produced_c(u){
   }else{
     d_model = new quantifiers::FirstOrderModelIG( this, c, "FirstOrderModelIG" );
   }
+  if( !options::finiteModelFind() ){
+    d_rel_dom = new quantifiers::RelevantDomain( this, d_model );
+  }else{
+    d_rel_dom = NULL;
+  }
+  if( options::relevantTriggers() ){
+    d_quant_rel = new QuantRelevance( false );
+  }else{
+    d_quant_rel = NULL;
+  }
 
   //add quantifiers modules
   if( options::quantConflictFind() ){
@@ -161,6 +172,9 @@ void QuantifiersEngine::check( Theory::Effort e ){
     d_hasAddedLemma = false;
     d_term_db->reset( e );
     d_eq_query->reset();
+    if( d_rel_dom ){
+      d_rel_dom->reset();
+    }
     if( e==Theory::EFFORT_LAST_CALL ){
       //if effort is last call, try to minimize model first
       if( options::finiteModelFind() ){
@@ -209,7 +223,9 @@ void QuantifiersEngine::registerQuantifier( Node f ){
     //make instantiation constants for f
     d_term_db->makeInstantiationConstantsFor( f );
     //register with quantifier relevance
-    d_quant_rel.registerQuantifier( f );
+    if( d_quant_rel ){
+      d_quant_rel->registerQuantifier( f );
+    }
     //register with each module
     for( int i=0; i<(int)d_modules.size(); i++ ){
       d_modules[i]->registerQuantifier( f );
@@ -264,9 +280,11 @@ void QuantifiersEngine::addTermToDatabase( Node n, bool withinQuant ){
     d_eem->newTerms( added );
   }
   //added contains also the Node that just have been asserted in this branch
-  for( std::set< Node >::iterator i=added.begin(), end=added.end(); i!=end; i++ ){
-    if( !withinQuant ){
-      d_quant_rel.setRelevance( i->getOperator(), 0 );
+  if( d_quant_rel ){
+    for( std::set< Node >::iterator i=added.begin(), end=added.end(); i!=end; i++ ){
+      if( !withinQuant ){
+        d_quant_rel->setRelevance( i->getOperator(), 0 );
+      }
     }
   }
 }
@@ -414,9 +432,17 @@ Node QuantifiersEngine::getInstantiation( Node f, std::vector< Node >& terms ) {
 }
 
 bool QuantifiersEngine::existsInstantiation( Node f, InstMatch& m, bool modEq, bool modInst ){
-  if( d_inst_match_trie.find( f )!=d_inst_match_trie.end() ){
-    if( d_inst_match_trie[f]->existsInstMatch( this, f, m, modEq, modInst ) ){
-      return true;
+  if( options::incrementalSolving() ){
+    if( d_c_inst_match_trie.find( f )!=d_c_inst_match_trie.end() ){
+      if( d_c_inst_match_trie[f]->existsInstMatch( this, f, m, getUserContext(), modEq, modInst ) ){
+        return true;
+      }
+    }
+  }else{
+    if( d_inst_match_trie.find( f )!=d_inst_match_trie.end() ){
+      if( d_inst_match_trie[f].existsInstMatch( this, f, m, modEq, modInst ) ){
+        return true;
+      }
     }
   }
   //also check model engine (it may contain instantiations internally)
@@ -461,19 +487,27 @@ bool QuantifiersEngine::addInstantiation( Node f, InstMatch& m, bool modEq, bool
     }
   }
   //check for duplication modulo equality
-  inst::CDInstMatchTrie* imt;
-  std::map< Node, inst::CDInstMatchTrie* >::iterator it = d_inst_match_trie.find( f );
-  if( it!=d_inst_match_trie.end() ){
-    imt = it->second;
+  bool alreadyExists = false;
+  ///*
+  Trace("inst-add-debug") << "Adding into inst trie" << std::endl;
+  if( options::incrementalSolving() ){
+    inst::CDInstMatchTrie* imt;
+    std::map< Node, inst::CDInstMatchTrie* >::iterator it = d_c_inst_match_trie.find( f );
+    if( it!=d_c_inst_match_trie.end() ){
+      imt = it->second;
+    }else{
+      imt = new CDInstMatchTrie( getUserContext() );
+      d_c_inst_match_trie[f] = imt;
+    }
+    alreadyExists = !imt->addInstMatch( this, f, m, getUserContext(), modEq, modInst );
   }else{
-    imt = new CDInstMatchTrie( getUserContext() );
-    d_inst_match_trie[f] = imt;
+    alreadyExists = !d_inst_match_trie[f].addInstMatch( this, f, m, modEq, modInst );
   }
-  Trace("inst-add-debug") << "Adding into inst trie" << std::endl;
-  if( !imt->addInstMatch( this, f, m, getUserContext(), modEq, modInst ) ){
-    Trace("inst-add-debug") << " -> Already exists." << std::endl;
-    ++(d_statistics.d_inst_duplicate);
-    return false;
+  //*/
+  if( alreadyExists ){
+      Trace("inst-add-debug") << " -> Already exists." << std::endl;
+      ++(d_statistics.d_inst_duplicate_eq);
+      return false;
   }
   Trace("inst-add-debug") << "compute terms" << std::endl;
   //compute the vector of terms for the instantiation
@@ -681,47 +715,46 @@ Node EqualityQueryQuantifiersEngine::getInternalRepresentative( Node a, Node f,
     if( d_int_rep.find( r )==d_int_rep.end() ){
       //find best selection for representative
       Node r_best;
-      if( options::fmfRelevantDomain() && !f.isNull() ){
-        Trace("internal-rep-debug") << "Consult relevant domain to mkRep " << r << std::endl;
-        r_best = d_qe->getModelEngine()->getRelevantDomain()->getRelevantTerm( f, index, r );
-        Trace("internal-rep-debug") << "Returned " << r_best << " " << r << std::endl;
-      }else{
-        std::vector< Node > eqc;
-        getEquivalenceClass( r, eqc );
-        Trace("internal-rep-select") << "Choose representative for equivalence class : { ";
-        for( unsigned i=0; i<eqc.size(); i++ ){
-          if( i>0 ) Trace("internal-rep-select") << ", ";
-          Trace("internal-rep-select") << eqc[i];
-        }
-        Trace("internal-rep-select")  << " } " << std::endl;
-        int r_best_score = -1;
-        for( size_t i=0; i<eqc.size(); i++ ){
-          //if cbqi is active, do not choose instantiation constant terms
-          if( !options::cbqi() || !quantifiers::TermDb::hasInstConstAttr(eqc[i]) ){
-            int score = getRepScore( eqc[i], f, index );
-            //score prefers earliest use of this term as a representative
-            if( r_best.isNull() || ( score>=0 && ( r_best_score<0 || score<r_best_score ) ) ){
-              r_best = eqc[i];
-              r_best_score = score;
-            }
-                     }
-        }
-        if( r_best.isNull() ){
-          if( !f.isNull() ){
-            Node ic = d_qe->getTermDatabase()->getInstantiationConstant( f, index );
-            r_best = d_qe->getTermDatabase()->getFreeVariableForInstConstant( ic );
-          }else{
-            r_best = a;
+      //if( options::fmfRelevantDomain() && !f.isNull() ){
+      //  Trace("internal-rep-debug") << "Consult relevant domain to mkRep " << r << std::endl;
+      //  r_best = d_qe->getRelevantDomain()->getRelevantTerm( f, index, r );
+      //  Trace("internal-rep-debug") << "Returned " << r_best << " " << r << std::endl;
+      //}
+      std::vector< Node > eqc;
+      getEquivalenceClass( r, eqc );
+      Trace("internal-rep-select") << "Choose representative for equivalence class : { ";
+      for( unsigned i=0; i<eqc.size(); i++ ){
+        if( i>0 ) Trace("internal-rep-select") << ", ";
+        Trace("internal-rep-select") << eqc[i];
+      }
+      Trace("internal-rep-select")  << " } " << std::endl;
+      int r_best_score = -1;
+      for( size_t i=0; i<eqc.size(); i++ ){
+        //if cbqi is active, do not choose instantiation constant terms
+        if( !options::cbqi() || !quantifiers::TermDb::hasInstConstAttr(eqc[i]) ){
+          int score = getRepScore( eqc[i], f, index );
+          //score prefers earliest use of this term as a representative
+          if( r_best.isNull() || ( score>=0 && ( r_best_score<0 || score<r_best_score ) ) ){
+            r_best = eqc[i];
+            r_best_score = score;
           }
-                   }
-        //now, make sure that no other member of the class is an instance
-        r_best = getInstance( r_best, eqc );
-        //store that this representative was chosen at this point
-        if( d_rep_score.find( r_best )==d_rep_score.end() ){
-          d_rep_score[ r_best ] = d_reset_count;
         }
-        Trace("internal-rep-select") << "...Choose " << r_best << std::endl;
       }
+      if( r_best.isNull() ){
+        if( !f.isNull() ){
+          Node ic = d_qe->getTermDatabase()->getInstantiationConstant( f, index );
+          r_best = d_qe->getTermDatabase()->getFreeVariableForInstConstant( ic );
+        }else{
+          r_best = a;
+        }
+      }
+      //now, make sure that no other member of the class is an instance
+      r_best = getInstance( r_best, eqc );
+      //store that this representative was chosen at this point
+      if( d_rep_score.find( r_best )==d_rep_score.end() ){
+        d_rep_score[ r_best ] = d_reset_count;
+      }
+      Trace("internal-rep-select") << "...Choose " << r_best << std::endl;
       d_int_rep[r] = r_best;
       if( r_best!=a ){
         Trace("internal-rep-debug") << "rep( " << a << " ) = " << r << ", " << std::endl;
index ee7e6e6d874dbfc692f603d84959986702b84c0d..9d341194fdff2b5229b7fab884ffec967e423da6 100644 (file)
@@ -68,6 +68,7 @@ namespace quantifiers {
   class BoundedIntegers;
   class QuantConflictFind;
   class RewriteEngine;
+  class RelevantDomain;
 }/* CVC4::theory::quantifiers */
 
 namespace inst {
@@ -95,7 +96,9 @@ private:
   /** equality query class */
   EqualityQueryQuantifiersEngine* d_eq_query;
   /** for computing relevance of quantifiers */
-  QuantRelevance d_quant_rel;
+  QuantRelevance * d_quant_rel;
+  /** relevant domain */
+  quantifiers::RelevantDomain* d_rel_dom;
   /** phase requirements for each quantifier for each instantiation literal */
   std::map< Node, QuantPhaseReq* > d_phase_reqs;
   /** efficient e-matcher */
@@ -121,7 +124,8 @@ private:
   /** has added lemma this round */
   bool d_hasAddedLemma;
   /** list of all instantiations produced for each quantifier */
-  std::map< Node, inst::CDInstMatchTrie* > d_inst_match_trie;
+  std::map< Node, inst::InstMatchTrie > d_inst_match_trie;
+  std::map< Node, inst::CDInstMatchTrie* > d_c_inst_match_trie;
   /** term database */
   quantifiers::TermDb* d_term_db;
   /** all triggers will be stored in this trie */
@@ -158,8 +162,10 @@ public:
   OutputChannel& getOutputChannel();
   /** get default valuation for the quantifiers engine */
   Valuation& getValuation();
+  /** get relevant domain */
+  quantifiers::RelevantDomain* getRelevantDomain() { return d_rel_dom; }
   /** get quantifier relevance */
-  QuantRelevance* getQuantifierRelevance() { return &d_quant_rel; }
+  QuantRelevance* getQuantifierRelevance() { return d_quant_rel; }
   /** get phase requirement information */
   QuantPhaseReq* getPhaseRequirements( Node f ) { return d_phase_reqs.find( f )==d_phase_reqs.end() ? NULL : d_phase_reqs[f]; }
   /** get phase requirement terms */
index d0a93a142f64da78b5a87c3540e3e763e35ee930..93d513d9f589b131649658461ea7daa216c9e7d6 100644 (file)
@@ -24,7 +24,6 @@ TESTS =       \
        bug291.smt2 \
        ex3.smt2 \
        Arrays_Q1-noinfer.smt2 \
-       array-unsat-simp3.smt2 \
        bignum_quant.smt2 \
        bug269.smt2 \
        burns13.smt2 \
@@ -60,6 +59,7 @@ TESTS =       \
 #              javafe.ast.WhileStmt.447.smt2 \
 #              javafe.tc.CheckCompilationUnit.001.smt2 \
 #              javafe.tc.FlowInsensitiveChecks.682.smt2 \
+#              array-unsat-simp3.smt2 \
 #
 
 EXTRA_DIST = $(TESTS) \