Moving some instantiation-related stuff from src/theory to src/theory/quantifiers...
authorMorgan Deters <mdeters@gmail.com>
Tue, 31 Jul 2012 21:24:31 +0000 (21:24 +0000)
committerMorgan Deters <mdeters@gmail.com>
Tue, 31 Jul 2012 21:24:31 +0000 (21:24 +0000)
The namespaces weren't changed, only the file locations.

50 files changed:
src/theory/Makefile.am
src/theory/arrays/theory_arrays_instantiator.cpp
src/theory/candidate_generator.cpp [deleted file]
src/theory/candidate_generator.h [deleted file]
src/theory/datatypes/theory_datatypes_instantiator.cpp
src/theory/inst_match.cpp [deleted file]
src/theory/inst_match.h [deleted file]
src/theory/instantiator_default.cpp [deleted file]
src/theory/instantiator_default.h [deleted file]
src/theory/quantifiers/Makefile.am
src/theory/quantifiers/candidate_generator.cpp [new file with mode: 0644]
src/theory/quantifiers/candidate_generator.h [new file with mode: 0644]
src/theory/quantifiers/first_order_model.h
src/theory/quantifiers/inst_match.cpp [new file with mode: 0644]
src/theory/quantifiers/inst_match.h [new file with mode: 0644]
src/theory/quantifiers/instantiation_engine.h
src/theory/quantifiers/instantiator_default.cpp [new file with mode: 0644]
src/theory/quantifiers/instantiator_default.h [new file with mode: 0644]
src/theory/quantifiers/model_builder.h
src/theory/quantifiers/model_engine.h
src/theory/quantifiers/relevant_domain.h
src/theory/quantifiers/rep_set_iterator.h
src/theory/quantifiers/term_database.h
src/theory/quantifiers/theory_quantifiers_instantiator.h
src/theory/quantifiers/trigger.cpp [new file with mode: 0644]
src/theory/quantifiers/trigger.h [new file with mode: 0644]
src/theory/quantifiers_engine.cpp
src/theory/quantifiers_engine.h
src/theory/rewriterules/Makefile.am
src/theory/rewriterules/rr_candidate_generator.cpp [new file with mode: 0644]
src/theory/rewriterules/rr_candidate_generator.h [new file with mode: 0644]
src/theory/rewriterules/rr_inst_match.cpp [new file with mode: 0644]
src/theory/rewriterules/rr_inst_match.h [new file with mode: 0644]
src/theory/rewriterules/rr_inst_match_impl.h [new file with mode: 0644]
src/theory/rewriterules/rr_trigger.cpp [new file with mode: 0644]
src/theory/rewriterules/rr_trigger.h [new file with mode: 0644]
src/theory/rewriterules/theory_rewriterules.h
src/theory/rr_candidate_generator.cpp [deleted file]
src/theory/rr_candidate_generator.h [deleted file]
src/theory/rr_inst_match.cpp [deleted file]
src/theory/rr_inst_match.h [deleted file]
src/theory/rr_inst_match_impl.h [deleted file]
src/theory/rr_trigger.cpp [deleted file]
src/theory/rr_trigger.h [deleted file]
src/theory/theory.cpp
src/theory/trigger.cpp [deleted file]
src/theory/trigger.h [deleted file]
src/theory/uf/inst_strategy.h
src/theory/uf/theory_uf_instantiator.cpp
src/theory/uf/theory_uf_instantiator.h

index 7a4cde04df43cbd13e3a10a16f882199156a26cc..8f6ab76c2c1796798ed837d50a8913701d60fed8 100644 (file)
@@ -38,23 +38,8 @@ libtheory_la_SOURCES = \
        unconstrained_simplifier.cpp \
        quantifiers_engine.h \
        quantifiers_engine.cpp \
-       instantiator_default.h \
-       instantiator_default.cpp \
-       rr_inst_match.h \
-       rr_inst_match_impl.h \
-       rr_inst_match.cpp \
-       rr_trigger.h \
-       rr_trigger.cpp \
-       rr_candidate_generator.h \
-       rr_candidate_generator.cpp \
-       inst_match.h \
-       inst_match.cpp \
-       trigger.h \
-       trigger.cpp \
        model.h \
-       model.cpp \
-       candidate_generator.h \
-       candidate_generator.cpp
+       model.cpp
 
 nodist_libtheory_la_SOURCES = \
        rewriter_tables.h \
index f5a7227377db48c1f28410156738f7695760c55a..844a11c317f823a0e562e39f297e013539f47a28 100644 (file)
@@ -18,7 +18,7 @@
 #include "theory/arrays/theory_arrays_instantiator.h"
 #include "theory/arrays/theory_arrays.h"
 #include "theory/quantifiers/options.h"
-#include "theory/rr_candidate_generator.h"
+#include "theory/rewriterules/rr_candidate_generator.h"
 
 using namespace std;
 using namespace CVC4;
diff --git a/src/theory/candidate_generator.cpp b/src/theory/candidate_generator.cpp
deleted file mode 100644 (file)
index de98d70..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*********************                                                        */
-/*! \file candidate_generator.cpp
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: mdeters
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Implementation of theory uf candidate generator class
- **/
-
-#include "theory/candidate_generator.h"
-#include "theory/theory_engine.h"
-#include "theory/uf/theory_uf.h"
-#include "theory/quantifiers/term_database.h"
-#include "theory/inst_match.h"
-#include "theory/quantifiers_engine.h"
-
-using namespace std;
-using namespace CVC4;
-using namespace CVC4::kind;
-using namespace CVC4::context;
-using namespace CVC4::theory;
-using namespace CVC4::theory::inst;
-
-bool CandidateGenerator::isLegalCandidate( Node n ){
-  return ( !n.getAttribute(NoMatchAttribute()) && ( !options::cbqi() || !n.hasAttribute(InstConstantAttribute()) ) );
-}
-
-void CandidateGeneratorQueue::addCandidate( Node n ) {
-  if( isLegalCandidate( n ) ){
-    d_candidates.push_back( n );
-  }
-}
-
-void CandidateGeneratorQueue::reset( Node eqc ){
-  if( d_candidate_index>0 ){
-    d_candidates.erase( d_candidates.begin(), d_candidates.begin() + d_candidate_index );
-    d_candidate_index = 0;
-  }
-  if( !eqc.isNull() ){
-    d_candidates.push_back( eqc );
-  }
-}
-Node CandidateGeneratorQueue::getNextCandidate(){
-  if( d_candidate_index<(int)d_candidates.size() ){
-    Node n = d_candidates[d_candidate_index];
-    d_candidate_index++;
-    return n;
-  }else{
-    d_candidate_index = 0;
-    d_candidates.clear();
-    return Node::null();
-  }
-}
-
-#if 0
-
-CandidateGeneratorQE::CandidateGeneratorQE( QuantifiersEngine* qe, Node op ) :
-  d_op( op ), d_qe( qe ), d_term_iter( -2 ){
-  Assert( !d_op.isNull() );
-}
-void CandidateGeneratorQE::resetInstantiationRound(){
-  d_term_iter_limit = d_qe->getTermDatabase()->d_op_map[d_op].size();
-}
-
-void CandidateGeneratorQE::reset( Node eqc ){
-  if( eqc.isNull() ){
-    d_term_iter = 0;
-  }else{
-    //create an equivalence class iterator in eq class eqc
-    if( d_qe->getEqualityQuery()->getEngine()->hasTerm( eqc ) ){
-      eqc = d_qe->getEqualityQuery()->getEngine()->getRepresentative( eqc );
-      d_eqc = eq::EqClassIterator( eqc, d_qe->getEqualityQuery()->getEngine() );
-      d_retNode = Node::null();
-    }else{
-      d_retNode = eqc;
-    }
-    d_term_iter = -1;
-  }
-}
-
-Node CandidateGeneratorQE::getNextCandidate(){
-  if( d_term_iter>=0 ){
-    //get next candidate term in the uf term database
-    while( d_term_iter<d_term_iter_limit ){
-      Node n = d_qe->getTermDatabase()->d_op_map[d_op][d_term_iter];
-      d_term_iter++;
-      if( isLegalCandidate( n ) ){
-        return n;
-      }
-    }
-  }else if( d_term_iter==-1 ){
-    if( d_retNode.isNull() ){
-      //get next candidate term in equivalence class
-      while( !d_eqc.isFinished() ){
-        Node n = (*d_eqc);
-        ++d_eqc;
-        if( n.hasOperator() && n.getOperator()==d_op ){
-          if( isLegalCandidate( n ) ){
-            return n;
-          }
-        }
-      }
-    }else{
-      Node ret;
-      if( d_retNode.hasOperator() && d_retNode.getOperator()==d_op ){
-        ret = d_retNode;
-      }
-      d_term_iter = -2; //done returning matches
-      return ret;
-    }
-  }
-  return Node::null();
-}
-
-#else
-
-
-CandidateGeneratorQE::CandidateGeneratorQE( QuantifiersEngine* qe, Node op ) :
-  d_op( op ), d_qe( qe ), d_term_iter( -1 ){
-  Assert( !d_op.isNull() );
-}
-void CandidateGeneratorQE::resetInstantiationRound(){
-  d_term_iter_limit = d_qe->getTermDatabase()->d_op_map[d_op].size();
-}
-
-void CandidateGeneratorQE::reset( Node eqc ){
-  d_term_iter = 0;
-  if( eqc.isNull() ){
-    d_using_term_db = true;
-  }else{
-    //create an equivalence class iterator in eq class eqc
-    d_eqc.clear();
-    d_qe->getEqualityQuery()->getEquivalenceClass( eqc, d_eqc );
-    d_using_term_db = false;
-  }
-}
-
-Node CandidateGeneratorQE::getNextCandidate(){
-  if( d_term_iter>=0 ){
-    if( d_using_term_db ){
-      //get next candidate term in the uf term database
-      while( d_term_iter<d_term_iter_limit ){
-        Node n = d_qe->getTermDatabase()->d_op_map[d_op][d_term_iter];
-        d_term_iter++;
-        if( isLegalCandidate( n ) ){
-          return n;
-        }
-      }
-    }else{
-      while( d_term_iter<(int)d_eqc.size() ){
-        Node n = d_eqc[d_term_iter];
-        d_term_iter++;
-        if( n.hasOperator() && n.getOperator()==d_op ){
-          if( isLegalCandidate( n ) ){
-            return n;
-          }
-        }
-      }
-    }
-  }
-  return Node::null();
-}
-
-#endif
-
-//CandidateGeneratorQEDisequal::CandidateGeneratorQEDisequal( QuantifiersEngine* qe, Node eqc ) :
-//  d_qe( qe ), d_eq_class( eqc ){
-//  d_eci = NULL;
-//}
-//void CandidateGeneratorQEDisequal::resetInstantiationRound(){
-//
-//}
-////we will iterate over all terms that are disequal from eqc
-//void CandidateGeneratorQEDisequal::reset( Node eqc ){
-//  //Assert( !eqc.isNull() );
-//  ////begin iterating over equivalence classes that are disequal from eqc
-//  //d_eci = d_ith->getEquivalenceClassInfo( eqc );
-//  //if( d_eci ){
-//  //  d_eqci_iter = d_eci->d_disequal.begin();
-//  //}
-//}
-//Node CandidateGeneratorQEDisequal::getNextCandidate(){
-//  //if( d_eci ){
-//  //  while( d_eqci_iter != d_eci->d_disequal.end() ){
-//  //    if( (*d_eqci_iter).second ){
-//  //      //we have an equivalence class that is disequal from eqc
-//  //      d_cg->reset( (*d_eqci_iter).first );
-//  //      Node n = d_cg->getNextCandidate();
-//  //      //if there is a candidate in this equivalence class, return it
-//  //      if( !n.isNull() ){
-//  //        return n;
-//  //      }
-//  //    }
-//  //    ++d_eqci_iter;
-//  //  }
-//  //}
-//  return Node::null();
-//}
-
-
-CandidateGeneratorQELitEq::CandidateGeneratorQELitEq( QuantifiersEngine* qe, Node mpat ) :
-  d_match_pattern( mpat ), d_qe( qe ){
-
-}
-void CandidateGeneratorQELitEq::resetInstantiationRound(){
-
-}
-void CandidateGeneratorQELitEq::reset( Node eqc ){
-  d_eq = eq::EqClassesIterator( d_qe->getEqualityQuery()->getEngine() );
-}
-Node CandidateGeneratorQELitEq::getNextCandidate(){
-  while( d_eq.isFinished() ){
-    Node n = (*d_eq);
-    ++d_eq;
-    if( n.getType()==d_match_pattern[0].getType() ){
-      //an equivalence class with the same type as the pattern, return reflexive equality
-      return NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), n, n );
-    }
-  }
-  return Node::null();
-}
-
-
-CandidateGeneratorQELitDeq::CandidateGeneratorQELitDeq( QuantifiersEngine* qe, Node mpat ) :
-  d_match_pattern( mpat ), d_qe( qe ){
-
-}
-void CandidateGeneratorQELitDeq::resetInstantiationRound(){
-
-}
-void CandidateGeneratorQELitDeq::reset( Node eqc ){
-  Node false_term = d_qe->getEqualityQuery()->getEngine()->getRepresentative( NodeManager::currentNM()->mkConst<bool>(false) );
-  d_eqc_false = eq::EqClassIterator( false_term, d_qe->getEqualityQuery()->getEngine() );
-}
-Node CandidateGeneratorQELitDeq::getNextCandidate(){
-  //get next candidate term in equivalence class
-  while( !d_eqc_false.isFinished() ){
-    Node n = (*d_eqc_false);
-    ++d_eqc_false;
-    if( n.getKind()==d_match_pattern.getKind() ){
-      //found an iff or equality, try to match it
-      //DO_THIS: cache to avoid redundancies?
-      //DO_THIS: do we need to try the symmetric equality for n?  or will it also exist in the eq class of false?
-      return n;
-    }
-  }
-  return Node::null();
-}
diff --git a/src/theory/candidate_generator.h b/src/theory/candidate_generator.h
deleted file mode 100644 (file)
index 134b0e1..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*********************                                                        */
-/*! \file candidate_generator.h
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: none
- ** Minor contributors (to current version): mdeters
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Theory uf candidate generator
- **/
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__CANDIDATE_GENERATOR_H
-#define __CVC4__CANDIDATE_GENERATOR_H
-
-#include "theory/theory.h"
-#include "theory/uf/equality_engine.h"
-
-namespace CVC4 {
-namespace theory {
-
-class QuantifiersEngine;
-
-namespace inst {
-
-/** base class for generating candidates for matching */
-class CandidateGenerator {
-public:
-  CandidateGenerator(){}
-  ~CandidateGenerator(){}
-
-  /** Get candidates functions.  These set up a context to get all match candidates.
-      cg->reset( eqc );
-      do{
-        Node cand = cg->getNextCandidate();
-        //.......
-      }while( !cand.isNull() );
-
-      eqc is the equivalence class you are searching in
-  */
-  virtual void reset( Node eqc ) = 0;
-  virtual Node getNextCandidate() = 0;
-  /** add candidate to list of nodes returned by this generator */
-  virtual void addCandidate( Node n ) {}
-  /** call this at the beginning of each instantiation round */
-  virtual void resetInstantiationRound() = 0;
-public:
-  /** legal candidate */
-  static bool isLegalCandidate( Node n );
-};/* class CandidateGenerator */
-
-/** candidate generator queue (for manual candidate generation) */
-class CandidateGeneratorQueue : public CandidateGenerator {
-private:
-  std::vector< Node > d_candidates;
-  int d_candidate_index;
-public:
-  CandidateGeneratorQueue() : d_candidate_index( 0 ){}
-  ~CandidateGeneratorQueue(){}
-
-  void addCandidate( Node n );
-
-  void resetInstantiationRound(){}
-  void reset( Node eqc );
-  Node getNextCandidate();
-};/* class CandidateGeneratorQueue */
-
-class CandidateGeneratorQEDisequal;
-
-#if 0
-
-class CandidateGeneratorQE : public CandidateGenerator
-{
-  friend class CandidateGeneratorQEDisequal;
-private:
-  //operator you are looking for
-  Node d_op;
-  //instantiator pointer
-  QuantifiersEngine* d_qe;
-  //the equality class iterator
-  eq::EqClassIterator d_eqc;
-  int d_term_iter;
-  int d_term_iter_limit;
-private:
-  Node d_retNode;
-public:
-  CandidateGeneratorQE( QuantifiersEngine* qe, Node op );
-  ~CandidateGeneratorQE(){}
-
-  void resetInstantiationRound();
-  void reset( Node eqc );
-  Node getNextCandidate();
-};
-
-#else
-
-class CandidateGeneratorQE : public CandidateGenerator
-{
-  friend class CandidateGeneratorQEDisequal;
-private:
-  //operator you are looking for
-  Node d_op;
-  //instantiator pointer
-  QuantifiersEngine* d_qe;
-  //the equality class iterator
-  std::vector< Node > d_eqc;
-  int d_term_iter;
-  int d_term_iter_limit;
-  bool d_using_term_db;
-public:
-  CandidateGeneratorQE( QuantifiersEngine* qe, Node op );
-  ~CandidateGeneratorQE(){}
-
-  void resetInstantiationRound();
-  void reset( Node eqc );
-  Node getNextCandidate();
-};
-
-#endif
-
-//class CandidateGeneratorQEDisequal : public CandidateGenerator
-//{
-//private:
-//  //equivalence class
-//  Node d_eq_class;
-//  //equivalence class info
-//  EqClassInfo* d_eci;
-//  //equivalence class iterator
-//  EqClassInfo::BoolMap::const_iterator d_eqci_iter;
-//  //instantiator pointer
-//  QuantifiersEngine* d_qe;
-//public:
-//  CandidateGeneratorQEDisequal( QuantifiersEngine* qe, Node eqc );
-//  ~CandidateGeneratorQEDisequal(){}
-//
-//  void resetInstantiationRound();
-//  void reset( Node eqc );   //should be what you want to be disequal from
-//  Node getNextCandidate();
-//};
-
-class CandidateGeneratorQELitEq : public CandidateGenerator
-{
-private:
-  //the equality classes iterator
-  eq::EqClassesIterator d_eq;
-  //equality you are trying to match equalities for
-  Node d_match_pattern;
-  //einstantiator pointer
-  QuantifiersEngine* d_qe;
-public:
-  CandidateGeneratorQELitEq( QuantifiersEngine* qe, Node mpat );
-  ~CandidateGeneratorQELitEq(){}
-
-  void resetInstantiationRound();
-  void reset( Node eqc );
-  Node getNextCandidate();
-};
-
-class CandidateGeneratorQELitDeq : public CandidateGenerator
-{
-private:
-  //the equality class iterator for false
-  eq::EqClassIterator d_eqc_false;
-  //equality you are trying to match disequalities for
-  Node d_match_pattern;
-  //einstantiator pointer
-  QuantifiersEngine* d_qe;
-public:
-  CandidateGeneratorQELitDeq( QuantifiersEngine* qe, Node mpat );
-  ~CandidateGeneratorQELitDeq(){}
-
-  void resetInstantiationRound();
-  void reset( Node eqc );
-  Node getNextCandidate();
-};
-
-}/* CVC4::theory::inst namespace */
-}/* CVC4::theory namespace */
-}/* CVC4 namespace */
-
-#endif /* __CVC4__THEORY_UF_INSTANTIATOR_H */
index 8ecf37fe2a45373178c160456f90a09778d1d45f..23f3e8950520cf91310b77a271d7212876302d28 100644 (file)
@@ -19,7 +19,7 @@
 #include "theory/theory_engine.h"
 #include "theory/quantifiers/options.h"
 #include "theory/quantifiers/term_database.h"
-#include "theory/rr_candidate_generator.h"
+#include "theory/rewriterules/rr_candidate_generator.h"
 
 using namespace std;
 using namespace CVC4;
diff --git a/src/theory/inst_match.cpp b/src/theory/inst_match.cpp
deleted file mode 100644 (file)
index f7c21c5..0000000
+++ /dev/null
@@ -1,880 +0,0 @@
-/*********************                                                        */
-/*! \file inst_match.cpp
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: none
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Implementation of inst match class
- **/
-
-#include "theory/inst_match.h"
-#include "theory/theory_engine.h"
-#include "theory/quantifiers_engine.h"
-#include "theory/candidate_generator.h"
-#include "theory/uf/theory_uf_instantiator.h"
-#include "theory/uf/equality_engine.h"
-#include "theory/quantifiers/options.h"
-#include "theory/quantifiers/model_engine.h"
-#include "theory/quantifiers/term_database.h"
-#include "theory/quantifiers/first_order_model.h"
-#include "theory/quantifiers/term_database.h"
-
-using namespace std;
-using namespace CVC4;
-using namespace CVC4::kind;
-using namespace CVC4::context;
-using namespace CVC4::theory;
-using namespace CVC4::theory::inst;
-
-
-InstMatch::InstMatch() {
-}
-
-InstMatch::InstMatch( InstMatch* m ) {
-  d_map = m->d_map;
-}
-
-bool InstMatch::setMatch( EqualityQuery* q, TNode v, TNode m, bool & set ){
-  std::map< Node, Node >::iterator vn = d_map.find( v );
-  if( vn==d_map.end() ){
-    set = true;
-    this->set(v,m);
-    Debug("matching-debug") << "Add partial " << v << "->" << m << std::endl;
-    return true;
-  }else{
-    set = false;
-    return q->areEqual( vn->second, m );
-  }
-}
-
-bool InstMatch::setMatch( EqualityQuery* q, TNode v, TNode m ){
-  bool set;
-  return setMatch(q,v,m,set);
-}
-
-bool InstMatch::add( InstMatch& m ){
-  for( std::map< Node, Node >::iterator it = m.d_map.begin(); it != m.d_map.end(); ++it ){
-    if( d_map.find( it->first )==d_map.end() ){
-      d_map[it->first] = it->second;
-    }
-  }
-  return true;
-}
-
-bool InstMatch::merge( EqualityQuery* q, InstMatch& m ){
-  for( std::map< Node, Node >::iterator it = m.d_map.begin(); it != m.d_map.end(); ++it ){
-    if( d_map.find( it->first )==d_map.end() ){
-      d_map[ it->first ] = it->second;
-    }else{
-      if( it->second!=d_map[it->first] ){
-        if( !q->areEqual( it->second, d_map[it->first] ) ){
-          d_map.clear();
-          return false;
-        }
-      }
-    }
-  }
-  return true;
-}
-
-void InstMatch::debugPrint( const char* c ){
-  for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){
-    Debug( c ) << "   " << it->first << " -> " << it->second << std::endl;
-  }
-  //if( !d_splits.empty() ){
-  //  Debug( c ) << "   Conditions: ";
-  //  for( std::map< Node, Node >::iterator it = d_splits.begin(); it !=d_splits.end(); ++it ){
-  //    Debug( c ) << it->first << " = " << it->second << " ";
-  //  }
-  //  Debug( c ) << std::endl;
-  //}
-}
-
-void InstMatch::makeComplete( Node f, QuantifiersEngine* qe ){
-  for( int i=0; i<(int)qe->getTermDatabase()->d_inst_constants[f].size(); i++ ){
-    Node ic = qe->getTermDatabase()->d_inst_constants[f][i];
-    if( d_map.find( ic )==d_map.end() ){
-      d_map[ ic ] = qe->getTermDatabase()->getFreeVariableForInstConstant( ic );
-    }
-  }
-}
-
-void InstMatch::makeInternal( QuantifiersEngine* qe ){
-  if( options::cbqi() ){
-    for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){
-      if( it->second.hasAttribute(InstConstantAttribute()) ){
-        d_map[ it->first ] = qe->getEqualityQuery()->getInternalRepresentative( it->second );
-        if( it->second.hasAttribute(InstConstantAttribute()) ){
-          d_map[ it->first ] = qe->getTermDatabase()->getFreeVariableForInstConstant( it->first );
-        }
-      }
-    }
-  }
-}
-
-void InstMatch::makeRepresentative( QuantifiersEngine* qe ){
-  for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){
-    d_map[ it->first ] = qe->getEqualityQuery()->getInternalRepresentative( it->second );
-    if( options::cbqi() && it->second.hasAttribute(InstConstantAttribute()) ){
-      d_map[ it->first ] = qe->getTermDatabase()->getFreeVariableForInstConstant( it->first );
-    }
-  }
-}
-
-void InstMatch::applyRewrite(){
-  for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){
-    it->second = Rewriter::rewrite(it->second);
-  }
-}
-
-void InstMatch::computeTermVec( QuantifiersEngine* qe, const std::vector< Node >& vars, std::vector< Node >& match ){
-  for( int i=0; i<(int)vars.size(); i++ ){
-    std::map< Node, Node >::iterator it = d_map.find( vars[i] );
-    if( it!=d_map.end() && !it->second.isNull() ){
-      match.push_back( it->second );
-    }else{
-      match.push_back( qe->getTermDatabase()->getFreeVariableForInstConstant( vars[i] ) );
-    }
-  }
-}
-void InstMatch::computeTermVec( const std::vector< Node >& vars, std::vector< Node >& match ){
-  for( int i=0; i<(int)vars.size(); i++ ){
-    match.push_back( d_map[ vars[i] ] );
-  }
-}
-
-
-/** 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;
-    Node n = m.get( qe->getTermDatabase()->getInstantiationConstant( f, i_index ) );
-    d_data[n].addInstMatch2( qe, f, m, index+1, imtio );
-  }
-}
-
-/** exists match */
-bool InstMatchTrie::existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, int index, ImtIndexOrder* imtio ){
-  if( long(index)==long(f[0].getNumChildren()) || ( imtio && long(index)==long(imtio->d_order.size()) ) ){
-    return true;
-  }else{
-    int i_index = imtio ? imtio->d_order[index] : index;
-    Node n = m.get( qe->getTermDatabase()->getInstantiationConstant( f, i_index ) );
-    std::map< Node, InstMatchTrie >::iterator it = d_data.find( n );
-    if( it!=d_data.end() ){
-      if( it->second.existsInstMatch( qe, f, m, modEq, index+1, imtio ) ){
-        return true;
-      }
-    }
-    if( modEq ){
-      //check modulo equality if any other instantiation match exists
-      if( 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.existsInstMatch( qe, f, m, modEq, index+1, imtio ) ){
-                return true;
-              }
-            }
-          }
-          ++eqc;
-        }
-      }
-      //for( std::map< Node, InstMatchTrie >::iterator itc = d_data.begin(); itc != d_data.end(); ++itc ){
-      //  if( itc->first!=n && qe->getEqualityQuery()->areEqual( n, itc->first ) ){
-      //    if( itc->second.existsInstMatch( qe, f, m, modEq, index+1 ) ){
-      //      return true;
-      //    }
-      //  }
-      //}
-    }
-    return false;
-  }
-}
-
-bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, ImtIndexOrder* imtio ){
-  if( !existsInstMatch( qe, f, m, modEq, 0, imtio ) ){
-    addInstMatch2( qe, f, m, 0, imtio );
-    return true;
-  }else{
-    return false;
-  }
-}
-
-InstMatchGenerator::InstMatchGenerator( Node pat, QuantifiersEngine* qe, int matchPolicy ) : d_matchPolicy( matchPolicy ){
-  initializePattern( pat, qe );
-}
-
-InstMatchGenerator::InstMatchGenerator( std::vector< Node >& pats, QuantifiersEngine* qe, int matchPolicy ) : d_matchPolicy( matchPolicy ){
-  if( pats.size()==1 ){
-    initializePattern( pats[0], qe );
-  }else{
-    initializePatterns( pats, qe );
-  }
-}
-
-void InstMatchGenerator::initializePatterns( std::vector< Node >& pats, QuantifiersEngine* qe ){
-  int childMatchPolicy = d_matchPolicy==MATCH_GEN_EFFICIENT_E_MATCH ? 0 : d_matchPolicy;
-  for( int i=0; i<(int)pats.size(); i++ ){
-    d_children.push_back( new InstMatchGenerator( pats[i], qe, childMatchPolicy ) );
-  }
-  d_pattern = Node::null();
-  d_match_pattern = Node::null();
-  d_cg = NULL;
-}
-
-void InstMatchGenerator::initializePattern( Node pat, QuantifiersEngine* qe ){
-  Debug("inst-match-gen") << "Pattern term is " << pat << std::endl;
-  Assert( pat.hasAttribute(InstConstantAttribute()) );
-  d_pattern = pat;
-  d_match_pattern = pat;
-  if( d_match_pattern.getKind()==NOT ){
-    //we want to add the children of the NOT
-    d_match_pattern = d_pattern[0];
-  }
-  if( d_match_pattern.getKind()==IFF || d_match_pattern.getKind()==EQUAL ){
-    if( !d_match_pattern[0].hasAttribute(InstConstantAttribute()) ){
-      Assert( d_match_pattern[1].hasAttribute(InstConstantAttribute()) );
-      //swap sides
-      d_pattern = NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), d_match_pattern[1], d_match_pattern[0] );
-      d_pattern = pat.getKind()==NOT ? d_pattern.notNode() : d_pattern;
-      if( pat.getKind()!=NOT ){   //TEMPORARY until we do better implementation of disequality matching
-        d_match_pattern = d_match_pattern[1];
-      }else{
-        d_match_pattern = d_pattern[0][0];
-      }
-    }else if( !d_match_pattern[1].hasAttribute(InstConstantAttribute()) ){
-      Assert( d_match_pattern[0].hasAttribute(InstConstantAttribute()) );
-      if( pat.getKind()!=NOT ){   //TEMPORARY until we do better implementation of disequality matching
-        d_match_pattern = d_match_pattern[0];
-      }
-    }
-  }
-  int childMatchPolicy = MATCH_GEN_DEFAULT;
-  for( int i=0; i<(int)d_match_pattern.getNumChildren(); i++ ){
-    if( d_match_pattern[i].hasAttribute(InstConstantAttribute()) ){
-      if( d_match_pattern[i].getKind()!=INST_CONSTANT ){
-        d_children.push_back( new InstMatchGenerator( d_match_pattern[i], qe, childMatchPolicy ) );
-        d_children_index.push_back( i );
-      }
-    }
-  }
-
-  Debug("inst-match-gen") << "Pattern is " << d_pattern << ", match pattern is " << d_match_pattern << std::endl;
-
-  //create candidate generator
-  if( d_match_pattern.getKind()==EQUAL || d_match_pattern.getKind()==IFF ){
-    Assert( d_matchPolicy==MATCH_GEN_DEFAULT );
-    //we will be producing candidates via literal matching heuristics
-    if( d_pattern.getKind()!=NOT ){
-      //candidates will be all equalities
-      d_cg = new inst::CandidateGeneratorQELitEq( qe, d_match_pattern );
-    }else{
-      //candidates will be all disequalities
-      d_cg = new inst::CandidateGeneratorQELitDeq( qe, d_match_pattern );
-    }
-  }else if( d_pattern.getKind()==EQUAL || d_pattern.getKind()==IFF || d_pattern.getKind()==NOT ){
-    Assert( d_matchPolicy==MATCH_GEN_DEFAULT );
-    if( d_pattern.getKind()==NOT ){
-      Unimplemented("Disequal generator unimplemented");
-    }else{
-      Assert( Trigger::isAtomicTrigger( d_match_pattern ) );
-      //we are matching only in a particular equivalence class
-      d_cg = new inst::CandidateGeneratorQE( qe, d_match_pattern.getOperator() );
-      //store the equivalence class that we will call d_cg->reset( ... ) on
-      d_eq_class = d_pattern[1];
-    }
-  }else if( Trigger::isAtomicTrigger( d_match_pattern ) ){
-    //if( d_matchPolicy==MATCH_GEN_EFFICIENT_E_MATCH ){
-      //Warning() << "Currently efficient e matching is not taken into account for quantifiers: " << d_pattern << std::endl;
-    //}
-    //we will be scanning lists trying to find d_match_pattern.getOperator()
-    d_cg = new inst::CandidateGeneratorQE( qe, d_match_pattern.getOperator() );
-  }else{
-    d_cg = new CandidateGeneratorQueue;
-    if( !Trigger::getPatternArithmetic( d_match_pattern.getAttribute(InstConstantAttribute()), d_match_pattern, d_arith_coeffs ) ){
-      Debug("inst-match-gen") << "(?) Unknown matching pattern is " << d_match_pattern << std::endl;
-      Warning() << "(?) Unknown matching pattern is " << d_match_pattern << std::endl;
-      d_matchPolicy = MATCH_GEN_INTERNAL_ERROR;
-    }else{
-      Debug("matching-arith") << "Generated arithmetic pattern for " << d_match_pattern << ": " << std::endl;
-      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
-        Debug("matching-arith") << "   " << it->first << " -> " << it->second << std::endl;
-      }
-      //we will treat this as match gen internal arithmetic
-      d_matchPolicy = MATCH_GEN_INTERNAL_ARITHMETIC;
-    }
-  }
-}
-
-/** get match (not modulo equality) */
-bool InstMatchGenerator::getMatch( Node t, InstMatch& m, QuantifiersEngine* qe ){
-  Debug("matching") << "Matching " << t << " against pattern " << d_match_pattern << " ("
-                    << m.size() << ")" << ", " << d_children.size() << std::endl;
-  Assert( !d_match_pattern.isNull() );
-  if( qe->d_optMatchIgnoreModelBasis && t.getAttribute(ModelBasisAttribute()) ){
-    return true;
-  }else if( d_matchPolicy==MATCH_GEN_INTERNAL_ARITHMETIC ){
-    return getMatchArithmetic( t, m, qe );
-  }else if( d_matchPolicy==MATCH_GEN_INTERNAL_ERROR ){
-    return false;
-  }else{
-    EqualityQuery* q = qe->getEqualityQuery();
-    //add m to partial match vector
-    std::vector< InstMatch > partial;
-    partial.push_back( InstMatch( &m ) );
-    //if t is null
-    Assert( !t.isNull() );
-    Assert( !t.hasAttribute(InstConstantAttribute()) );
-    Assert( t.getKind()==d_match_pattern.getKind() );
-    Assert( !Trigger::isAtomicTrigger( d_match_pattern ) || t.getOperator()==d_match_pattern.getOperator() );
-    //first, check if ground arguments are not equal, or a match is in conflict
-    for( int i=0; i<(int)d_match_pattern.getNumChildren(); i++ ){
-      if( d_match_pattern[i].hasAttribute(InstConstantAttribute()) ){
-        if( d_match_pattern[i].getKind()==INST_CONSTANT ){
-          if( !partial[0].setMatch( q, d_match_pattern[i], t[i] ) ){
-            //match is in conflict
-            Debug("matching-debug") << "Match in conflict " << t[i] << " and "
-                                    << d_match_pattern[i] << " because "
-                                    << partial[0].get(d_match_pattern[i])
-                                    << std::endl;
-            Debug("matching-fail") << "Match fail: " << partial[0].get(d_match_pattern[i]) << " and " << t[i] << std::endl;
-            return false;
-          }
-        }
-      }else{
-        if( !q->areEqual( d_match_pattern[i], t[i] ) ){
-          Debug("matching-fail") << "Match fail arg: " << d_match_pattern[i] << " and " << t[i] << std::endl;
-          //ground arguments are not equal
-          return false;
-        }
-      }
-    }
-    //now, fit children into match
-    //we will be requesting candidates for matching terms for each child
-    std::vector< Node > reps;
-    for( int i=0; i<(int)d_children.size(); i++ ){
-      Node rep = q->getRepresentative( t[ d_children_index[i] ] );
-      reps.push_back( rep );
-      d_children[i]->d_cg->reset( rep );
-    }
-
-    //combine child matches
-    int index = 0;
-    while( index>=0 && index<(int)d_children.size() ){
-      partial.push_back( InstMatch( &partial[index] ) );
-      if( d_children[index]->getNextMatch2( partial[index+1], qe ) ){
-        index++;
-      }else{
-        d_children[index]->d_cg->reset( reps[index] );
-        partial.pop_back();
-        if( !partial.empty() ){
-          partial.pop_back();
-        }
-        index--;
-      }
-    }
-    if( index>=0 ){
-      m = partial.back();
-      return true;
-    }else{
-      return false;
-    }
-  }
-}
-
-bool InstMatchGenerator::getNextMatch2( InstMatch& m, QuantifiersEngine* qe, bool saveMatched ){
-  bool success = false;
-  Node t;
-  do{
-    //get the next candidate term t
-    t = d_cg->getNextCandidate();
-    //if t not null, try to fit it into match m
-    if( !t.isNull() && t.getType()==d_match_pattern.getType() ){
-      success = getMatch( t, m, qe );
-    }
-  }while( !success && !t.isNull() );
-  if (saveMatched) m.d_matched = t;
-  return success;
-}
-
-bool InstMatchGenerator::getMatchArithmetic( Node t, InstMatch& m, QuantifiersEngine* qe ){
-  Debug("matching-arith") << "Matching " << t << " " << d_match_pattern << std::endl;
-  if( !d_arith_coeffs.empty() ){
-    NodeBuilder<> tb(kind::PLUS);
-    Node ic = Node::null();
-    for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
-      Debug("matching-arith") << it->first << " -> " << it->second << std::endl;
-      if( !it->first.isNull() ){
-        if( m.find( it->first )==m.end() ){
-          //see if we can choose this to set
-          if( ic.isNull() && ( it->second.isNull() || !it->first.getType().isInteger() ) ){
-            ic = it->first;
-          }
-        }else{
-          Debug("matching-arith") << "already set " << m.get( it->first ) << std::endl;
-          Node tm = m.get( it->first );
-          if( !it->second.isNull() ){
-            tm = NodeManager::currentNM()->mkNode( MULT, it->second, tm );
-          }
-          tb << tm;
-        }
-      }else{
-        tb << it->second;
-      }
-    }
-    if( !ic.isNull() ){
-      Node tm;
-      if( tb.getNumChildren()==0 ){
-        tm = t;
-      }else{
-        tm = tb.getNumChildren()==1 ? tb.getChild( 0 ) : tb;
-        tm = NodeManager::currentNM()->mkNode( MINUS, t, tm );
-      }
-      if( !d_arith_coeffs[ ic ].isNull() ){
-        Assert( !ic.getType().isInteger() );
-        Node coeff = NodeManager::currentNM()->mkConst( Rational(1) / d_arith_coeffs[ ic ].getConst<Rational>() );
-        tm = NodeManager::currentNM()->mkNode( MULT, coeff, tm );
-      }
-      m.set( ic, Rewriter::rewrite( tm ));
-      //set the rest to zeros
-      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
-        if( !it->first.isNull() ){
-          if( m.find( it->first )==m.end() ){
-            m.set( it->first, NodeManager::currentNM()->mkConst( Rational(0) ) );
-          }
-        }
-      }
-      Debug("matching-arith") << "Setting " << ic << " to " << tm << std::endl;
-      return true;
-    }else{
-      return false;
-    }
-  }else{
-    return false;
-  }
-}
-
-
-/** reset instantiation round */
-void InstMatchGenerator::resetInstantiationRound( QuantifiersEngine* qe ){
-  if( d_match_pattern.isNull() ){
-    for( int i=0; i<(int)d_children.size(); i++ ){
-      d_children[i]->resetInstantiationRound( qe );
-    }
-  }else{
-    if( d_cg ){
-      d_cg->resetInstantiationRound();
-    }
-  }
-}
-
-void InstMatchGenerator::reset( Node eqc, QuantifiersEngine* qe ){
-  if( d_match_pattern.isNull() ){
-    for( int i=0; i<(int)d_children.size(); i++ ){
-      d_children[i]->reset( eqc, qe );
-    }
-    d_partial.clear();
-  }else{
-    if( !d_eq_class.isNull() ){
-      //we have a specific equivalence class in mind
-      //we are producing matches for f(E) ~ t, where E is a non-ground vector of terms, and t is a ground term
-      //just look in equivalence class of the RHS
-      d_cg->reset( d_eq_class );
-    }else{
-      d_cg->reset( eqc );
-    }
-  }
-}
-
-bool InstMatchGenerator::getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-  m.d_matched = Node::null();
-  if( d_match_pattern.isNull() ){
-    int index = (int)d_partial.size();
-    while( index>=0 && index<(int)d_children.size() ){
-      if( index>0 ){
-        d_partial.push_back( InstMatch( &d_partial[index-1] ) );
-      }else{
-        d_partial.push_back( InstMatch() );
-      }
-      if( d_children[index]->getNextMatch( d_partial[index], qe ) ){
-        index++;
-      }else{
-        d_children[index]->reset( Node::null(), qe );
-        d_partial.pop_back();
-        if( !d_partial.empty() ){
-          d_partial.pop_back();
-        }
-        index--;
-      }
-    }
-    if( index>=0 ){
-      m = d_partial.back();
-      d_partial.pop_back();
-      return true;
-    }else{
-      return false;
-    }
-  }else{
-    bool res = getNextMatch2( m, qe, true );
-    Assert(!res || !m.d_matched.isNull());
-    return res;
-  }
-}
-
-
-
-// Currently the implementation doesn't take into account that
-// variable should have the same value given.
-// TODO use the d_children way perhaps
-// TODO replace by a real dictionnary
-// We should create a real substitution? slower more precise
-// We don't do that often
-bool InstMatchGenerator::nonunifiable( TNode t0, const std::vector<Node> & vars){
-  if(d_match_pattern.isNull()) return true;
-
-  typedef std::vector<std::pair<TNode,TNode> > tstack;
-  tstack stack(1,std::make_pair(t0,d_match_pattern)); // t * pat
-
-  while(!stack.empty()){
-    const std::pair<TNode,TNode> p = stack.back(); stack.pop_back();
-    const TNode & t = p.first;
-    const TNode & pat = p.second;
-
-    // t or pat is a variable currently we consider that can match anything
-    if( find(vars.begin(),vars.end(),t) != vars.end() ) continue;
-    if( pat.getKind() == INST_CONSTANT ) continue;
-
-    // t and pat are nonunifiable
-    if( !Trigger::isAtomicTrigger( t ) || !Trigger::isAtomicTrigger( pat ) ) {
-      if(t == pat) continue;
-      else return true;
-    };
-    if( t.getOperator() != pat.getOperator() ) return true;
-
-    //put the children on the stack
-    for( size_t i=0; i < pat.getNumChildren(); i++ ){
-      stack.push_back(std::make_pair(t[i],pat[i]));
-    };
-  }
-  // The heuristic can't find non-unifiability
-  return false;
-}
-
-int InstMatchGenerator::addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe ){
-  //now, try to add instantiation for each match produced
-  int addedLemmas = 0;
-  InstMatch m;
-  while( getNextMatch( m, qe ) ){
-    //m.makeInternal( d_quantEngine->getEqualityQuery() );
-    m.add( baseMatch );
-    if( qe->addInstantiation( f, m ) ){
-      addedLemmas++;
-      if( qe->d_optInstLimitActive && qe->d_optInstLimit<=0 ){
-        return addedLemmas;
-      }
-    }
-    m.clear();
-  }
-  //return number of lemmas added
-  return addedLemmas;
-}
-
-int InstMatchGenerator::addTerm( Node f, Node t, QuantifiersEngine* qe ){
-  Assert( options::eagerInstQuant() );
-  if( !d_match_pattern.isNull() ){
-    InstMatch m;
-    if( getMatch( t, m, qe ) ){
-      if( qe->addInstantiation( f, m ) ){
-        return 1;
-      }
-    }
-  }else{
-    for( int i=0; i<(int)d_children.size(); i++ ){
-      d_children[i]->addTerm( f, t, qe );
-    }
-  }
-  return 0;
-}
-
-/** constructors */
-InstMatchGeneratorMulti::InstMatchGeneratorMulti( Node f, std::vector< Node >& pats, QuantifiersEngine* qe, int matchOption ) :
-d_f( f ){
-  Debug("smart-multi-trigger") << "Making smart multi-trigger for " << f << std::endl;
-  std::map< Node, std::vector< Node > > var_contains;
-  Trigger::getVarContains( f, pats, var_contains );
-  //convert to indicies
-  for( std::map< Node, std::vector< Node > >::iterator it = var_contains.begin(); it != var_contains.end(); ++it ){
-    Debug("smart-multi-trigger") << "Pattern " << it->first << " contains: ";
-    for( int i=0; i<(int)it->second.size(); i++ ){
-      Debug("smart-multi-trigger") << it->second[i] << " ";
-      int index = it->second[i].getAttribute(InstVarNumAttribute());
-      d_var_contains[ it->first ].push_back( index );
-      d_var_to_node[ index ].push_back( it->first );
-    }
-    Debug("smart-multi-trigger") << std::endl;
-  }
-  for( int i=0; i<(int)pats.size(); i++ ){
-    Node n = pats[i];
-    //make the match generator
-    d_children.push_back( new InstMatchGenerator( n, qe, matchOption ) );
-    //compute unique/shared variables
-    std::vector< int > unique_vars;
-    std::map< int, bool > shared_vars;
-    int numSharedVars = 0;
-    for( int j=0; j<(int)d_var_contains[n].size(); j++ ){
-      if( d_var_to_node[ d_var_contains[n][j] ].size()==1 ){
-        Debug("smart-multi-trigger") << "Var " << d_var_contains[n][j] << " is unique to " << pats[i] << std::endl;
-        unique_vars.push_back( d_var_contains[n][j] );
-      }else{
-        shared_vars[ d_var_contains[n][j] ] = true;
-        numSharedVars++;
-      }
-    }
-    //we use the latest shared variables, then unique variables
-    std::vector< int > vars;
-    int index = i==0 ? (int)(pats.size()-1) : (i-1);
-    while( numSharedVars>0 && index!=i ){
-      for( std::map< int, bool >::iterator it = shared_vars.begin(); it != shared_vars.end(); ++it ){
-        if( it->second ){
-          if( std::find( d_var_contains[ pats[index] ].begin(), d_var_contains[ pats[index] ].end(), it->first )!=
-              d_var_contains[ pats[index] ].end() ){
-            vars.push_back( it->first );
-            shared_vars[ it->first ] = false;
-            numSharedVars--;
-          }
-        }
-      }
-      index = index==0 ? (int)(pats.size()-1) : (index-1);
-    }
-    vars.insert( vars.end(), unique_vars.begin(), unique_vars.end() );
-    Debug("smart-multi-trigger") << "   Index[" << i << "]: ";
-    for( int i=0; i<(int)vars.size(); i++ ){
-      Debug("smart-multi-trigger") << vars[i] << " ";
-    }
-    Debug("smart-multi-trigger") << std::endl;
-    //make ordered inst match trie
-    InstMatchTrie::ImtIndexOrder* imtio = new InstMatchTrie::ImtIndexOrder;
-    imtio->d_order.insert( imtio->d_order.begin(), vars.begin(), vars.end() );
-    d_children_trie.push_back( InstMatchTrieOrdered( imtio ) );
-  }
-
-}
-
-/** reset instantiation round (call this whenever equivalence classes have changed) */
-void InstMatchGeneratorMulti::resetInstantiationRound( QuantifiersEngine* qe ){
-  for( int i=0; i<(int)d_children.size(); i++ ){
-    d_children[i]->resetInstantiationRound( qe );
-  }
-}
-
-/** reset, eqc is the equivalence class to search in (any if eqc=null) */
-void InstMatchGeneratorMulti::reset( Node eqc, QuantifiersEngine* qe ){
-  for( int i=0; i<(int)d_children.size(); i++ ){
-    d_children[i]->reset( eqc, qe );
-  }
-}
-
-int InstMatchGeneratorMulti::addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe ){
-  int addedLemmas = 0;
-  Debug("smart-multi-trigger") << "Process smart multi trigger" << std::endl;
-  for( int i=0; i<(int)d_children.size(); i++ ){
-    Debug("smart-multi-trigger") << "Calculate matches " << i << std::endl;
-    std::vector< InstMatch > newMatches;
-    InstMatch m;
-    while( d_children[i]->getNextMatch( m, qe ) ){
-      m.makeRepresentative( qe );
-      newMatches.push_back( InstMatch( &m ) );
-      m.clear();
-    }
-    for( int j=0; j<(int)newMatches.size(); j++ ){
-      processNewMatch( qe, newMatches[j], i, addedLemmas );
-    }
-  }
-  return addedLemmas;
-}
-
-void InstMatchGeneratorMulti::processNewMatch( QuantifiersEngine* qe, InstMatch& m, int fromChildIndex, int& addedLemmas ){
-  //see if these produce new matches
-  d_children_trie[fromChildIndex].addInstMatch( qe, d_f, m, true );
-  //possibly only do the following if we know that new matches will be produced?
-  //the issue is that instantiations are filtered in quantifiers engine, and so there is no guarentee that
-  // we can safely skip the following lines, even when we have already produced this match.
-  Debug("smart-multi-trigger") << "Child " << fromChildIndex << " produced match " << m << std::endl;
-  //process new instantiations
-  int childIndex = (fromChildIndex+1)%(int)d_children.size();
-  std::vector< IndexedTrie > unique_var_tries;
-  processNewInstantiations( qe, m, addedLemmas, d_children_trie[childIndex].getTrie(),
-                            unique_var_tries, 0, childIndex, fromChildIndex, true );
-}
-
-void InstMatchGeneratorMulti::processNewInstantiations( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas, InstMatchTrie* tr,
-                                                        std::vector< IndexedTrie >& unique_var_tries,
-                                                        int trieIndex, int childIndex, int endChildIndex, bool modEq ){
-  if( childIndex==endChildIndex ){
-    //now, process unique variables
-    processNewInstantiations2( qe, m, addedLemmas, unique_var_tries, 0 );
-  }else if( trieIndex<(int)d_children_trie[childIndex].getOrdering()->d_order.size() ){
-    int curr_index = d_children_trie[childIndex].getOrdering()->d_order[trieIndex];
-    Node curr_ic = qe->getTermDatabase()->getInstantiationConstant( d_f, curr_index );
-    if( m.find( curr_ic )==m.end() ){
-      //if( d_var_to_node[ curr_index ].size()==1 ){    //FIXME
-      //  //unique variable(s), defer calculation
-      //  unique_var_tries.push_back( IndexedTrie( std::pair< int, int >( childIndex, trieIndex ), tr ) );
-      //  int newChildIndex = (childIndex+1)%(int)d_children.size();
-      //  processNewInstantiations( qe, m, d_children_trie[newChildIndex].getTrie(), unique_var_tries,
-      //                            0, newChildIndex, endChildIndex, modEq );
-      //}else{
-        //shared and non-set variable, add to InstMatch
-        for( std::map< Node, InstMatchTrie >::iterator it = tr->d_data.begin(); it != tr->d_data.end(); ++it ){
-          InstMatch mn( &m );
-          mn.set( curr_ic, it->first);
-          processNewInstantiations( qe, mn, addedLemmas, &(it->second), unique_var_tries,
-                                    trieIndex+1, childIndex, endChildIndex, modEq );
-        }
-      //}
-    }else{
-      //shared and set variable, try to merge
-      Node n = m.get( curr_ic );
-      std::map< Node, InstMatchTrie >::iterator it = tr->d_data.find( n );
-      if( it!=tr->d_data.end() ){
-        processNewInstantiations( qe, m, addedLemmas, &(it->second), unique_var_tries,
-                                  trieIndex+1, childIndex, endChildIndex, modEq );
-      }
-      if( modEq ){
-        //check modulo equality for other possible instantiations
-        if( 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 = tr->d_data.find( en );
-              if( itc!=tr->d_data.end() ){
-                processNewInstantiations( qe, m, addedLemmas, &(itc->second), unique_var_tries,
-                                          trieIndex+1, childIndex, endChildIndex, modEq );
-              }
-            }
-            ++eqc;
-          }
-        }
-      }
-    }
-  }else{
-    int newChildIndex = (childIndex+1)%(int)d_children.size();
-    processNewInstantiations( qe, m, addedLemmas, d_children_trie[newChildIndex].getTrie(), unique_var_tries,
-                              0, newChildIndex, endChildIndex, modEq );
-  }
-}
-
-void InstMatchGeneratorMulti::processNewInstantiations2( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas,
-                                                         std::vector< IndexedTrie >& unique_var_tries,
-                                                         int uvtIndex, InstMatchTrie* tr, int trieIndex ){
-  if( uvtIndex<(int)unique_var_tries.size() ){
-    int childIndex = unique_var_tries[uvtIndex].first.first;
-    if( !tr ){
-      tr = unique_var_tries[uvtIndex].second;
-      trieIndex = unique_var_tries[uvtIndex].first.second;
-    }
-    if( trieIndex<(int)d_children_trie[childIndex].getOrdering()->d_order.size() ){
-      int curr_index = d_children_trie[childIndex].getOrdering()->d_order[trieIndex];
-      Node curr_ic = qe->getTermDatabase()->getInstantiationConstant( d_f, curr_index );
-      //unique non-set variable, add to InstMatch
-      for( std::map< Node, InstMatchTrie >::iterator it = tr->d_data.begin(); it != tr->d_data.end(); ++it ){
-        InstMatch mn( &m );
-        mn.set( curr_ic, it->first);
-        processNewInstantiations2( qe, mn, addedLemmas, unique_var_tries, uvtIndex, &(it->second), trieIndex+1 );
-      }
-    }else{
-      processNewInstantiations2( qe, m, addedLemmas, unique_var_tries, uvtIndex+1 );
-    }
-  }else{
-    //m is an instantiation
-    if( qe->addInstantiation( d_f, m ) ){
-      addedLemmas++;
-      Debug("smart-multi-trigger") << "-> Produced instantiation " << m << std::endl;
-    }
-  }
-}
-
-int InstMatchGeneratorMulti::addTerm( Node f, Node t, QuantifiersEngine* qe ){
-  Assert( options::eagerInstQuant() );
-  int addedLemmas = 0;
-  for( int i=0; i<(int)d_children.size(); i++ ){
-    if( ((InstMatchGenerator*)d_children[i])->d_match_pattern.getOperator()==t.getOperator() ){
-      InstMatch m;
-      //if it produces a match, then process it with the rest
-      if( ((InstMatchGenerator*)d_children[i])->getMatch( t, m, qe ) ){
-        processNewMatch( qe, m, i, addedLemmas );
-      }
-    }
-  }
-  return addedLemmas;
-}
-
-int InstMatchGeneratorSimple::addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe ){
-  InstMatch m;
-  m.add( baseMatch );
-  int addedLemmas = 0;
-  if( d_match_pattern.getType()==NodeManager::currentNM()->booleanType() ){
-    for( int i=0; i<2; i++ ){
-      addInstantiations( m, qe, addedLemmas, 0, &(qe->getTermDatabase()->d_pred_map_trie[i][ d_match_pattern.getOperator() ]) );
-    }
-  }else{
-    addInstantiations( m, qe, addedLemmas, 0, &(qe->getTermDatabase()->d_func_map_trie[ d_match_pattern.getOperator() ]) );
-  }
-  return addedLemmas;
-}
-
-void InstMatchGeneratorSimple::addInstantiations( InstMatch& m, QuantifiersEngine* qe, int& addedLemmas, int argIndex, quantifiers::TermArgTrie* tat ){
-  if( argIndex==(int)d_match_pattern.getNumChildren() ){
-    //m is an instantiation
-    if( qe->addInstantiation( d_f, m ) ){
-      addedLemmas++;
-      Debug("simple-multi-trigger") << "-> Produced instantiation " << m << std::endl;
-    }
-  }else{
-    if( d_match_pattern[argIndex].getKind()==INST_CONSTANT ){
-      Node ic = d_match_pattern[argIndex];
-      for( std::map< Node, quantifiers::TermArgTrie >::iterator it = tat->d_data.begin(); it != tat->d_data.end(); ++it ){
-        Node t = it->first;
-        if( m.get( ic ).isNull() || m.get( ic )==t ){
-          Node prev = m.get( ic );
-          m.set( ic, t);
-          addInstantiations( m, qe, addedLemmas, argIndex+1, &(it->second) );
-          m.set( ic, prev);
-        }
-      }
-    }else{
-      Node r = qe->getEqualityQuery()->getRepresentative( d_match_pattern[argIndex] );
-      std::map< Node, quantifiers::TermArgTrie >::iterator it = tat->d_data.find( r );
-      if( it!=tat->d_data.end() ){
-        addInstantiations( m, qe, addedLemmas, argIndex+1, &(it->second) );
-      }
-    }
-  }
-}
-
-int InstMatchGeneratorSimple::addTerm( Node f, Node t, QuantifiersEngine* qe ){
-  Assert( options::eagerInstQuant() );
-  InstMatch m;
-  for( int i=0; i<(int)t.getNumChildren(); i++ ){
-    if( d_match_pattern[i].getKind()==INST_CONSTANT ){
-      m.set(d_match_pattern[i], t[i]);
-    }else if( !qe->getEqualityQuery()->areEqual( d_match_pattern[i], t[i] ) ){
-      return 0;
-    }
-  }
-  return qe->addInstantiation( f, m ) ? 1 : 0;
-}
diff --git a/src/theory/inst_match.h b/src/theory/inst_match.h
deleted file mode 100644 (file)
index 2b40277..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/*********************                                                        */
-/*! \file inst_match.h
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: none
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief inst match class
- **/
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__INST_MATCH_H
-#define __CVC4__INST_MATCH_H
-
-#include "util/hash.h"
-
-#include <ext/hash_set>
-#include <iostream>
-#include <map>
-
-#include "context/cdlist.h"
-#include "theory/candidate_generator.h"
-
-//#define USE_EFFICIENT_E_MATCHING
-
-namespace CVC4 {
-namespace theory {
-
-/** Attribute true for nodes that should not be used for matching */
-struct NoMatchAttributeId {};
-/** use the special for boolean flag */
-typedef expr::Attribute< NoMatchAttributeId,
-                         bool,
-                         expr::attr::NullCleanupStrategy,
-                         true // context dependent
-                       > NoMatchAttribute;
-
-// attribute for "contains instantiation constants from"
-struct InstConstantAttributeId {};
-typedef expr::Attribute<InstConstantAttributeId, Node> InstConstantAttribute;
-
-struct InstLevelAttributeId {};
-typedef expr::Attribute<InstLevelAttributeId, uint64_t> InstLevelAttribute;
-
-struct InstVarNumAttributeId {};
-typedef expr::Attribute<InstVarNumAttributeId, uint64_t> InstVarNumAttribute;
-
-// Attribute that tell if a node have been asserted in this branch
-struct AvailableInTermDbId {};
-/** use the special for boolean flag */
-typedef expr::Attribute<AvailableInTermDbId,
-                        bool,
-                        expr::attr::NullCleanupStrategy,
-                        true  // context dependent
-                        > AvailableInTermDb;
-
-
-class QuantifiersEngine;
-namespace quantifiers{
-  class TermArgTrie;
-}
-
-namespace uf{
-  class InstantiatorTheoryUf;
-  class TheoryUF;
-}/* CVC4::theory::uf namespace */
-
-namespace inst {
-
-class EqualityQuery {
-public:
-  EqualityQuery(){}
-  virtual ~EqualityQuery(){};
-  /** contains term */
-  virtual bool hasTerm( Node a ) = 0;
-  /** get the representative of the equivalence class of a */
-  virtual Node getRepresentative( Node a ) = 0;
-  /** returns true if a and b are equal in the current context */
-  virtual bool areEqual( Node a, Node b ) = 0;
-  /** returns true is a and b are disequal in the current context */
-  virtual bool areDisequal( Node a, Node b ) = 0;
-  /** getInternalRepresentative gets the current best representative in the equivalence class of a, based on some criteria.
-      If cbqi is active, this will return a term in the equivalence class of "a" that does
-      not contain instantiation constants, if such a term exists.
-   */
-  virtual Node getInternalRepresentative( Node a ) = 0;
-  /** get the equality engine associated with this query */
-  virtual eq::EqualityEngine* getEngine() = 0;
-  /** get the equivalence class of a */
-  virtual void getEquivalenceClass( Node a, std::vector< Node >& eqc ) = 0;
-};/* class EqualityQuery */
-
-/** basic class defining an instantiation */
-class InstMatch {
-  /* map from variable to ground terms */
-  std::map< Node, Node > d_map;
-public:
-  InstMatch();
-  InstMatch( InstMatch* m );
-
-  /** set the match of v to m */
-  bool setMatch( EqualityQuery* q, TNode v, TNode m );
-  /* This version tell if the variable has been set */
-  bool setMatch( EqualityQuery* q, TNode v, TNode m, bool & set);
-  /** fill all unfilled values with m */
-  bool add( InstMatch& m );
-  /** if compatible, fill all unfilled values with m and return true
-      return false otherwise */
-  bool merge( EqualityQuery* q, InstMatch& m );
-  /** debug print method */
-  void debugPrint( const char* c );
-  /** make complete */
-  void makeComplete( Node f, QuantifiersEngine* qe );
-  /** make internal: ensure that no term in d_map contains instantiation constants */
-  void makeInternal( QuantifiersEngine* qe );
-  /** make representative */
-  void makeRepresentative( QuantifiersEngine* qe );
-  /** apply rewrite */
-  void applyRewrite();
-  /** compute d_match */
-  void computeTermVec( QuantifiersEngine* qe, const std::vector< Node >& vars, std::vector< Node >& match );
-  /** compute d_match */
-  void computeTermVec( const std::vector< Node >& vars, std::vector< Node >& match );
-  /** clear */
-  void clear(){ d_map.clear(); }
-  /** erase */
-  template<class Iterator>
-  void erase(Iterator begin, Iterator end){
-    for(Iterator i = begin; i != end; ++i){
-      d_map.erase(*i);
-    };
-  }
-  void erase(Node node){ d_map.erase(node); }
-  /** is_empty */
-  bool empty(){ return d_map.empty(); }
-  /** set */
-  void set(TNode var, TNode n){
-    //std::cout << "var.getType() " << var.getType() << "n.getType() " << n.getType() << std::endl ;
-    Assert( !var.isNull() );
-    Assert( n.isNull() ||// For a strange use in inst_match.cpp InstMatchGeneratorSimple::addInstantiations
-            var.getType() == n.getType() );
-    d_map[var] = n;
-  }
-  Node get(TNode var){ return d_map[var]; }
-  size_t size(){ return d_map.size(); }
-  /* iterator */
-  std::map< Node, Node >::iterator begin(){ return d_map.begin(); };
-  std::map< Node, Node >::iterator end(){ return d_map.end(); };
-  std::map< Node, Node >::iterator find(Node var){ return d_map.find(var); };
-  /* Node used for matching the trigger only for mono-trigger (just for
-     efficiency because I need only that) */
-  Node d_matched;
-  /** to stream */
-  inline void toStream(std::ostream& out) const {
-    out << "INST_MATCH( ";
-    for( std::map< Node, Node >::const_iterator it = d_map.begin(); it != d_map.end(); ++it ){
-      if( it != d_map.begin() ){ out << ", "; }
-      out << it->first << " -> " << it->second;
-    }
-    out << " )";
-  }
-};/* class InstMatch */
-
-inline std::ostream& operator<<(std::ostream& out, const InstMatch& m) {
-  m.toStream(out);
-  return out;
-}
-
-/** trie for InstMatch objects */
-class InstMatchTrie {
-public:
-  class ImtIndexOrder {
-  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 existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, int index, ImtIndexOrder* imtio );
-public:
-  /** the data */
-  std::map< Node, InstMatchTrie > d_data;
-public:
-  InstMatchTrie(){}
-  ~InstMatchTrie(){}
-public:
-  /** 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, ImtIndexOrder* imtio = NULL );
-};/* class InstMatchTrie */
-
-class InstMatchTrieOrdered {
-private:
-  InstMatchTrie::ImtIndexOrder* d_imtio;
-  InstMatchTrie d_imt;
-public:
-  InstMatchTrieOrdered( InstMatchTrie::ImtIndexOrder* imtio ) : d_imtio( imtio ){}
-  ~InstMatchTrieOrdered(){}
-  /** get ordering */
-  InstMatchTrie::ImtIndexOrder* getOrdering() { return d_imtio; }
-  /** get trie */
-  InstMatchTrie* getTrie() { return &d_imt; }
-public:
-  /** add match m, return true if successful */
-  bool addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false ){
-    return d_imt.addInstMatch( qe, f, m, modEq, d_imtio );
-  }
-};/* class InstMatchTrieOrdered */
-
-/** base class for producing InstMatch objects */
-class IMGenerator {
-public:
-  /** reset instantiation round (call this at beginning of instantiation round) */
-  virtual void resetInstantiationRound( QuantifiersEngine* qe ) = 0;
-  /** reset, eqc is the equivalence class to search in (any if eqc=null) */
-  virtual void reset( Node eqc, QuantifiersEngine* qe ) = 0;
-  /** get the next match.  must call reset( eqc ) before this function. */
-  virtual bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) = 0;
-  /** return true if whatever Node is substituted for the variables the
-      given Node can't match the pattern */
-  virtual bool nonunifiable( TNode t, const std::vector<Node> & vars) = 0;
-  /** add instantiations directly */
-  virtual int addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe ) = 0;
-  /** add ground term t, called when t is added to term db */
-  virtual int addTerm( Node f, Node t, QuantifiersEngine* qe ) = 0;
-};/* class IMGenerator */
-
-
-class InstMatchGenerator : public IMGenerator {
-private:
-  /** candidate generator */
-  CandidateGenerator* d_cg;
-  /** policy to use for matching */
-  int d_matchPolicy;
-  /** children generators */
-  std::vector< InstMatchGenerator* > d_children;
-  std::vector< int > d_children_index;
-  /** partial vector */
-  std::vector< InstMatch > d_partial;
-  /** eq class */
-  Node d_eq_class;
-  /** for arithmetic matching */
-  std::map< Node, Node > d_arith_coeffs;
-  /** initialize pattern */
-  void initializePatterns( std::vector< Node >& pats, QuantifiersEngine* qe );
-  void initializePattern( Node pat, QuantifiersEngine* qe );
-public:
-  enum {
-    //options for producing matches
-    MATCH_GEN_DEFAULT = 0,
-    MATCH_GEN_EFFICIENT_E_MATCH,   //generate matches via Efficient E-matching for SMT solvers
-    //others (internally used)
-    MATCH_GEN_INTERNAL_ARITHMETIC,
-    MATCH_GEN_INTERNAL_ERROR,
-  };
-private:
-  /** get the next match.  must call d_cg->reset( ... ) before using.
-      only valid for use where !d_match_pattern.isNull().
-  */
-  bool getNextMatch2( InstMatch& m, QuantifiersEngine* qe, bool saveMatched = false );
-  /** for arithmetic */
-  bool getMatchArithmetic( Node t, InstMatch& m, QuantifiersEngine* qe );
-public:
-  /** get the match against ground term or formula t.
-      d_match_pattern and t should have the same shape.
-      only valid for use where !d_match_pattern.isNull().
-  */
-  bool getMatch( Node t, InstMatch& m, QuantifiersEngine* qe );
-
-  /** constructors */
-  InstMatchGenerator( Node pat, QuantifiersEngine* qe, int matchOption = 0 );
-  InstMatchGenerator( std::vector< Node >& pats, QuantifiersEngine* qe, int matchOption = 0 );
-  /** destructor */
-  ~InstMatchGenerator(){}
-  /** The pattern we are producing matches for.
-      If null, this is a multi trigger that is merging matches from d_children.
-  */
-  Node d_pattern;
-  /** match pattern */
-  Node d_match_pattern;
-public:
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  void resetInstantiationRound( QuantifiersEngine* qe );
-  /** reset, eqc is the equivalence class to search in (any if eqc=null) */
-  void reset( Node eqc, QuantifiersEngine* qe );
-  /** get the next match.  must call reset( eqc ) before this function. */
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe );
-  /** return true if whatever Node is substituted for the variables the
-      given Node can't match the pattern */
-  bool nonunifiable( TNode t, const std::vector<Node> & vars);
-  /** add instantiations */
-  int addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe );
-  /** add ground term t */
-  int addTerm( Node f, Node t, QuantifiersEngine* qe );
-};/* class InstMatchGenerator */
-
-/** smart multi-trigger implementation */
-class InstMatchGeneratorMulti : public IMGenerator {
-private:
-  /** indexed trie */
-  typedef std::pair< std::pair< int, int >, InstMatchTrie* > IndexedTrie;
-  /** process new match */
-  void processNewMatch( QuantifiersEngine* qe, InstMatch& m, int fromChildIndex, int& addedLemmas );
-  /** process new instantiations */
-  void processNewInstantiations( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas, InstMatchTrie* tr,
-                                 std::vector< IndexedTrie >& unique_var_tries,
-                                 int trieIndex, int childIndex, int endChildIndex, bool modEq );
-  /** process new instantiations 2 */
-  void processNewInstantiations2( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas,
-                                  std::vector< IndexedTrie >& unique_var_tries,
-                                  int uvtIndex, InstMatchTrie* tr = NULL, int trieIndex = 0 );
-private:
-  /** var contains (variable indices) for each pattern node */
-  std::map< Node, std::vector< int > > d_var_contains;
-  /** variable indices contained to pattern nodes */
-  std::map< int, std::vector< Node > > d_var_to_node;
-  /** quantifier to use */
-  Node d_f;
-  /** policy to use for matching */
-  int d_matchPolicy;
-  /** children generators */
-  std::vector< InstMatchGenerator* > d_children;
-  /** inst match tries for each child */
-  std::vector< InstMatchTrieOrdered > d_children_trie;
-  /** calculate matches */
-  void calculateMatches( QuantifiersEngine* qe );
-public:
-  /** constructors */
-  InstMatchGeneratorMulti( Node f, std::vector< Node >& pats, QuantifiersEngine* qe, int matchOption = 0 );
-  /** destructor */
-  ~InstMatchGeneratorMulti(){}
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  void resetInstantiationRound( QuantifiersEngine* qe );
-  /** reset, eqc is the equivalence class to search in (any if eqc=null) */
-  void reset( Node eqc, QuantifiersEngine* qe );
-  /** get the next match.  must call reset( eqc ) before this function. (not implemented) */
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) { return false; }
-  /** return true if whatever Node is substituted for the variables the
-      given Node can't match the pattern */
-  bool nonunifiable( TNode t, const std::vector<Node> & vars) { return true; }
-  /** add instantiations */
-  int addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe );
-  /** add ground term t */
-  int addTerm( Node f, Node t, QuantifiersEngine* qe );
-};/* class InstMatchGeneratorMulti */
-
-/** smart (single)-trigger implementation */
-class InstMatchGeneratorSimple : public IMGenerator {
-private:
-  /** quantifier for match term */
-  Node d_f;
-  /** match term */
-  Node d_match_pattern;
-  /** add instantiations */
-  void addInstantiations( InstMatch& m, QuantifiersEngine* qe, int& addedLemmas, int argIndex, quantifiers::TermArgTrie* tat );
-public:
-  /** constructors */
-  InstMatchGeneratorSimple( Node f, Node pat ) : d_f( f ), d_match_pattern( pat ){}
-  /** destructor */
-  ~InstMatchGeneratorSimple(){}
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  void resetInstantiationRound( QuantifiersEngine* qe ) {}
-  /** reset, eqc is the equivalence class to search in (any if eqc=null) */
-  void reset( Node eqc, QuantifiersEngine* qe ) {}
-  /** get the next match.  must call reset( eqc ) before this function. (not implemented) */
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) { return false; }
-  /** return true if whatever Node is substituted for the variables the
-      given Node can't match the pattern */
-  bool nonunifiable( TNode t, const std::vector<Node> & vars) { return true; }
-  /** add instantiations */
-  int addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe );
-  /** add ground term t, possibly add instantiations */
-  int addTerm( Node f, Node t, QuantifiersEngine* qe );
-};/* class InstMatchGeneratorSimple */
-
-}/* CVC4::theory::inst namespace */
-
-typedef CVC4::theory::inst::InstMatch InstMatch;
-typedef CVC4::theory::inst::EqualityQuery EqualityQuery;
-
-}/* CVC4::theory namespace */
-}/* CVC4 namespace */
-
-#endif /* __CVC4__INST_MATCH_H */
diff --git a/src/theory/instantiator_default.cpp b/src/theory/instantiator_default.cpp
deleted file mode 100644 (file)
index cff1696..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*********************                                                        */
-/*! \file instantiator_default.cpp
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: none
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Implementation of instantiator_default class
- **/
-
-#include "theory/instantiator_default.h"
-#include "theory/theory_engine.h"
-
-using namespace std;
-using namespace CVC4;
-using namespace CVC4::kind;
-using namespace CVC4::context;
-using namespace CVC4::theory;
-
-InstantiatorDefault::InstantiatorDefault(context::Context* c, QuantifiersEngine* ie, Theory* th) :
-  Instantiator( c, ie, th ) {
-}
-
-void InstantiatorDefault::assertNode( Node assertion ){
-}
-
-void InstantiatorDefault::processResetInstantiationRound( Theory::Effort effort ){
-}
-
-int InstantiatorDefault::process( Node f, Theory::Effort effort, int e ){
-  /*
-  if( e < 4 ){
-    return InstStrategy::STATUS_UNFINISHED;
-  }else if( e == 4 ){
-    Debug("quant-default") << "Process " << f << " : " << std::endl;
-    InstMatch m;
-    for( int j=0; j<(int)d_quantEngine->getNumInstantiationConstants( f ); j++ ){
-      Node i = d_quantEngine->getInstantiationConstant( f, j );
-      Debug("quant-default") << "Getting value for " << i << std::endl;
-      if( d_quantEngine->getTheoryEngine()->theoryOf( i )==getTheory() ){    //if it belongs to this theory
-        Node val = d_th->getValue( i );
-        Debug("quant-default") << "Default Instantiate for " << d_th->getId() << ", setting " << i << " = " << val << std::endl;
-        m.set( i, val);
-      }
-    }
-    d_quantEngine->addInstantiation( f, m );
-  }
-  */
-  return InstStrategy::STATUS_UNKNOWN;
-}
diff --git a/src/theory/instantiator_default.h b/src/theory/instantiator_default.h
deleted file mode 100644 (file)
index 967a0c1..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*********************                                                        */
-/*! \file instantiator_default.h
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: none
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief instantiator_default
- **/
-
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__INSTANTIATOR_DEFAULT_H
-#define __CVC4__INSTANTIATOR_DEFAULT_H
-
-#include <string>
-#include "theory/quantifiers_engine.h"
-
-namespace CVC4 {
-namespace theory {
-
-class InstantiatorDefault : public Instantiator {
-  friend class QuantifiersEngine;
-protected:
-  /** reset instantiation round */
-  void processResetInstantiationRound(Theory::Effort effort);
-  /** process quantifier */
-  int process( Node f, Theory::Effort effort, int e );
-public:
-  InstantiatorDefault(context::Context* c, QuantifiersEngine* ie, Theory* th);
-  ~InstantiatorDefault() { }
-  /** check function, assertion is asserted to theory */
-  void assertNode( Node assertion );
-  /** identify */
-  std::string identify() const { return std::string("InstantiatorDefault"); }
-};/* class InstantiatorDefault */
-
-}/* CVC4::theory namespace */
-}/* CVC4 namespace */
-
-#endif /* __CVC4__INSTANTIATOR_DEFAULT_H */
index 5172001fc74de52bf28ba679cbfaa6cc7e213446..2b16c9af317babe284ff123c5c245e7bcbc7f7bd 100644 (file)
@@ -15,6 +15,14 @@ libquantifiers_la_SOURCES = \
        theory_quantifiers_instantiator.cpp \
        instantiation_engine.h \
        instantiation_engine.cpp \
+       trigger.h \
+       trigger.cpp \
+       candidate_generator.h \
+       candidate_generator.cpp \
+       instantiator_default.h \
+       instantiator_default.cpp \
+       inst_match.h \
+       inst_match.cpp \
        model_engine.h \
        model_engine.cpp \
        inst_when_mode.cpp \
diff --git a/src/theory/quantifiers/candidate_generator.cpp b/src/theory/quantifiers/candidate_generator.cpp
new file mode 100644 (file)
index 0000000..6a7c4c5
--- /dev/null
@@ -0,0 +1,255 @@
+/*********************                                                        */
+/*! \file candidate_generator.cpp
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: mdeters
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of theory uf candidate generator class
+ **/
+
+#include "theory/quantifiers/candidate_generator.h"
+#include "theory/theory_engine.h"
+#include "theory/uf/theory_uf.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/quantifiers/inst_match.h"
+#include "theory/quantifiers_engine.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::inst;
+
+bool CandidateGenerator::isLegalCandidate( Node n ){
+  return ( !n.getAttribute(NoMatchAttribute()) && ( !options::cbqi() || !n.hasAttribute(InstConstantAttribute()) ) );
+}
+
+void CandidateGeneratorQueue::addCandidate( Node n ) {
+  if( isLegalCandidate( n ) ){
+    d_candidates.push_back( n );
+  }
+}
+
+void CandidateGeneratorQueue::reset( Node eqc ){
+  if( d_candidate_index>0 ){
+    d_candidates.erase( d_candidates.begin(), d_candidates.begin() + d_candidate_index );
+    d_candidate_index = 0;
+  }
+  if( !eqc.isNull() ){
+    d_candidates.push_back( eqc );
+  }
+}
+Node CandidateGeneratorQueue::getNextCandidate(){
+  if( d_candidate_index<(int)d_candidates.size() ){
+    Node n = d_candidates[d_candidate_index];
+    d_candidate_index++;
+    return n;
+  }else{
+    d_candidate_index = 0;
+    d_candidates.clear();
+    return Node::null();
+  }
+}
+
+#if 0
+
+CandidateGeneratorQE::CandidateGeneratorQE( QuantifiersEngine* qe, Node op ) :
+  d_op( op ), d_qe( qe ), d_term_iter( -2 ){
+  Assert( !d_op.isNull() );
+}
+void CandidateGeneratorQE::resetInstantiationRound(){
+  d_term_iter_limit = d_qe->getTermDatabase()->d_op_map[d_op].size();
+}
+
+void CandidateGeneratorQE::reset( Node eqc ){
+  if( eqc.isNull() ){
+    d_term_iter = 0;
+  }else{
+    //create an equivalence class iterator in eq class eqc
+    if( d_qe->getEqualityQuery()->getEngine()->hasTerm( eqc ) ){
+      eqc = d_qe->getEqualityQuery()->getEngine()->getRepresentative( eqc );
+      d_eqc = eq::EqClassIterator( eqc, d_qe->getEqualityQuery()->getEngine() );
+      d_retNode = Node::null();
+    }else{
+      d_retNode = eqc;
+    }
+    d_term_iter = -1;
+  }
+}
+
+Node CandidateGeneratorQE::getNextCandidate(){
+  if( d_term_iter>=0 ){
+    //get next candidate term in the uf term database
+    while( d_term_iter<d_term_iter_limit ){
+      Node n = d_qe->getTermDatabase()->d_op_map[d_op][d_term_iter];
+      d_term_iter++;
+      if( isLegalCandidate( n ) ){
+        return n;
+      }
+    }
+  }else if( d_term_iter==-1 ){
+    if( d_retNode.isNull() ){
+      //get next candidate term in equivalence class
+      while( !d_eqc.isFinished() ){
+        Node n = (*d_eqc);
+        ++d_eqc;
+        if( n.hasOperator() && n.getOperator()==d_op ){
+          if( isLegalCandidate( n ) ){
+            return n;
+          }
+        }
+      }
+    }else{
+      Node ret;
+      if( d_retNode.hasOperator() && d_retNode.getOperator()==d_op ){
+        ret = d_retNode;
+      }
+      d_term_iter = -2; //done returning matches
+      return ret;
+    }
+  }
+  return Node::null();
+}
+
+#else
+
+
+CandidateGeneratorQE::CandidateGeneratorQE( QuantifiersEngine* qe, Node op ) :
+  d_op( op ), d_qe( qe ), d_term_iter( -1 ){
+  Assert( !d_op.isNull() );
+}
+void CandidateGeneratorQE::resetInstantiationRound(){
+  d_term_iter_limit = d_qe->getTermDatabase()->d_op_map[d_op].size();
+}
+
+void CandidateGeneratorQE::reset( Node eqc ){
+  d_term_iter = 0;
+  if( eqc.isNull() ){
+    d_using_term_db = true;
+  }else{
+    //create an equivalence class iterator in eq class eqc
+    d_eqc.clear();
+    d_qe->getEqualityQuery()->getEquivalenceClass( eqc, d_eqc );
+    d_using_term_db = false;
+  }
+}
+
+Node CandidateGeneratorQE::getNextCandidate(){
+  if( d_term_iter>=0 ){
+    if( d_using_term_db ){
+      //get next candidate term in the uf term database
+      while( d_term_iter<d_term_iter_limit ){
+        Node n = d_qe->getTermDatabase()->d_op_map[d_op][d_term_iter];
+        d_term_iter++;
+        if( isLegalCandidate( n ) ){
+          return n;
+        }
+      }
+    }else{
+      while( d_term_iter<(int)d_eqc.size() ){
+        Node n = d_eqc[d_term_iter];
+        d_term_iter++;
+        if( n.hasOperator() && n.getOperator()==d_op ){
+          if( isLegalCandidate( n ) ){
+            return n;
+          }
+        }
+      }
+    }
+  }
+  return Node::null();
+}
+
+#endif
+
+//CandidateGeneratorQEDisequal::CandidateGeneratorQEDisequal( QuantifiersEngine* qe, Node eqc ) :
+//  d_qe( qe ), d_eq_class( eqc ){
+//  d_eci = NULL;
+//}
+//void CandidateGeneratorQEDisequal::resetInstantiationRound(){
+//
+//}
+////we will iterate over all terms that are disequal from eqc
+//void CandidateGeneratorQEDisequal::reset( Node eqc ){
+//  //Assert( !eqc.isNull() );
+//  ////begin iterating over equivalence classes that are disequal from eqc
+//  //d_eci = d_ith->getEquivalenceClassInfo( eqc );
+//  //if( d_eci ){
+//  //  d_eqci_iter = d_eci->d_disequal.begin();
+//  //}
+//}
+//Node CandidateGeneratorQEDisequal::getNextCandidate(){
+//  //if( d_eci ){
+//  //  while( d_eqci_iter != d_eci->d_disequal.end() ){
+//  //    if( (*d_eqci_iter).second ){
+//  //      //we have an equivalence class that is disequal from eqc
+//  //      d_cg->reset( (*d_eqci_iter).first );
+//  //      Node n = d_cg->getNextCandidate();
+//  //      //if there is a candidate in this equivalence class, return it
+//  //      if( !n.isNull() ){
+//  //        return n;
+//  //      }
+//  //    }
+//  //    ++d_eqci_iter;
+//  //  }
+//  //}
+//  return Node::null();
+//}
+
+
+CandidateGeneratorQELitEq::CandidateGeneratorQELitEq( QuantifiersEngine* qe, Node mpat ) :
+  d_match_pattern( mpat ), d_qe( qe ){
+
+}
+void CandidateGeneratorQELitEq::resetInstantiationRound(){
+
+}
+void CandidateGeneratorQELitEq::reset( Node eqc ){
+  d_eq = eq::EqClassesIterator( d_qe->getEqualityQuery()->getEngine() );
+}
+Node CandidateGeneratorQELitEq::getNextCandidate(){
+  while( d_eq.isFinished() ){
+    Node n = (*d_eq);
+    ++d_eq;
+    if( n.getType()==d_match_pattern[0].getType() ){
+      //an equivalence class with the same type as the pattern, return reflexive equality
+      return NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), n, n );
+    }
+  }
+  return Node::null();
+}
+
+
+CandidateGeneratorQELitDeq::CandidateGeneratorQELitDeq( QuantifiersEngine* qe, Node mpat ) :
+  d_match_pattern( mpat ), d_qe( qe ){
+
+}
+void CandidateGeneratorQELitDeq::resetInstantiationRound(){
+
+}
+void CandidateGeneratorQELitDeq::reset( Node eqc ){
+  Node false_term = d_qe->getEqualityQuery()->getEngine()->getRepresentative( NodeManager::currentNM()->mkConst<bool>(false) );
+  d_eqc_false = eq::EqClassIterator( false_term, d_qe->getEqualityQuery()->getEngine() );
+}
+Node CandidateGeneratorQELitDeq::getNextCandidate(){
+  //get next candidate term in equivalence class
+  while( !d_eqc_false.isFinished() ){
+    Node n = (*d_eqc_false);
+    ++d_eqc_false;
+    if( n.getKind()==d_match_pattern.getKind() ){
+      //found an iff or equality, try to match it
+      //DO_THIS: cache to avoid redundancies?
+      //DO_THIS: do we need to try the symmetric equality for n?  or will it also exist in the eq class of false?
+      return n;
+    }
+  }
+  return Node::null();
+}
diff --git a/src/theory/quantifiers/candidate_generator.h b/src/theory/quantifiers/candidate_generator.h
new file mode 100644 (file)
index 0000000..a6aa34a
--- /dev/null
@@ -0,0 +1,187 @@
+/*********************                                                        */
+/*! \file candidate_generator.h
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: none
+ ** Minor contributors (to current version): mdeters
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Theory uf candidate generator
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__QUANTIFIERS__CANDIDATE_GENERATOR_H
+#define __CVC4__THEORY__QUANTIFIERS__CANDIDATE_GENERATOR_H
+
+#include "theory/theory.h"
+#include "theory/uf/equality_engine.h"
+
+namespace CVC4 {
+namespace theory {
+
+class QuantifiersEngine;
+
+namespace inst {
+
+/** base class for generating candidates for matching */
+class CandidateGenerator {
+public:
+  CandidateGenerator(){}
+  ~CandidateGenerator(){}
+
+  /** Get candidates functions.  These set up a context to get all match candidates.
+      cg->reset( eqc );
+      do{
+        Node cand = cg->getNextCandidate();
+        //.......
+      }while( !cand.isNull() );
+
+      eqc is the equivalence class you are searching in
+  */
+  virtual void reset( Node eqc ) = 0;
+  virtual Node getNextCandidate() = 0;
+  /** add candidate to list of nodes returned by this generator */
+  virtual void addCandidate( Node n ) {}
+  /** call this at the beginning of each instantiation round */
+  virtual void resetInstantiationRound() = 0;
+public:
+  /** legal candidate */
+  static bool isLegalCandidate( Node n );
+};/* class CandidateGenerator */
+
+/** candidate generator queue (for manual candidate generation) */
+class CandidateGeneratorQueue : public CandidateGenerator {
+private:
+  std::vector< Node > d_candidates;
+  int d_candidate_index;
+public:
+  CandidateGeneratorQueue() : d_candidate_index( 0 ){}
+  ~CandidateGeneratorQueue(){}
+
+  void addCandidate( Node n );
+
+  void resetInstantiationRound(){}
+  void reset( Node eqc );
+  Node getNextCandidate();
+};/* class CandidateGeneratorQueue */
+
+class CandidateGeneratorQEDisequal;
+
+#if 0
+
+class CandidateGeneratorQE : public CandidateGenerator
+{
+  friend class CandidateGeneratorQEDisequal;
+private:
+  //operator you are looking for
+  Node d_op;
+  //instantiator pointer
+  QuantifiersEngine* d_qe;
+  //the equality class iterator
+  eq::EqClassIterator d_eqc;
+  int d_term_iter;
+  int d_term_iter_limit;
+private:
+  Node d_retNode;
+public:
+  CandidateGeneratorQE( QuantifiersEngine* qe, Node op );
+  ~CandidateGeneratorQE(){}
+
+  void resetInstantiationRound();
+  void reset( Node eqc );
+  Node getNextCandidate();
+};
+
+#else
+
+class CandidateGeneratorQE : public CandidateGenerator
+{
+  friend class CandidateGeneratorQEDisequal;
+private:
+  //operator you are looking for
+  Node d_op;
+  //instantiator pointer
+  QuantifiersEngine* d_qe;
+  //the equality class iterator
+  std::vector< Node > d_eqc;
+  int d_term_iter;
+  int d_term_iter_limit;
+  bool d_using_term_db;
+public:
+  CandidateGeneratorQE( QuantifiersEngine* qe, Node op );
+  ~CandidateGeneratorQE(){}
+
+  void resetInstantiationRound();
+  void reset( Node eqc );
+  Node getNextCandidate();
+};
+
+#endif
+
+//class CandidateGeneratorQEDisequal : public CandidateGenerator
+//{
+//private:
+//  //equivalence class
+//  Node d_eq_class;
+//  //equivalence class info
+//  EqClassInfo* d_eci;
+//  //equivalence class iterator
+//  EqClassInfo::BoolMap::const_iterator d_eqci_iter;
+//  //instantiator pointer
+//  QuantifiersEngine* d_qe;
+//public:
+//  CandidateGeneratorQEDisequal( QuantifiersEngine* qe, Node eqc );
+//  ~CandidateGeneratorQEDisequal(){}
+//
+//  void resetInstantiationRound();
+//  void reset( Node eqc );   //should be what you want to be disequal from
+//  Node getNextCandidate();
+//};
+
+class CandidateGeneratorQELitEq : public CandidateGenerator
+{
+private:
+  //the equality classes iterator
+  eq::EqClassesIterator d_eq;
+  //equality you are trying to match equalities for
+  Node d_match_pattern;
+  //einstantiator pointer
+  QuantifiersEngine* d_qe;
+public:
+  CandidateGeneratorQELitEq( QuantifiersEngine* qe, Node mpat );
+  ~CandidateGeneratorQELitEq(){}
+
+  void resetInstantiationRound();
+  void reset( Node eqc );
+  Node getNextCandidate();
+};
+
+class CandidateGeneratorQELitDeq : public CandidateGenerator
+{
+private:
+  //the equality class iterator for false
+  eq::EqClassIterator d_eqc_false;
+  //equality you are trying to match disequalities for
+  Node d_match_pattern;
+  //einstantiator pointer
+  QuantifiersEngine* d_qe;
+public:
+  CandidateGeneratorQELitDeq( QuantifiersEngine* qe, Node mpat );
+  ~CandidateGeneratorQELitDeq(){}
+
+  void resetInstantiationRound();
+  void reset( Node eqc );
+  Node getNextCandidate();
+};
+
+}/* CVC4::theory::inst namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__QUANTIFIERS__CANDIDATE_GENERATOR_H */
index afa8dab794317f8822253955818f5ed49a31f3eb..8ad9114528de899683b885252e03762074c9a54a 100644 (file)
@@ -80,10 +80,10 @@ public:
   TermDb* getTermDatabase();
   /** to stream function */
   void toStream( std::ostream& out );
-};
+};/* class FirstOrderModel */
 
-}
-}
-}
+}/* CVC4::theory::quantifiers namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
-#endif
+#endif /* __CVC4__FIRST_ORDER_MODEL_H */
diff --git a/src/theory/quantifiers/inst_match.cpp b/src/theory/quantifiers/inst_match.cpp
new file mode 100644 (file)
index 0000000..271e049
--- /dev/null
@@ -0,0 +1,880 @@
+/*********************                                                        */
+/*! \file inst_match.cpp
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of inst match class
+ **/
+
+#include "theory/quantifiers/inst_match.h"
+#include "theory/theory_engine.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/quantifiers/candidate_generator.h"
+#include "theory/uf/theory_uf_instantiator.h"
+#include "theory/uf/equality_engine.h"
+#include "theory/quantifiers/options.h"
+#include "theory/quantifiers/model_engine.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/quantifiers/first_order_model.h"
+#include "theory/quantifiers/term_database.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::inst;
+
+
+InstMatch::InstMatch() {
+}
+
+InstMatch::InstMatch( InstMatch* m ) {
+  d_map = m->d_map;
+}
+
+bool InstMatch::setMatch( EqualityQuery* q, TNode v, TNode m, bool & set ){
+  std::map< Node, Node >::iterator vn = d_map.find( v );
+  if( vn==d_map.end() ){
+    set = true;
+    this->set(v,m);
+    Debug("matching-debug") << "Add partial " << v << "->" << m << std::endl;
+    return true;
+  }else{
+    set = false;
+    return q->areEqual( vn->second, m );
+  }
+}
+
+bool InstMatch::setMatch( EqualityQuery* q, TNode v, TNode m ){
+  bool set;
+  return setMatch(q,v,m,set);
+}
+
+bool InstMatch::add( InstMatch& m ){
+  for( std::map< Node, Node >::iterator it = m.d_map.begin(); it != m.d_map.end(); ++it ){
+    if( d_map.find( it->first )==d_map.end() ){
+      d_map[it->first] = it->second;
+    }
+  }
+  return true;
+}
+
+bool InstMatch::merge( EqualityQuery* q, InstMatch& m ){
+  for( std::map< Node, Node >::iterator it = m.d_map.begin(); it != m.d_map.end(); ++it ){
+    if( d_map.find( it->first )==d_map.end() ){
+      d_map[ it->first ] = it->second;
+    }else{
+      if( it->second!=d_map[it->first] ){
+        if( !q->areEqual( it->second, d_map[it->first] ) ){
+          d_map.clear();
+          return false;
+        }
+      }
+    }
+  }
+  return true;
+}
+
+void InstMatch::debugPrint( const char* c ){
+  for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){
+    Debug( c ) << "   " << it->first << " -> " << it->second << std::endl;
+  }
+  //if( !d_splits.empty() ){
+  //  Debug( c ) << "   Conditions: ";
+  //  for( std::map< Node, Node >::iterator it = d_splits.begin(); it !=d_splits.end(); ++it ){
+  //    Debug( c ) << it->first << " = " << it->second << " ";
+  //  }
+  //  Debug( c ) << std::endl;
+  //}
+}
+
+void InstMatch::makeComplete( Node f, QuantifiersEngine* qe ){
+  for( int i=0; i<(int)qe->getTermDatabase()->d_inst_constants[f].size(); i++ ){
+    Node ic = qe->getTermDatabase()->d_inst_constants[f][i];
+    if( d_map.find( ic )==d_map.end() ){
+      d_map[ ic ] = qe->getTermDatabase()->getFreeVariableForInstConstant( ic );
+    }
+  }
+}
+
+void InstMatch::makeInternal( QuantifiersEngine* qe ){
+  if( options::cbqi() ){
+    for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){
+      if( it->second.hasAttribute(InstConstantAttribute()) ){
+        d_map[ it->first ] = qe->getEqualityQuery()->getInternalRepresentative( it->second );
+        if( it->second.hasAttribute(InstConstantAttribute()) ){
+          d_map[ it->first ] = qe->getTermDatabase()->getFreeVariableForInstConstant( it->first );
+        }
+      }
+    }
+  }
+}
+
+void InstMatch::makeRepresentative( QuantifiersEngine* qe ){
+  for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){
+    d_map[ it->first ] = qe->getEqualityQuery()->getInternalRepresentative( it->second );
+    if( options::cbqi() && it->second.hasAttribute(InstConstantAttribute()) ){
+      d_map[ it->first ] = qe->getTermDatabase()->getFreeVariableForInstConstant( it->first );
+    }
+  }
+}
+
+void InstMatch::applyRewrite(){
+  for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){
+    it->second = Rewriter::rewrite(it->second);
+  }
+}
+
+void InstMatch::computeTermVec( QuantifiersEngine* qe, const std::vector< Node >& vars, std::vector< Node >& match ){
+  for( int i=0; i<(int)vars.size(); i++ ){
+    std::map< Node, Node >::iterator it = d_map.find( vars[i] );
+    if( it!=d_map.end() && !it->second.isNull() ){
+      match.push_back( it->second );
+    }else{
+      match.push_back( qe->getTermDatabase()->getFreeVariableForInstConstant( vars[i] ) );
+    }
+  }
+}
+void InstMatch::computeTermVec( const std::vector< Node >& vars, std::vector< Node >& match ){
+  for( int i=0; i<(int)vars.size(); i++ ){
+    match.push_back( d_map[ vars[i] ] );
+  }
+}
+
+
+/** 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;
+    Node n = m.get( qe->getTermDatabase()->getInstantiationConstant( f, i_index ) );
+    d_data[n].addInstMatch2( qe, f, m, index+1, imtio );
+  }
+}
+
+/** exists match */
+bool InstMatchTrie::existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, int index, ImtIndexOrder* imtio ){
+  if( long(index)==long(f[0].getNumChildren()) || ( imtio && long(index)==long(imtio->d_order.size()) ) ){
+    return true;
+  }else{
+    int i_index = imtio ? imtio->d_order[index] : index;
+    Node n = m.get( qe->getTermDatabase()->getInstantiationConstant( f, i_index ) );
+    std::map< Node, InstMatchTrie >::iterator it = d_data.find( n );
+    if( it!=d_data.end() ){
+      if( it->second.existsInstMatch( qe, f, m, modEq, index+1, imtio ) ){
+        return true;
+      }
+    }
+    if( modEq ){
+      //check modulo equality if any other instantiation match exists
+      if( 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.existsInstMatch( qe, f, m, modEq, index+1, imtio ) ){
+                return true;
+              }
+            }
+          }
+          ++eqc;
+        }
+      }
+      //for( std::map< Node, InstMatchTrie >::iterator itc = d_data.begin(); itc != d_data.end(); ++itc ){
+      //  if( itc->first!=n && qe->getEqualityQuery()->areEqual( n, itc->first ) ){
+      //    if( itc->second.existsInstMatch( qe, f, m, modEq, index+1 ) ){
+      //      return true;
+      //    }
+      //  }
+      //}
+    }
+    return false;
+  }
+}
+
+bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, ImtIndexOrder* imtio ){
+  if( !existsInstMatch( qe, f, m, modEq, 0, imtio ) ){
+    addInstMatch2( qe, f, m, 0, imtio );
+    return true;
+  }else{
+    return false;
+  }
+}
+
+InstMatchGenerator::InstMatchGenerator( Node pat, QuantifiersEngine* qe, int matchPolicy ) : d_matchPolicy( matchPolicy ){
+  initializePattern( pat, qe );
+}
+
+InstMatchGenerator::InstMatchGenerator( std::vector< Node >& pats, QuantifiersEngine* qe, int matchPolicy ) : d_matchPolicy( matchPolicy ){
+  if( pats.size()==1 ){
+    initializePattern( pats[0], qe );
+  }else{
+    initializePatterns( pats, qe );
+  }
+}
+
+void InstMatchGenerator::initializePatterns( std::vector< Node >& pats, QuantifiersEngine* qe ){
+  int childMatchPolicy = d_matchPolicy==MATCH_GEN_EFFICIENT_E_MATCH ? 0 : d_matchPolicy;
+  for( int i=0; i<(int)pats.size(); i++ ){
+    d_children.push_back( new InstMatchGenerator( pats[i], qe, childMatchPolicy ) );
+  }
+  d_pattern = Node::null();
+  d_match_pattern = Node::null();
+  d_cg = NULL;
+}
+
+void InstMatchGenerator::initializePattern( Node pat, QuantifiersEngine* qe ){
+  Debug("inst-match-gen") << "Pattern term is " << pat << std::endl;
+  Assert( pat.hasAttribute(InstConstantAttribute()) );
+  d_pattern = pat;
+  d_match_pattern = pat;
+  if( d_match_pattern.getKind()==NOT ){
+    //we want to add the children of the NOT
+    d_match_pattern = d_pattern[0];
+  }
+  if( d_match_pattern.getKind()==IFF || d_match_pattern.getKind()==EQUAL ){
+    if( !d_match_pattern[0].hasAttribute(InstConstantAttribute()) ){
+      Assert( d_match_pattern[1].hasAttribute(InstConstantAttribute()) );
+      //swap sides
+      d_pattern = NodeManager::currentNM()->mkNode( d_match_pattern.getKind(), d_match_pattern[1], d_match_pattern[0] );
+      d_pattern = pat.getKind()==NOT ? d_pattern.notNode() : d_pattern;
+      if( pat.getKind()!=NOT ){   //TEMPORARY until we do better implementation of disequality matching
+        d_match_pattern = d_match_pattern[1];
+      }else{
+        d_match_pattern = d_pattern[0][0];
+      }
+    }else if( !d_match_pattern[1].hasAttribute(InstConstantAttribute()) ){
+      Assert( d_match_pattern[0].hasAttribute(InstConstantAttribute()) );
+      if( pat.getKind()!=NOT ){   //TEMPORARY until we do better implementation of disequality matching
+        d_match_pattern = d_match_pattern[0];
+      }
+    }
+  }
+  int childMatchPolicy = MATCH_GEN_DEFAULT;
+  for( int i=0; i<(int)d_match_pattern.getNumChildren(); i++ ){
+    if( d_match_pattern[i].hasAttribute(InstConstantAttribute()) ){
+      if( d_match_pattern[i].getKind()!=INST_CONSTANT ){
+        d_children.push_back( new InstMatchGenerator( d_match_pattern[i], qe, childMatchPolicy ) );
+        d_children_index.push_back( i );
+      }
+    }
+  }
+
+  Debug("inst-match-gen") << "Pattern is " << d_pattern << ", match pattern is " << d_match_pattern << std::endl;
+
+  //create candidate generator
+  if( d_match_pattern.getKind()==EQUAL || d_match_pattern.getKind()==IFF ){
+    Assert( d_matchPolicy==MATCH_GEN_DEFAULT );
+    //we will be producing candidates via literal matching heuristics
+    if( d_pattern.getKind()!=NOT ){
+      //candidates will be all equalities
+      d_cg = new inst::CandidateGeneratorQELitEq( qe, d_match_pattern );
+    }else{
+      //candidates will be all disequalities
+      d_cg = new inst::CandidateGeneratorQELitDeq( qe, d_match_pattern );
+    }
+  }else if( d_pattern.getKind()==EQUAL || d_pattern.getKind()==IFF || d_pattern.getKind()==NOT ){
+    Assert( d_matchPolicy==MATCH_GEN_DEFAULT );
+    if( d_pattern.getKind()==NOT ){
+      Unimplemented("Disequal generator unimplemented");
+    }else{
+      Assert( Trigger::isAtomicTrigger( d_match_pattern ) );
+      //we are matching only in a particular equivalence class
+      d_cg = new inst::CandidateGeneratorQE( qe, d_match_pattern.getOperator() );
+      //store the equivalence class that we will call d_cg->reset( ... ) on
+      d_eq_class = d_pattern[1];
+    }
+  }else if( Trigger::isAtomicTrigger( d_match_pattern ) ){
+    //if( d_matchPolicy==MATCH_GEN_EFFICIENT_E_MATCH ){
+      //Warning() << "Currently efficient e matching is not taken into account for quantifiers: " << d_pattern << std::endl;
+    //}
+    //we will be scanning lists trying to find d_match_pattern.getOperator()
+    d_cg = new inst::CandidateGeneratorQE( qe, d_match_pattern.getOperator() );
+  }else{
+    d_cg = new CandidateGeneratorQueue;
+    if( !Trigger::getPatternArithmetic( d_match_pattern.getAttribute(InstConstantAttribute()), d_match_pattern, d_arith_coeffs ) ){
+      Debug("inst-match-gen") << "(?) Unknown matching pattern is " << d_match_pattern << std::endl;
+      Warning() << "(?) Unknown matching pattern is " << d_match_pattern << std::endl;
+      d_matchPolicy = MATCH_GEN_INTERNAL_ERROR;
+    }else{
+      Debug("matching-arith") << "Generated arithmetic pattern for " << d_match_pattern << ": " << std::endl;
+      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
+        Debug("matching-arith") << "   " << it->first << " -> " << it->second << std::endl;
+      }
+      //we will treat this as match gen internal arithmetic
+      d_matchPolicy = MATCH_GEN_INTERNAL_ARITHMETIC;
+    }
+  }
+}
+
+/** get match (not modulo equality) */
+bool InstMatchGenerator::getMatch( Node t, InstMatch& m, QuantifiersEngine* qe ){
+  Debug("matching") << "Matching " << t << " against pattern " << d_match_pattern << " ("
+                    << m.size() << ")" << ", " << d_children.size() << std::endl;
+  Assert( !d_match_pattern.isNull() );
+  if( qe->d_optMatchIgnoreModelBasis && t.getAttribute(ModelBasisAttribute()) ){
+    return true;
+  }else if( d_matchPolicy==MATCH_GEN_INTERNAL_ARITHMETIC ){
+    return getMatchArithmetic( t, m, qe );
+  }else if( d_matchPolicy==MATCH_GEN_INTERNAL_ERROR ){
+    return false;
+  }else{
+    EqualityQuery* q = qe->getEqualityQuery();
+    //add m to partial match vector
+    std::vector< InstMatch > partial;
+    partial.push_back( InstMatch( &m ) );
+    //if t is null
+    Assert( !t.isNull() );
+    Assert( !t.hasAttribute(InstConstantAttribute()) );
+    Assert( t.getKind()==d_match_pattern.getKind() );
+    Assert( !Trigger::isAtomicTrigger( d_match_pattern ) || t.getOperator()==d_match_pattern.getOperator() );
+    //first, check if ground arguments are not equal, or a match is in conflict
+    for( int i=0; i<(int)d_match_pattern.getNumChildren(); i++ ){
+      if( d_match_pattern[i].hasAttribute(InstConstantAttribute()) ){
+        if( d_match_pattern[i].getKind()==INST_CONSTANT ){
+          if( !partial[0].setMatch( q, d_match_pattern[i], t[i] ) ){
+            //match is in conflict
+            Debug("matching-debug") << "Match in conflict " << t[i] << " and "
+                                    << d_match_pattern[i] << " because "
+                                    << partial[0].get(d_match_pattern[i])
+                                    << std::endl;
+            Debug("matching-fail") << "Match fail: " << partial[0].get(d_match_pattern[i]) << " and " << t[i] << std::endl;
+            return false;
+          }
+        }
+      }else{
+        if( !q->areEqual( d_match_pattern[i], t[i] ) ){
+          Debug("matching-fail") << "Match fail arg: " << d_match_pattern[i] << " and " << t[i] << std::endl;
+          //ground arguments are not equal
+          return false;
+        }
+      }
+    }
+    //now, fit children into match
+    //we will be requesting candidates for matching terms for each child
+    std::vector< Node > reps;
+    for( int i=0; i<(int)d_children.size(); i++ ){
+      Node rep = q->getRepresentative( t[ d_children_index[i] ] );
+      reps.push_back( rep );
+      d_children[i]->d_cg->reset( rep );
+    }
+
+    //combine child matches
+    int index = 0;
+    while( index>=0 && index<(int)d_children.size() ){
+      partial.push_back( InstMatch( &partial[index] ) );
+      if( d_children[index]->getNextMatch2( partial[index+1], qe ) ){
+        index++;
+      }else{
+        d_children[index]->d_cg->reset( reps[index] );
+        partial.pop_back();
+        if( !partial.empty() ){
+          partial.pop_back();
+        }
+        index--;
+      }
+    }
+    if( index>=0 ){
+      m = partial.back();
+      return true;
+    }else{
+      return false;
+    }
+  }
+}
+
+bool InstMatchGenerator::getNextMatch2( InstMatch& m, QuantifiersEngine* qe, bool saveMatched ){
+  bool success = false;
+  Node t;
+  do{
+    //get the next candidate term t
+    t = d_cg->getNextCandidate();
+    //if t not null, try to fit it into match m
+    if( !t.isNull() && t.getType()==d_match_pattern.getType() ){
+      success = getMatch( t, m, qe );
+    }
+  }while( !success && !t.isNull() );
+  if (saveMatched) m.d_matched = t;
+  return success;
+}
+
+bool InstMatchGenerator::getMatchArithmetic( Node t, InstMatch& m, QuantifiersEngine* qe ){
+  Debug("matching-arith") << "Matching " << t << " " << d_match_pattern << std::endl;
+  if( !d_arith_coeffs.empty() ){
+    NodeBuilder<> tb(kind::PLUS);
+    Node ic = Node::null();
+    for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
+      Debug("matching-arith") << it->first << " -> " << it->second << std::endl;
+      if( !it->first.isNull() ){
+        if( m.find( it->first )==m.end() ){
+          //see if we can choose this to set
+          if( ic.isNull() && ( it->second.isNull() || !it->first.getType().isInteger() ) ){
+            ic = it->first;
+          }
+        }else{
+          Debug("matching-arith") << "already set " << m.get( it->first ) << std::endl;
+          Node tm = m.get( it->first );
+          if( !it->second.isNull() ){
+            tm = NodeManager::currentNM()->mkNode( MULT, it->second, tm );
+          }
+          tb << tm;
+        }
+      }else{
+        tb << it->second;
+      }
+    }
+    if( !ic.isNull() ){
+      Node tm;
+      if( tb.getNumChildren()==0 ){
+        tm = t;
+      }else{
+        tm = tb.getNumChildren()==1 ? tb.getChild( 0 ) : tb;
+        tm = NodeManager::currentNM()->mkNode( MINUS, t, tm );
+      }
+      if( !d_arith_coeffs[ ic ].isNull() ){
+        Assert( !ic.getType().isInteger() );
+        Node coeff = NodeManager::currentNM()->mkConst( Rational(1) / d_arith_coeffs[ ic ].getConst<Rational>() );
+        tm = NodeManager::currentNM()->mkNode( MULT, coeff, tm );
+      }
+      m.set( ic, Rewriter::rewrite( tm ));
+      //set the rest to zeros
+      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
+        if( !it->first.isNull() ){
+          if( m.find( it->first )==m.end() ){
+            m.set( it->first, NodeManager::currentNM()->mkConst( Rational(0) ) );
+          }
+        }
+      }
+      Debug("matching-arith") << "Setting " << ic << " to " << tm << std::endl;
+      return true;
+    }else{
+      return false;
+    }
+  }else{
+    return false;
+  }
+}
+
+
+/** reset instantiation round */
+void InstMatchGenerator::resetInstantiationRound( QuantifiersEngine* qe ){
+  if( d_match_pattern.isNull() ){
+    for( int i=0; i<(int)d_children.size(); i++ ){
+      d_children[i]->resetInstantiationRound( qe );
+    }
+  }else{
+    if( d_cg ){
+      d_cg->resetInstantiationRound();
+    }
+  }
+}
+
+void InstMatchGenerator::reset( Node eqc, QuantifiersEngine* qe ){
+  if( d_match_pattern.isNull() ){
+    for( int i=0; i<(int)d_children.size(); i++ ){
+      d_children[i]->reset( eqc, qe );
+    }
+    d_partial.clear();
+  }else{
+    if( !d_eq_class.isNull() ){
+      //we have a specific equivalence class in mind
+      //we are producing matches for f(E) ~ t, where E is a non-ground vector of terms, and t is a ground term
+      //just look in equivalence class of the RHS
+      d_cg->reset( d_eq_class );
+    }else{
+      d_cg->reset( eqc );
+    }
+  }
+}
+
+bool InstMatchGenerator::getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+  m.d_matched = Node::null();
+  if( d_match_pattern.isNull() ){
+    int index = (int)d_partial.size();
+    while( index>=0 && index<(int)d_children.size() ){
+      if( index>0 ){
+        d_partial.push_back( InstMatch( &d_partial[index-1] ) );
+      }else{
+        d_partial.push_back( InstMatch() );
+      }
+      if( d_children[index]->getNextMatch( d_partial[index], qe ) ){
+        index++;
+      }else{
+        d_children[index]->reset( Node::null(), qe );
+        d_partial.pop_back();
+        if( !d_partial.empty() ){
+          d_partial.pop_back();
+        }
+        index--;
+      }
+    }
+    if( index>=0 ){
+      m = d_partial.back();
+      d_partial.pop_back();
+      return true;
+    }else{
+      return false;
+    }
+  }else{
+    bool res = getNextMatch2( m, qe, true );
+    Assert(!res || !m.d_matched.isNull());
+    return res;
+  }
+}
+
+
+
+// Currently the implementation doesn't take into account that
+// variable should have the same value given.
+// TODO use the d_children way perhaps
+// TODO replace by a real dictionnary
+// We should create a real substitution? slower more precise
+// We don't do that often
+bool InstMatchGenerator::nonunifiable( TNode t0, const std::vector<Node> & vars){
+  if(d_match_pattern.isNull()) return true;
+
+  typedef std::vector<std::pair<TNode,TNode> > tstack;
+  tstack stack(1,std::make_pair(t0,d_match_pattern)); // t * pat
+
+  while(!stack.empty()){
+    const std::pair<TNode,TNode> p = stack.back(); stack.pop_back();
+    const TNode & t = p.first;
+    const TNode & pat = p.second;
+
+    // t or pat is a variable currently we consider that can match anything
+    if( find(vars.begin(),vars.end(),t) != vars.end() ) continue;
+    if( pat.getKind() == INST_CONSTANT ) continue;
+
+    // t and pat are nonunifiable
+    if( !Trigger::isAtomicTrigger( t ) || !Trigger::isAtomicTrigger( pat ) ) {
+      if(t == pat) continue;
+      else return true;
+    };
+    if( t.getOperator() != pat.getOperator() ) return true;
+
+    //put the children on the stack
+    for( size_t i=0; i < pat.getNumChildren(); i++ ){
+      stack.push_back(std::make_pair(t[i],pat[i]));
+    };
+  }
+  // The heuristic can't find non-unifiability
+  return false;
+}
+
+int InstMatchGenerator::addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe ){
+  //now, try to add instantiation for each match produced
+  int addedLemmas = 0;
+  InstMatch m;
+  while( getNextMatch( m, qe ) ){
+    //m.makeInternal( d_quantEngine->getEqualityQuery() );
+    m.add( baseMatch );
+    if( qe->addInstantiation( f, m ) ){
+      addedLemmas++;
+      if( qe->d_optInstLimitActive && qe->d_optInstLimit<=0 ){
+        return addedLemmas;
+      }
+    }
+    m.clear();
+  }
+  //return number of lemmas added
+  return addedLemmas;
+}
+
+int InstMatchGenerator::addTerm( Node f, Node t, QuantifiersEngine* qe ){
+  Assert( options::eagerInstQuant() );
+  if( !d_match_pattern.isNull() ){
+    InstMatch m;
+    if( getMatch( t, m, qe ) ){
+      if( qe->addInstantiation( f, m ) ){
+        return 1;
+      }
+    }
+  }else{
+    for( int i=0; i<(int)d_children.size(); i++ ){
+      d_children[i]->addTerm( f, t, qe );
+    }
+  }
+  return 0;
+}
+
+/** constructors */
+InstMatchGeneratorMulti::InstMatchGeneratorMulti( Node f, std::vector< Node >& pats, QuantifiersEngine* qe, int matchOption ) :
+d_f( f ){
+  Debug("smart-multi-trigger") << "Making smart multi-trigger for " << f << std::endl;
+  std::map< Node, std::vector< Node > > var_contains;
+  Trigger::getVarContains( f, pats, var_contains );
+  //convert to indicies
+  for( std::map< Node, std::vector< Node > >::iterator it = var_contains.begin(); it != var_contains.end(); ++it ){
+    Debug("smart-multi-trigger") << "Pattern " << it->first << " contains: ";
+    for( int i=0; i<(int)it->second.size(); i++ ){
+      Debug("smart-multi-trigger") << it->second[i] << " ";
+      int index = it->second[i].getAttribute(InstVarNumAttribute());
+      d_var_contains[ it->first ].push_back( index );
+      d_var_to_node[ index ].push_back( it->first );
+    }
+    Debug("smart-multi-trigger") << std::endl;
+  }
+  for( int i=0; i<(int)pats.size(); i++ ){
+    Node n = pats[i];
+    //make the match generator
+    d_children.push_back( new InstMatchGenerator( n, qe, matchOption ) );
+    //compute unique/shared variables
+    std::vector< int > unique_vars;
+    std::map< int, bool > shared_vars;
+    int numSharedVars = 0;
+    for( int j=0; j<(int)d_var_contains[n].size(); j++ ){
+      if( d_var_to_node[ d_var_contains[n][j] ].size()==1 ){
+        Debug("smart-multi-trigger") << "Var " << d_var_contains[n][j] << " is unique to " << pats[i] << std::endl;
+        unique_vars.push_back( d_var_contains[n][j] );
+      }else{
+        shared_vars[ d_var_contains[n][j] ] = true;
+        numSharedVars++;
+      }
+    }
+    //we use the latest shared variables, then unique variables
+    std::vector< int > vars;
+    int index = i==0 ? (int)(pats.size()-1) : (i-1);
+    while( numSharedVars>0 && index!=i ){
+      for( std::map< int, bool >::iterator it = shared_vars.begin(); it != shared_vars.end(); ++it ){
+        if( it->second ){
+          if( std::find( d_var_contains[ pats[index] ].begin(), d_var_contains[ pats[index] ].end(), it->first )!=
+              d_var_contains[ pats[index] ].end() ){
+            vars.push_back( it->first );
+            shared_vars[ it->first ] = false;
+            numSharedVars--;
+          }
+        }
+      }
+      index = index==0 ? (int)(pats.size()-1) : (index-1);
+    }
+    vars.insert( vars.end(), unique_vars.begin(), unique_vars.end() );
+    Debug("smart-multi-trigger") << "   Index[" << i << "]: ";
+    for( int i=0; i<(int)vars.size(); i++ ){
+      Debug("smart-multi-trigger") << vars[i] << " ";
+    }
+    Debug("smart-multi-trigger") << std::endl;
+    //make ordered inst match trie
+    InstMatchTrie::ImtIndexOrder* imtio = new InstMatchTrie::ImtIndexOrder;
+    imtio->d_order.insert( imtio->d_order.begin(), vars.begin(), vars.end() );
+    d_children_trie.push_back( InstMatchTrieOrdered( imtio ) );
+  }
+
+}
+
+/** reset instantiation round (call this whenever equivalence classes have changed) */
+void InstMatchGeneratorMulti::resetInstantiationRound( QuantifiersEngine* qe ){
+  for( int i=0; i<(int)d_children.size(); i++ ){
+    d_children[i]->resetInstantiationRound( qe );
+  }
+}
+
+/** reset, eqc is the equivalence class to search in (any if eqc=null) */
+void InstMatchGeneratorMulti::reset( Node eqc, QuantifiersEngine* qe ){
+  for( int i=0; i<(int)d_children.size(); i++ ){
+    d_children[i]->reset( eqc, qe );
+  }
+}
+
+int InstMatchGeneratorMulti::addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe ){
+  int addedLemmas = 0;
+  Debug("smart-multi-trigger") << "Process smart multi trigger" << std::endl;
+  for( int i=0; i<(int)d_children.size(); i++ ){
+    Debug("smart-multi-trigger") << "Calculate matches " << i << std::endl;
+    std::vector< InstMatch > newMatches;
+    InstMatch m;
+    while( d_children[i]->getNextMatch( m, qe ) ){
+      m.makeRepresentative( qe );
+      newMatches.push_back( InstMatch( &m ) );
+      m.clear();
+    }
+    for( int j=0; j<(int)newMatches.size(); j++ ){
+      processNewMatch( qe, newMatches[j], i, addedLemmas );
+    }
+  }
+  return addedLemmas;
+}
+
+void InstMatchGeneratorMulti::processNewMatch( QuantifiersEngine* qe, InstMatch& m, int fromChildIndex, int& addedLemmas ){
+  //see if these produce new matches
+  d_children_trie[fromChildIndex].addInstMatch( qe, d_f, m, true );
+  //possibly only do the following if we know that new matches will be produced?
+  //the issue is that instantiations are filtered in quantifiers engine, and so there is no guarentee that
+  // we can safely skip the following lines, even when we have already produced this match.
+  Debug("smart-multi-trigger") << "Child " << fromChildIndex << " produced match " << m << std::endl;
+  //process new instantiations
+  int childIndex = (fromChildIndex+1)%(int)d_children.size();
+  std::vector< IndexedTrie > unique_var_tries;
+  processNewInstantiations( qe, m, addedLemmas, d_children_trie[childIndex].getTrie(),
+                            unique_var_tries, 0, childIndex, fromChildIndex, true );
+}
+
+void InstMatchGeneratorMulti::processNewInstantiations( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas, InstMatchTrie* tr,
+                                                        std::vector< IndexedTrie >& unique_var_tries,
+                                                        int trieIndex, int childIndex, int endChildIndex, bool modEq ){
+  if( childIndex==endChildIndex ){
+    //now, process unique variables
+    processNewInstantiations2( qe, m, addedLemmas, unique_var_tries, 0 );
+  }else if( trieIndex<(int)d_children_trie[childIndex].getOrdering()->d_order.size() ){
+    int curr_index = d_children_trie[childIndex].getOrdering()->d_order[trieIndex];
+    Node curr_ic = qe->getTermDatabase()->getInstantiationConstant( d_f, curr_index );
+    if( m.find( curr_ic )==m.end() ){
+      //if( d_var_to_node[ curr_index ].size()==1 ){    //FIXME
+      //  //unique variable(s), defer calculation
+      //  unique_var_tries.push_back( IndexedTrie( std::pair< int, int >( childIndex, trieIndex ), tr ) );
+      //  int newChildIndex = (childIndex+1)%(int)d_children.size();
+      //  processNewInstantiations( qe, m, d_children_trie[newChildIndex].getTrie(), unique_var_tries,
+      //                            0, newChildIndex, endChildIndex, modEq );
+      //}else{
+        //shared and non-set variable, add to InstMatch
+        for( std::map< Node, InstMatchTrie >::iterator it = tr->d_data.begin(); it != tr->d_data.end(); ++it ){
+          InstMatch mn( &m );
+          mn.set( curr_ic, it->first);
+          processNewInstantiations( qe, mn, addedLemmas, &(it->second), unique_var_tries,
+                                    trieIndex+1, childIndex, endChildIndex, modEq );
+        }
+      //}
+    }else{
+      //shared and set variable, try to merge
+      Node n = m.get( curr_ic );
+      std::map< Node, InstMatchTrie >::iterator it = tr->d_data.find( n );
+      if( it!=tr->d_data.end() ){
+        processNewInstantiations( qe, m, addedLemmas, &(it->second), unique_var_tries,
+                                  trieIndex+1, childIndex, endChildIndex, modEq );
+      }
+      if( modEq ){
+        //check modulo equality for other possible instantiations
+        if( 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 = tr->d_data.find( en );
+              if( itc!=tr->d_data.end() ){
+                processNewInstantiations( qe, m, addedLemmas, &(itc->second), unique_var_tries,
+                                          trieIndex+1, childIndex, endChildIndex, modEq );
+              }
+            }
+            ++eqc;
+          }
+        }
+      }
+    }
+  }else{
+    int newChildIndex = (childIndex+1)%(int)d_children.size();
+    processNewInstantiations( qe, m, addedLemmas, d_children_trie[newChildIndex].getTrie(), unique_var_tries,
+                              0, newChildIndex, endChildIndex, modEq );
+  }
+}
+
+void InstMatchGeneratorMulti::processNewInstantiations2( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas,
+                                                         std::vector< IndexedTrie >& unique_var_tries,
+                                                         int uvtIndex, InstMatchTrie* tr, int trieIndex ){
+  if( uvtIndex<(int)unique_var_tries.size() ){
+    int childIndex = unique_var_tries[uvtIndex].first.first;
+    if( !tr ){
+      tr = unique_var_tries[uvtIndex].second;
+      trieIndex = unique_var_tries[uvtIndex].first.second;
+    }
+    if( trieIndex<(int)d_children_trie[childIndex].getOrdering()->d_order.size() ){
+      int curr_index = d_children_trie[childIndex].getOrdering()->d_order[trieIndex];
+      Node curr_ic = qe->getTermDatabase()->getInstantiationConstant( d_f, curr_index );
+      //unique non-set variable, add to InstMatch
+      for( std::map< Node, InstMatchTrie >::iterator it = tr->d_data.begin(); it != tr->d_data.end(); ++it ){
+        InstMatch mn( &m );
+        mn.set( curr_ic, it->first);
+        processNewInstantiations2( qe, mn, addedLemmas, unique_var_tries, uvtIndex, &(it->second), trieIndex+1 );
+      }
+    }else{
+      processNewInstantiations2( qe, m, addedLemmas, unique_var_tries, uvtIndex+1 );
+    }
+  }else{
+    //m is an instantiation
+    if( qe->addInstantiation( d_f, m ) ){
+      addedLemmas++;
+      Debug("smart-multi-trigger") << "-> Produced instantiation " << m << std::endl;
+    }
+  }
+}
+
+int InstMatchGeneratorMulti::addTerm( Node f, Node t, QuantifiersEngine* qe ){
+  Assert( options::eagerInstQuant() );
+  int addedLemmas = 0;
+  for( int i=0; i<(int)d_children.size(); i++ ){
+    if( ((InstMatchGenerator*)d_children[i])->d_match_pattern.getOperator()==t.getOperator() ){
+      InstMatch m;
+      //if it produces a match, then process it with the rest
+      if( ((InstMatchGenerator*)d_children[i])->getMatch( t, m, qe ) ){
+        processNewMatch( qe, m, i, addedLemmas );
+      }
+    }
+  }
+  return addedLemmas;
+}
+
+int InstMatchGeneratorSimple::addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe ){
+  InstMatch m;
+  m.add( baseMatch );
+  int addedLemmas = 0;
+  if( d_match_pattern.getType()==NodeManager::currentNM()->booleanType() ){
+    for( int i=0; i<2; i++ ){
+      addInstantiations( m, qe, addedLemmas, 0, &(qe->getTermDatabase()->d_pred_map_trie[i][ d_match_pattern.getOperator() ]) );
+    }
+  }else{
+    addInstantiations( m, qe, addedLemmas, 0, &(qe->getTermDatabase()->d_func_map_trie[ d_match_pattern.getOperator() ]) );
+  }
+  return addedLemmas;
+}
+
+void InstMatchGeneratorSimple::addInstantiations( InstMatch& m, QuantifiersEngine* qe, int& addedLemmas, int argIndex, quantifiers::TermArgTrie* tat ){
+  if( argIndex==(int)d_match_pattern.getNumChildren() ){
+    //m is an instantiation
+    if( qe->addInstantiation( d_f, m ) ){
+      addedLemmas++;
+      Debug("simple-multi-trigger") << "-> Produced instantiation " << m << std::endl;
+    }
+  }else{
+    if( d_match_pattern[argIndex].getKind()==INST_CONSTANT ){
+      Node ic = d_match_pattern[argIndex];
+      for( std::map< Node, quantifiers::TermArgTrie >::iterator it = tat->d_data.begin(); it != tat->d_data.end(); ++it ){
+        Node t = it->first;
+        if( m.get( ic ).isNull() || m.get( ic )==t ){
+          Node prev = m.get( ic );
+          m.set( ic, t);
+          addInstantiations( m, qe, addedLemmas, argIndex+1, &(it->second) );
+          m.set( ic, prev);
+        }
+      }
+    }else{
+      Node r = qe->getEqualityQuery()->getRepresentative( d_match_pattern[argIndex] );
+      std::map< Node, quantifiers::TermArgTrie >::iterator it = tat->d_data.find( r );
+      if( it!=tat->d_data.end() ){
+        addInstantiations( m, qe, addedLemmas, argIndex+1, &(it->second) );
+      }
+    }
+  }
+}
+
+int InstMatchGeneratorSimple::addTerm( Node f, Node t, QuantifiersEngine* qe ){
+  Assert( options::eagerInstQuant() );
+  InstMatch m;
+  for( int i=0; i<(int)t.getNumChildren(); i++ ){
+    if( d_match_pattern[i].getKind()==INST_CONSTANT ){
+      m.set(d_match_pattern[i], t[i]);
+    }else if( !qe->getEqualityQuery()->areEqual( d_match_pattern[i], t[i] ) ){
+      return 0;
+    }
+  }
+  return qe->addInstantiation( f, m ) ? 1 : 0;
+}
diff --git a/src/theory/quantifiers/inst_match.h b/src/theory/quantifiers/inst_match.h
new file mode 100644 (file)
index 0000000..fffa3bc
--- /dev/null
@@ -0,0 +1,394 @@
+/*********************                                                        */
+/*! \file inst_match.h
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief inst match class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__QUANTIFIERS__INST_MATCH_H
+#define __CVC4__THEORY__QUANTIFIERS__INST_MATCH_H
+
+#include "util/hash.h"
+
+#include <ext/hash_set>
+#include <iostream>
+#include <map>
+
+#include "context/cdlist.h"
+#include "theory/quantifiers/candidate_generator.h"
+
+//#define USE_EFFICIENT_E_MATCHING
+
+namespace CVC4 {
+namespace theory {
+
+/** Attribute true for nodes that should not be used for matching */
+struct NoMatchAttributeId {};
+/** use the special for boolean flag */
+typedef expr::Attribute< NoMatchAttributeId,
+                         bool,
+                         expr::attr::NullCleanupStrategy,
+                         true // context dependent
+                       > NoMatchAttribute;
+
+// attribute for "contains instantiation constants from"
+struct InstConstantAttributeId {};
+typedef expr::Attribute<InstConstantAttributeId, Node> InstConstantAttribute;
+
+struct InstLevelAttributeId {};
+typedef expr::Attribute<InstLevelAttributeId, uint64_t> InstLevelAttribute;
+
+struct InstVarNumAttributeId {};
+typedef expr::Attribute<InstVarNumAttributeId, uint64_t> InstVarNumAttribute;
+
+// Attribute that tell if a node have been asserted in this branch
+struct AvailableInTermDbId {};
+/** use the special for boolean flag */
+typedef expr::Attribute<AvailableInTermDbId,
+                        bool,
+                        expr::attr::NullCleanupStrategy,
+                        true  // context dependent
+                        > AvailableInTermDb;
+
+
+class QuantifiersEngine;
+namespace quantifiers{
+  class TermArgTrie;
+}
+
+namespace uf{
+  class InstantiatorTheoryUf;
+  class TheoryUF;
+}/* CVC4::theory::uf namespace */
+
+namespace inst {
+
+class EqualityQuery {
+public:
+  EqualityQuery(){}
+  virtual ~EqualityQuery(){};
+  /** contains term */
+  virtual bool hasTerm( Node a ) = 0;
+  /** get the representative of the equivalence class of a */
+  virtual Node getRepresentative( Node a ) = 0;
+  /** returns true if a and b are equal in the current context */
+  virtual bool areEqual( Node a, Node b ) = 0;
+  /** returns true is a and b are disequal in the current context */
+  virtual bool areDisequal( Node a, Node b ) = 0;
+  /** getInternalRepresentative gets the current best representative in the equivalence class of a, based on some criteria.
+      If cbqi is active, this will return a term in the equivalence class of "a" that does
+      not contain instantiation constants, if such a term exists.
+   */
+  virtual Node getInternalRepresentative( Node a ) = 0;
+  /** get the equality engine associated with this query */
+  virtual eq::EqualityEngine* getEngine() = 0;
+  /** get the equivalence class of a */
+  virtual void getEquivalenceClass( Node a, std::vector< Node >& eqc ) = 0;
+};/* class EqualityQuery */
+
+/** basic class defining an instantiation */
+class InstMatch {
+  /* map from variable to ground terms */
+  std::map< Node, Node > d_map;
+public:
+  InstMatch();
+  InstMatch( InstMatch* m );
+
+  /** set the match of v to m */
+  bool setMatch( EqualityQuery* q, TNode v, TNode m );
+  /* This version tell if the variable has been set */
+  bool setMatch( EqualityQuery* q, TNode v, TNode m, bool & set);
+  /** fill all unfilled values with m */
+  bool add( InstMatch& m );
+  /** if compatible, fill all unfilled values with m and return true
+      return false otherwise */
+  bool merge( EqualityQuery* q, InstMatch& m );
+  /** debug print method */
+  void debugPrint( const char* c );
+  /** make complete */
+  void makeComplete( Node f, QuantifiersEngine* qe );
+  /** make internal: ensure that no term in d_map contains instantiation constants */
+  void makeInternal( QuantifiersEngine* qe );
+  /** make representative */
+  void makeRepresentative( QuantifiersEngine* qe );
+  /** apply rewrite */
+  void applyRewrite();
+  /** compute d_match */
+  void computeTermVec( QuantifiersEngine* qe, const std::vector< Node >& vars, std::vector< Node >& match );
+  /** compute d_match */
+  void computeTermVec( const std::vector< Node >& vars, std::vector< Node >& match );
+  /** clear */
+  void clear(){ d_map.clear(); }
+  /** erase */
+  template<class Iterator>
+  void erase(Iterator begin, Iterator end){
+    for(Iterator i = begin; i != end; ++i){
+      d_map.erase(*i);
+    };
+  }
+  void erase(Node node){ d_map.erase(node); }
+  /** is_empty */
+  bool empty(){ return d_map.empty(); }
+  /** set */
+  void set(TNode var, TNode n){
+    //std::cout << "var.getType() " << var.getType() << "n.getType() " << n.getType() << std::endl ;
+    Assert( !var.isNull() );
+    Assert( n.isNull() ||// For a strange use in inst_match.cpp InstMatchGeneratorSimple::addInstantiations
+            var.getType() == n.getType() );
+    d_map[var] = n;
+  }
+  Node get(TNode var){ return d_map[var]; }
+  size_t size(){ return d_map.size(); }
+  /* iterator */
+  std::map< Node, Node >::iterator begin(){ return d_map.begin(); };
+  std::map< Node, Node >::iterator end(){ return d_map.end(); };
+  std::map< Node, Node >::iterator find(Node var){ return d_map.find(var); };
+  /* Node used for matching the trigger only for mono-trigger (just for
+     efficiency because I need only that) */
+  Node d_matched;
+  /** to stream */
+  inline void toStream(std::ostream& out) const {
+    out << "INST_MATCH( ";
+    for( std::map< Node, Node >::const_iterator it = d_map.begin(); it != d_map.end(); ++it ){
+      if( it != d_map.begin() ){ out << ", "; }
+      out << it->first << " -> " << it->second;
+    }
+    out << " )";
+  }
+};/* class InstMatch */
+
+inline std::ostream& operator<<(std::ostream& out, const InstMatch& m) {
+  m.toStream(out);
+  return out;
+}
+
+/** trie for InstMatch objects */
+class InstMatchTrie {
+public:
+  class ImtIndexOrder {
+  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 existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, int index, ImtIndexOrder* imtio );
+public:
+  /** the data */
+  std::map< Node, InstMatchTrie > d_data;
+public:
+  InstMatchTrie(){}
+  ~InstMatchTrie(){}
+public:
+  /** 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, ImtIndexOrder* imtio = NULL );
+};/* class InstMatchTrie */
+
+class InstMatchTrieOrdered {
+private:
+  InstMatchTrie::ImtIndexOrder* d_imtio;
+  InstMatchTrie d_imt;
+public:
+  InstMatchTrieOrdered( InstMatchTrie::ImtIndexOrder* imtio ) : d_imtio( imtio ){}
+  ~InstMatchTrieOrdered(){}
+  /** get ordering */
+  InstMatchTrie::ImtIndexOrder* getOrdering() { return d_imtio; }
+  /** get trie */
+  InstMatchTrie* getTrie() { return &d_imt; }
+public:
+  /** add match m, return true if successful */
+  bool addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false ){
+    return d_imt.addInstMatch( qe, f, m, modEq, d_imtio );
+  }
+};/* class InstMatchTrieOrdered */
+
+/** base class for producing InstMatch objects */
+class IMGenerator {
+public:
+  /** reset instantiation round (call this at beginning of instantiation round) */
+  virtual void resetInstantiationRound( QuantifiersEngine* qe ) = 0;
+  /** reset, eqc is the equivalence class to search in (any if eqc=null) */
+  virtual void reset( Node eqc, QuantifiersEngine* qe ) = 0;
+  /** get the next match.  must call reset( eqc ) before this function. */
+  virtual bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) = 0;
+  /** return true if whatever Node is substituted for the variables the
+      given Node can't match the pattern */
+  virtual bool nonunifiable( TNode t, const std::vector<Node> & vars) = 0;
+  /** add instantiations directly */
+  virtual int addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe ) = 0;
+  /** add ground term t, called when t is added to term db */
+  virtual int addTerm( Node f, Node t, QuantifiersEngine* qe ) = 0;
+};/* class IMGenerator */
+
+
+class InstMatchGenerator : public IMGenerator {
+private:
+  /** candidate generator */
+  CandidateGenerator* d_cg;
+  /** policy to use for matching */
+  int d_matchPolicy;
+  /** children generators */
+  std::vector< InstMatchGenerator* > d_children;
+  std::vector< int > d_children_index;
+  /** partial vector */
+  std::vector< InstMatch > d_partial;
+  /** eq class */
+  Node d_eq_class;
+  /** for arithmetic matching */
+  std::map< Node, Node > d_arith_coeffs;
+  /** initialize pattern */
+  void initializePatterns( std::vector< Node >& pats, QuantifiersEngine* qe );
+  void initializePattern( Node pat, QuantifiersEngine* qe );
+public:
+  enum {
+    //options for producing matches
+    MATCH_GEN_DEFAULT = 0,
+    MATCH_GEN_EFFICIENT_E_MATCH,   //generate matches via Efficient E-matching for SMT solvers
+    //others (internally used)
+    MATCH_GEN_INTERNAL_ARITHMETIC,
+    MATCH_GEN_INTERNAL_ERROR,
+  };
+private:
+  /** get the next match.  must call d_cg->reset( ... ) before using.
+      only valid for use where !d_match_pattern.isNull().
+  */
+  bool getNextMatch2( InstMatch& m, QuantifiersEngine* qe, bool saveMatched = false );
+  /** for arithmetic */
+  bool getMatchArithmetic( Node t, InstMatch& m, QuantifiersEngine* qe );
+public:
+  /** get the match against ground term or formula t.
+      d_match_pattern and t should have the same shape.
+      only valid for use where !d_match_pattern.isNull().
+  */
+  bool getMatch( Node t, InstMatch& m, QuantifiersEngine* qe );
+
+  /** constructors */
+  InstMatchGenerator( Node pat, QuantifiersEngine* qe, int matchOption = 0 );
+  InstMatchGenerator( std::vector< Node >& pats, QuantifiersEngine* qe, int matchOption = 0 );
+  /** destructor */
+  ~InstMatchGenerator(){}
+  /** The pattern we are producing matches for.
+      If null, this is a multi trigger that is merging matches from d_children.
+  */
+  Node d_pattern;
+  /** match pattern */
+  Node d_match_pattern;
+public:
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  void resetInstantiationRound( QuantifiersEngine* qe );
+  /** reset, eqc is the equivalence class to search in (any if eqc=null) */
+  void reset( Node eqc, QuantifiersEngine* qe );
+  /** get the next match.  must call reset( eqc ) before this function. */
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe );
+  /** return true if whatever Node is substituted for the variables the
+      given Node can't match the pattern */
+  bool nonunifiable( TNode t, const std::vector<Node> & vars);
+  /** add instantiations */
+  int addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe );
+  /** add ground term t */
+  int addTerm( Node f, Node t, QuantifiersEngine* qe );
+};/* class InstMatchGenerator */
+
+/** smart multi-trigger implementation */
+class InstMatchGeneratorMulti : public IMGenerator {
+private:
+  /** indexed trie */
+  typedef std::pair< std::pair< int, int >, InstMatchTrie* > IndexedTrie;
+  /** process new match */
+  void processNewMatch( QuantifiersEngine* qe, InstMatch& m, int fromChildIndex, int& addedLemmas );
+  /** process new instantiations */
+  void processNewInstantiations( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas, InstMatchTrie* tr,
+                                 std::vector< IndexedTrie >& unique_var_tries,
+                                 int trieIndex, int childIndex, int endChildIndex, bool modEq );
+  /** process new instantiations 2 */
+  void processNewInstantiations2( QuantifiersEngine* qe, InstMatch& m, int& addedLemmas,
+                                  std::vector< IndexedTrie >& unique_var_tries,
+                                  int uvtIndex, InstMatchTrie* tr = NULL, int trieIndex = 0 );
+private:
+  /** var contains (variable indices) for each pattern node */
+  std::map< Node, std::vector< int > > d_var_contains;
+  /** variable indices contained to pattern nodes */
+  std::map< int, std::vector< Node > > d_var_to_node;
+  /** quantifier to use */
+  Node d_f;
+  /** policy to use for matching */
+  int d_matchPolicy;
+  /** children generators */
+  std::vector< InstMatchGenerator* > d_children;
+  /** inst match tries for each child */
+  std::vector< InstMatchTrieOrdered > d_children_trie;
+  /** calculate matches */
+  void calculateMatches( QuantifiersEngine* qe );
+public:
+  /** constructors */
+  InstMatchGeneratorMulti( Node f, std::vector< Node >& pats, QuantifiersEngine* qe, int matchOption = 0 );
+  /** destructor */
+  ~InstMatchGeneratorMulti(){}
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  void resetInstantiationRound( QuantifiersEngine* qe );
+  /** reset, eqc is the equivalence class to search in (any if eqc=null) */
+  void reset( Node eqc, QuantifiersEngine* qe );
+  /** get the next match.  must call reset( eqc ) before this function. (not implemented) */
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) { return false; }
+  /** return true if whatever Node is substituted for the variables the
+      given Node can't match the pattern */
+  bool nonunifiable( TNode t, const std::vector<Node> & vars) { return true; }
+  /** add instantiations */
+  int addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe );
+  /** add ground term t */
+  int addTerm( Node f, Node t, QuantifiersEngine* qe );
+};/* class InstMatchGeneratorMulti */
+
+/** smart (single)-trigger implementation */
+class InstMatchGeneratorSimple : public IMGenerator {
+private:
+  /** quantifier for match term */
+  Node d_f;
+  /** match term */
+  Node d_match_pattern;
+  /** add instantiations */
+  void addInstantiations( InstMatch& m, QuantifiersEngine* qe, int& addedLemmas, int argIndex, quantifiers::TermArgTrie* tat );
+public:
+  /** constructors */
+  InstMatchGeneratorSimple( Node f, Node pat ) : d_f( f ), d_match_pattern( pat ){}
+  /** destructor */
+  ~InstMatchGeneratorSimple(){}
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  void resetInstantiationRound( QuantifiersEngine* qe ) {}
+  /** reset, eqc is the equivalence class to search in (any if eqc=null) */
+  void reset( Node eqc, QuantifiersEngine* qe ) {}
+  /** get the next match.  must call reset( eqc ) before this function. (not implemented) */
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) { return false; }
+  /** return true if whatever Node is substituted for the variables the
+      given Node can't match the pattern */
+  bool nonunifiable( TNode t, const std::vector<Node> & vars) { return true; }
+  /** add instantiations */
+  int addInstantiations( Node f, InstMatch& baseMatch, QuantifiersEngine* qe );
+  /** add ground term t, possibly add instantiations */
+  int addTerm( Node f, Node t, QuantifiersEngine* qe );
+};/* class InstMatchGeneratorSimple */
+
+}/* CVC4::theory::inst namespace */
+
+typedef CVC4::theory::inst::InstMatch InstMatch;
+typedef CVC4::theory::inst::EqualityQuery EqualityQuery;
+
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__QUANTIFIERS__INST_MATCH_H */
index 13de210aba256ac57b84354f628d8cb056ea5230..37ee6d80126308ff6b28557ba996b69f7b9586e6 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "cvc4_private.h"
 
-#ifndef __CVC4__INSTANTIATION_ENGINE_H
-#define __CVC4__INSTANTIATION_ENGINE_H
+#ifndef __CVC4__THEORY__QUANTIFIERS__INSTANTIATION_ENGINE_H
+#define __CVC4__THEORY__QUANTIFIERS__INSTANTIATION_ENGINE_H
 
 #include "theory/quantifiers_engine.h"
 #include "theory/quantifiers/theory_quantifiers.h"
@@ -69,10 +69,10 @@ public:
 public:
   /** get the corresponding counterexample literal for quantified formula node n */
   Node getCounterexampleLiteralFor( Node f ) { return d_ce_lit.find( f )==d_ce_lit.end() ? Node::null() : d_ce_lit[ f ]; }
-};
+};/* class InstantiationEngine */
 
-}
-}
-}
+}/* CVC4::theory::quantifiers namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
-#endif
+#endif /* __CVC4__THEORY__QUANTIFIERS__INSTANTIATION_ENGINE_H */
diff --git a/src/theory/quantifiers/instantiator_default.cpp b/src/theory/quantifiers/instantiator_default.cpp
new file mode 100644 (file)
index 0000000..ca29f27
--- /dev/null
@@ -0,0 +1,56 @@
+/*********************                                                        */
+/*! \file instantiator_default.cpp
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of instantiator_default class
+ **/
+
+#include "theory/quantifiers/instantiator_default.h"
+#include "theory/theory_engine.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+
+InstantiatorDefault::InstantiatorDefault(context::Context* c, QuantifiersEngine* ie, Theory* th) :
+  Instantiator( c, ie, th ) {
+}
+
+void InstantiatorDefault::assertNode( Node assertion ){
+}
+
+void InstantiatorDefault::processResetInstantiationRound( Theory::Effort effort ){
+}
+
+int InstantiatorDefault::process( Node f, Theory::Effort effort, int e ){
+  /*
+  if( e < 4 ){
+    return InstStrategy::STATUS_UNFINISHED;
+  }else if( e == 4 ){
+    Debug("quant-default") << "Process " << f << " : " << std::endl;
+    InstMatch m;
+    for( int j=0; j<(int)d_quantEngine->getNumInstantiationConstants( f ); j++ ){
+      Node i = d_quantEngine->getInstantiationConstant( f, j );
+      Debug("quant-default") << "Getting value for " << i << std::endl;
+      if( d_quantEngine->getTheoryEngine()->theoryOf( i )==getTheory() ){    //if it belongs to this theory
+        Node val = d_th->getValue( i );
+        Debug("quant-default") << "Default Instantiate for " << d_th->getId() << ", setting " << i << " = " << val << std::endl;
+        m.set( i, val);
+      }
+    }
+    d_quantEngine->addInstantiation( f, m );
+  }
+  */
+  return InstStrategy::STATUS_UNKNOWN;
+}
diff --git a/src/theory/quantifiers/instantiator_default.h b/src/theory/quantifiers/instantiator_default.h
new file mode 100644 (file)
index 0000000..8e0a8de
--- /dev/null
@@ -0,0 +1,48 @@
+/*********************                                                        */
+/*! \file instantiator_default.h
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief instantiator_default
+ **/
+
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__QUANTIFIERS__INSTANTIATOR_DEFAULT_H
+#define __CVC4__THEORY__QUANTIFIERS__INSTANTIATOR_DEFAULT_H
+
+#include <string>
+#include "theory/quantifiers_engine.h"
+
+namespace CVC4 {
+namespace theory {
+
+class InstantiatorDefault : public Instantiator {
+  friend class QuantifiersEngine;
+protected:
+  /** reset instantiation round */
+  void processResetInstantiationRound(Theory::Effort effort);
+  /** process quantifier */
+  int process( Node f, Theory::Effort effort, int e );
+public:
+  InstantiatorDefault(context::Context* c, QuantifiersEngine* ie, Theory* th);
+  ~InstantiatorDefault() { }
+  /** check function, assertion is asserted to theory */
+  void assertNode( Node assertion );
+  /** identify */
+  std::string identify() const { return std::string("InstantiatorDefault"); }
+};/* class InstantiatorDefault */
+
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__QUANTIFIERS__INSTANTIATOR_DEFAULT_H */
index 05eb8f55f47cebb4c622c38cd36dd5d8b2746099..344b731e096d10801e16b38bd9f0286b8af5209c 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "cvc4_private.h"
 
-#ifndef __CVC4__QUANTIFIERS_MODEL_BUILDER_H
-#define __CVC4__QUANTIFIERS_MODEL_BUILDER_H
+#ifndef __CVC4__THEORY__QUANTIFIERS__MODEL_BUILDER_H
+#define __CVC4__THEORY__QUANTIFIERS__MODEL_BUILDER_H
 
 #include "theory/quantifiers_engine.h"
 #include "theory/model.h"
@@ -82,10 +82,10 @@ public:
     ~Statistics();
   };
   Statistics d_statistics;
-};
+};/* class ModelEngineBuilder */
 
-}
-}
-}
+}/* CVC4::theory::quantifiers namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
-#endif
+#endif /* __CVC4__THEORY__QUANTIFIERS__MODEL_BUILDER_H */
index 1139332fe659b76707dcef716f79901dfb3a293c..f5d1db736596346399f98a2a996542c021d36e6e 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "cvc4_private.h"
 
-#ifndef __CVC4__QUANTIFIERS_MODEL_ENGINE_H
-#define __CVC4__QUANTIFIERS_MODEL_ENGINE_H
+#ifndef __CVC4__THEORY__QUANTIFIERS__MODEL_ENGINE_H
+#define __CVC4__THEORY__QUANTIFIERS__MODEL_ENGINE_H
 
 #include "theory/quantifiers_engine.h"
 #include "theory/quantifiers/model_builder.h"
@@ -81,10 +81,10 @@ public:
     ~Statistics();
   };
   Statistics d_statistics;
-};
+};/* class ModelEngine */
 
-}
-}
-}
+}/* CVC4::theory::quantifiers namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
-#endif
+#endif /* __CVC4__THEORY__QUANTIFIERS__MODEL_ENGINE_H */
index 8c8ea6a424153117b3c6d9742474f8ff8d4b1db3..6ce47d114db9b7b295c82e6500368dbee68c88f0 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "cvc4_private.h"
 
-#ifndef __CVC4__RELEVANT_DOMAIN_H
-#define __CVC4__RELEVANT_DOMAIN_H
+#ifndef __CVC4__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H
+#define __CVC4__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H
 
 #include "theory/quantifiers/first_order_model.h"
 
@@ -45,10 +45,10 @@ public:
   void compute();
   //relevant instantiation domain for each quantifier
   std::map< Node, std::vector< RepDomain > > d_quant_inst_domain;
-};
+};/* class RelevantDomain */
 
-}
-}
-}
+}/* CVC4::theory::quantifiers namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
-#endif
+#endif /* __CVC4__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H */
index a5ec266a956b9f229e70acee09274e0dae166dd2..85a2f3fd2ab924654cb04a3a2c1f528d0303d2a5 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "cvc4_private.h"
 
-#ifndef __CVC4__REP_SET_ITERATOR_H
-#define __CVC4__REP_SET_ITERATOR_H
+#ifndef __CVC4__THEORY__QUANTIFIERS__REP_SET_ITERATOR_H
+#define __CVC4__THEORY__QUANTIFIERS__REP_SET_ITERATOR_H
 
 #include "theory/quantifiers_engine.h"
 #include "theory/quantifiers/first_order_model.h"
@@ -110,11 +110,10 @@ public:
   int d_eval_uf_terms;
   int d_eval_lits;
   int d_eval_lits_unknown;
-};
-
+};/* class RepSetEvaluator */
 
-}
-}
-}
+}/* CVC4::theory::quantifiers namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
 #endif
index 2af6992f7a3d9eb659445d1eaf6f8b776922fb49..8106b5715a34389ea4e9e7644a70a540c44c118b 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "cvc4_private.h"
 
-#ifndef __CVC4__QUANTIFIERS_TERM_DATABASE_H
-#define __CVC4__QUANTIFIERS_TERM_DATABASE_H
+#ifndef __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_H
+#define __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_H
 
 #include "theory/theory.h"
 
@@ -149,8 +149,8 @@ public:
   Node getFreeVariableForInstConstant( Node n );
 };/* class TermDb */
 
-}
-}
-}
+}/* CVC4::theory::quantifiers namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
-#endif
+#endif /* __CVC4__THEORY__QUANTIFIERS__TERM_DATABASE_H */
index bf17495a1c62bb7790261ac7481aded605dbf399..e837811b089917004d5bbc0968f8141f9b44c6a3 100644 (file)
@@ -17,8 +17,8 @@
 
 #include "cvc4_private.h"
 
-#ifndef __CVC4__INSTANTIATOR_QUANTIFIERS_H
-#define __CVC4__INSTANTIATOR_QUANTIFIERS_H
+#ifndef __CVC4__THEORY__QUANTIFIERS__THEORY_QUANTIFIERS_INSTANTIATOR_H
+#define __CVC4__THEORY__QUANTIFIERS__THEORY_QUANTIFIERS_INSTANTIATOR_H
 
 #include "theory/quantifiers_engine.h"
 
@@ -51,10 +51,10 @@ private:
     ~Statistics();
   };
   Statistics d_statistics;
-};/* class InstantiatiorTheoryArith  */
+};/* class InstantiatiorTheoryQuantifiers */
 
-}
-}
-}
+}/* CVC4::theory::quantifiers namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
-#endif
\ No newline at end of file
+#endif /* __CVC4__THEORY__QUANTIFIERS__THEORY_QUANTIFIERS_INSTANTIATOR_H */
diff --git a/src/theory/quantifiers/trigger.cpp b/src/theory/quantifiers/trigger.cpp
new file mode 100644 (file)
index 0000000..4bb8528
--- /dev/null
@@ -0,0 +1,558 @@
+/*********************                                                        */
+/*! \file trigger.cpp
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of trigger class
+ **/
+
+#include "theory/quantifiers/trigger.h"
+#include "theory/theory_engine.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/uf/theory_uf_instantiator.h"
+#include "theory/quantifiers/candidate_generator.h"
+#include "theory/uf/equality_engine.h"
+#include "theory/quantifiers/options.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::inst;
+
+//#define NESTED_PATTERN_SELECTION
+
+Trigger* Trigger::TrTrie::getTrigger2( std::vector< Node >& nodes ){
+  if( nodes.empty() ){
+    return d_tr;
+  }else{
+    Node n = nodes.back();
+    nodes.pop_back();
+    if( d_children.find( n )!=d_children.end() ){
+      return d_children[n]->getTrigger2( nodes );
+    }else{
+      return NULL;
+    }
+  }
+}
+void Trigger::TrTrie::addTrigger2( std::vector< Node >& nodes, Trigger* t ){
+  if( nodes.empty() ){
+    d_tr = t;
+  }else{
+    Node n = nodes.back();
+    nodes.pop_back();
+    if( d_children.find( n )==d_children.end() ){
+      d_children[n] = new TrTrie;
+    }
+    d_children[n]->addTrigger2( nodes, t );
+  }
+}
+
+/** trigger static members */
+std::map< TNode, std::vector< TNode > > Trigger::d_var_contains;
+Trigger::TrTrie Trigger::d_tr_trie;
+
+/** trigger class constructor */
+Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool smartTriggers ) :
+d_quantEngine( qe ), d_f( f ){
+  d_nodes.insert( d_nodes.begin(), nodes.begin(), nodes.end() );
+  if( smartTriggers ){
+    if( d_nodes.size()==1 ){
+      if( isSimpleTrigger( d_nodes[0] ) ){
+        d_mg = new InstMatchGeneratorSimple( f, d_nodes[0] );
+      }else{
+        d_mg = new InstMatchGenerator( d_nodes[0], qe, matchOption );
+      }
+    }else{
+      d_mg = new InstMatchGeneratorMulti( f, d_nodes, qe, matchOption );
+    }
+  }else{
+    d_mg = new InstMatchGenerator( d_nodes, qe, matchOption );
+  }
+  Debug("trigger") << "Trigger for " << f << ": " << std::endl;
+  for( int i=0; i<(int)d_nodes.size(); i++ ){
+    Debug("trigger") << "   " << d_nodes[i] << std::endl;
+  }
+  Debug("trigger") << std::endl;
+  if( d_nodes.size()==1 ){
+    if( isSimpleTrigger( d_nodes[0] ) ){
+      ++(qe->d_statistics.d_triggers);
+    }else{
+      ++(qe->d_statistics.d_simple_triggers);
+    }
+  }else{
+    Debug("multi-trigger") << "Multi-trigger " << (*this) << std::endl;
+    //Notice() << "Multi-trigger for " << f << " : " << std::endl;
+    //Notice() << "   " << (*this) << std::endl;
+    ++(qe->d_statistics.d_multi_triggers);
+  }
+  //Notice() << "Trigger : " << (*this) << "  for " << f << std::endl;
+  if( options::eagerInstQuant() ){
+    Theory* th_uf = qe->getTheoryEngine()->getTheory( theory::THEORY_UF );
+    uf::InstantiatorTheoryUf* ith = (uf::InstantiatorTheoryUf*)th_uf->getInstantiator();
+    for( int i=0; i<(int)d_nodes.size(); i++ ){
+      ith->registerTrigger( this, d_nodes[i].getOperator() );
+    }
+  }
+}
+void Trigger::computeVarContains( Node n ) {
+  if( d_var_contains.find( n )==d_var_contains.end() ){
+    d_var_contains[n].clear();
+    computeVarContains2( n, n );
+  }
+}
+
+void Trigger::computeVarContains2( Node n, Node parent ){
+  if( n.getKind()==INST_CONSTANT ){
+    if( std::find( d_var_contains[parent].begin(), d_var_contains[parent].end(), n )==d_var_contains[parent].end() ){
+      d_var_contains[parent].push_back( n );
+    }
+  }else{
+    for( int i=0; i<(int)n.getNumChildren(); i++ ){
+      computeVarContains2( n[i], parent );
+    }
+  }
+}
+
+void Trigger::resetInstantiationRound(){
+  d_mg->resetInstantiationRound( d_quantEngine );
+}
+
+void Trigger::reset( Node eqc ){
+  d_mg->reset( eqc, d_quantEngine );
+}
+
+bool Trigger::getNextMatch( InstMatch& m ){
+  bool retVal = d_mg->getNextMatch( m, d_quantEngine );
+  //m.makeInternal( d_quantEngine->getEqualityQuery() );
+  return retVal;
+}
+
+bool Trigger::getMatch( Node t, InstMatch& m ){
+  //FIXME: this assumes d_mg is an inst match generator
+  return ((InstMatchGenerator*)d_mg)->getMatch( t, m, d_quantEngine );
+}
+
+int Trigger::addTerm( Node t ){
+  return d_mg->addTerm( d_f, t, d_quantEngine );
+}
+
+int Trigger::addInstantiations( InstMatch& baseMatch ){
+  int addedLemmas = d_mg->addInstantiations( d_f, baseMatch, d_quantEngine );
+  if( addedLemmas>0 ){
+    Debug("inst-trigger") << "Added " << addedLemmas << " lemmas, trigger was ";
+    for( int i=0; i<(int)d_nodes.size(); i++ ){
+      Debug("inst-trigger") << d_nodes[i] << " ";
+    }
+    Debug("inst-trigger") << std::endl;
+  }
+  return addedLemmas;
+}
+
+Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool keepAll, int trOption,
+                             bool smartTriggers ){
+  std::vector< Node > trNodes;
+  if( !keepAll ){
+    //only take nodes that contribute variables to the trigger when added
+    std::vector< Node > temp;
+    temp.insert( temp.begin(), nodes.begin(), nodes.end() );
+    std::map< Node, bool > vars;
+    std::map< Node, std::vector< Node > > patterns;
+    for( int i=0; i<(int)temp.size(); i++ ){
+      bool foundVar = false;
+      computeVarContains( temp[i] );
+      for( int j=0; j<(int)d_var_contains[ temp[i] ].size(); j++ ){
+        Node v = d_var_contains[ temp[i] ][j];
+        if( v.getAttribute(InstConstantAttribute())==f ){
+          if( vars.find( v )==vars.end() ){
+            vars[ v ] = true;
+            foundVar = true;
+          }
+        }
+      }
+      if( foundVar ){
+        trNodes.push_back( temp[i] );
+        for( int j=0; j<(int)d_var_contains[ temp[i] ].size(); j++ ){
+          Node v = d_var_contains[ temp[i] ][j];
+          patterns[ v ].push_back( temp[i] );
+        }
+      }
+    }
+    //now, minimalize the trigger
+    for( int i=0; i<(int)trNodes.size(); i++ ){
+      bool keepPattern = false;
+      Node n = trNodes[i];
+      for( int j=0; j<(int)d_var_contains[ n ].size(); j++ ){
+        Node v = d_var_contains[ n ][j];
+        if( patterns[v].size()==1 ){
+          keepPattern = true;
+          break;
+        }
+      }
+      if( !keepPattern ){
+        //remove from pattern vector
+        for( int j=0; j<(int)d_var_contains[ n ].size(); j++ ){
+          Node v = d_var_contains[ n ][j];
+          for( int k=0; k<(int)patterns[v].size(); k++ ){
+            if( patterns[v][k]==n ){
+              patterns[v].erase( patterns[v].begin() + k, patterns[v].begin() + k + 1 );
+              break;
+            }
+          }
+        }
+        //remove from trigger nodes
+        trNodes.erase( trNodes.begin() + i, trNodes.begin() + i + 1 );
+        i--;
+      }
+    }
+  }else{
+    trNodes.insert( trNodes.begin(), nodes.begin(), nodes.end() );
+  }
+
+  //check for duplicate?
+  if( trOption==TR_MAKE_NEW ){
+    //static int trNew = 0;
+    //static int trOld = 0;
+    //Trigger* t = d_tr_trie.getTrigger( trNodes );
+    //if( t ){
+    //  trOld++;
+    //}else{
+    //  trNew++;
+    //}
+    //if( (trNew+trOld)%100==0 ){
+    //  Notice() << "Trigger new old = " << trNew << " " << trOld << std::endl;
+    //}
+  }else{
+    Trigger* t = d_tr_trie.getTrigger( trNodes );
+    if( t ){
+      if( trOption==TR_GET_OLD ){
+        //just return old trigger
+        return t;
+      }else{
+        return NULL;
+      }
+    }
+  }
+  Trigger* t = new Trigger( qe, f, trNodes, matchOption, smartTriggers );
+  d_tr_trie.addTrigger( trNodes, t );
+  return t;
+}
+Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, Node n, int matchOption, bool keepAll, int trOption, bool smartTriggers ){
+  std::vector< Node > nodes;
+  nodes.push_back( n );
+  return mkTrigger( qe, f, nodes, matchOption, keepAll, trOption, smartTriggers );
+}
+
+bool Trigger::isUsableTrigger( std::vector< Node >& nodes, Node f ){
+  for( int i=0; i<(int)nodes.size(); i++ ){
+    if( !isUsableTrigger( nodes[i], f ) ){
+      return false;
+    }
+  }
+  return true;
+}
+
+bool Trigger::isUsable( Node n, Node f ){
+  if( n.getAttribute(InstConstantAttribute())==f ){
+    if( !isAtomicTrigger( n ) && n.getKind()!=INST_CONSTANT ){
+      std::map< Node, Node > coeffs;
+      return getPatternArithmetic( f, n, coeffs );
+    }else{
+      for( int i=0; i<(int)n.getNumChildren(); i++ ){
+        if( !isUsable( n[i], f ) ){
+          return false;
+        }
+      }
+      return true;
+    }
+  }else{
+    return true;
+  }
+}
+
+bool Trigger::isUsableTrigger( Node n, Node f ){
+  //return n.getAttribute(InstConstantAttribute())==f && n.getKind()==APPLY_UF;
+  return n.getAttribute(InstConstantAttribute())==f && isAtomicTrigger( n ) && isUsable( n, f );
+}
+
+bool Trigger::isAtomicTrigger( Node n ){
+  return n.getKind()==APPLY_UF || n.getKind()==SELECT || n.getKind()==STORE ||
+         n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR || n.getKind()==APPLY_TESTER;
+}
+bool Trigger::isSimpleTrigger( Node n ){
+  if( isAtomicTrigger( n ) ){
+    for( int i=0; i<(int)n.getNumChildren(); i++ ){
+      if( n[i].getKind()!=INST_CONSTANT && n[i].hasAttribute(InstConstantAttribute()) ){
+        return false;
+      }
+    }
+    return true;
+  }else{
+    return false;
+  }
+}
+
+/** filter all nodes that have instances */
+void Trigger::filterInstances( std::vector< Node >& nodes ){
+  std::vector< bool > active;
+  active.resize( nodes.size(), true );
+  for( int i=0; i<(int)nodes.size(); i++ ){
+    for( int j=i+1; j<(int)nodes.size(); j++ ){
+      if( active[i] && active[j] ){
+        int result = isInstanceOf( nodes[i], nodes[j] );
+        if( result==1 ){
+          active[j] = false;
+        }else if( result==-1 ){
+          active[i] = false;
+        }
+      }
+    }
+  }
+  std::vector< Node > temp;
+  for( int i=0; i<(int)nodes.size(); i++ ){
+    if( active[i] ){
+      temp.push_back( nodes[i] );
+    }
+  }
+  nodes.clear();
+  nodes.insert( nodes.begin(), temp.begin(), temp.end() );
+}
+
+
+bool Trigger::collectPatTerms2( QuantifiersEngine* qe, Node f, Node n, std::map< Node, bool >& patMap, int tstrt ){
+  if( patMap.find( n )==patMap.end() ){
+    patMap[ n ] = false;
+    if( tstrt==TS_MIN_TRIGGER ){
+      if( n.getKind()==FORALL ){
+#ifdef NESTED_PATTERN_SELECTION
+        //return collectPatTerms2( qe, f, qe->getOrCreateCounterexampleBody( n ), patMap, tstrt );
+        return collectPatTerms2( qe, f, qe->getBoundBody( n ), patMap, tstrt );
+#else
+        return false;
+#endif
+      }else{
+        bool retVal = false;
+        for( int i=0; i<(int)n.getNumChildren(); i++ ){
+          if( collectPatTerms2( qe, f, n[i], patMap, tstrt ) ){
+            retVal = true;
+          }
+        }
+        if( retVal ){
+          return true;
+        }else if( isUsableTrigger( n, f ) ){
+          patMap[ n ] = true;
+          return true;
+        }else{
+          return false;
+        }
+      }
+    }else{
+      bool retVal = false;
+      if( isUsableTrigger( n, f ) ){
+        patMap[ n ] = true;
+        if( tstrt==TS_MAX_TRIGGER ){
+          return true;
+        }else{
+          retVal = true;
+        }
+      }
+      if( n.getKind()==FORALL ){
+#ifdef NESTED_PATTERN_SELECTION
+        //if( collectPatTerms2( qe, f, qe->getOrCreateCounterexampleBody( n ), patMap, tstrt ) ){
+        //  retVal = true;
+        //}
+        if( collectPatTerms2( qe, f, qe->getBoundBody( n ), patMap, tstrt ) ){
+          retVal = true;
+        }
+#endif
+      }else{
+        for( int i=0; i<(int)n.getNumChildren(); i++ ){
+          if( collectPatTerms2( qe, f, n[i], patMap, tstrt ) ){
+            retVal = true;
+          }
+        }
+      }
+      return retVal;
+    }
+  }else{
+    return patMap[ n ];
+  }
+}
+
+void Trigger::collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, bool filterInst ){
+  std::map< Node, bool > patMap;
+  if( filterInst ){
+    //immediately do not consider any term t for which another term is an instance of t
+    std::vector< Node > patTerms2;
+    collectPatTerms( qe, f, n, patTerms2, TS_ALL, false );
+    std::vector< Node > temp;
+    temp.insert( temp.begin(), patTerms2.begin(), patTerms2.end() );
+    filterInstances( temp );
+    if( temp.size()!=patTerms2.size() ){
+      Debug("trigger-filter-instance") << "Filtered an instance: " << std::endl;
+      Debug("trigger-filter-instance") << "Old: ";
+      for( int i=0; i<(int)patTerms2.size(); i++ ){
+        Debug("trigger-filter-instance") << patTerms2[i] << " ";
+      }
+      Debug("trigger-filter-instance") << std::endl << "New: ";
+      for( int i=0; i<(int)temp.size(); i++ ){
+        Debug("trigger-filter-instance") << temp[i] << " ";
+      }
+      Debug("trigger-filter-instance") << std::endl;
+    }
+    if( tstrt==TS_ALL ){
+      patTerms.insert( patTerms.begin(), temp.begin(), temp.end() );
+      return;
+    }else{
+      //do not consider terms that have instances
+      for( int i=0; i<(int)patTerms2.size(); i++ ){
+        if( std::find( temp.begin(), temp.end(), patTerms2[i] )==temp.end() ){
+          patMap[ patTerms2[i] ] = false;
+        }
+      }
+    }
+  }
+  collectPatTerms2( qe, f, n, patMap, tstrt );
+  for( std::map< Node, bool >::iterator it = patMap.begin(); it != patMap.end(); ++it ){
+    if( it->second ){
+      patTerms.push_back( it->first );
+    }
+  }
+}
+
+/** is n1 an instance of n2 or vice versa? */
+int Trigger::isInstanceOf( Node n1, Node n2 ){
+  if( n1==n2 ){
+    return 1;
+  }else if( n1.getKind()==n2.getKind() ){
+    if( n1.getKind()==APPLY_UF ){
+      if( n1.getOperator()==n2.getOperator() ){
+        int result = 0;
+        for( int i=0; i<(int)n1.getNumChildren(); i++ ){
+          if( n1[i]!=n2[i] ){
+            int cResult = isInstanceOf( n1[i], n2[i] );
+            if( cResult==0 ){
+              return 0;
+            }else if( cResult!=result ){
+              if( result!=0 ){
+                return 0;
+              }else{
+                result = cResult;
+              }
+            }
+          }
+        }
+        return result;
+      }
+    }
+    return 0;
+  }else if( n2.getKind()==INST_CONSTANT ){
+    computeVarContains( n1 );
+    //if( std::find( d_var_contains[ n1 ].begin(), d_var_contains[ n1 ].end(), n2 )!=d_var_contains[ n1 ].end() ){
+    //  return 1;
+    //}
+    if( d_var_contains[ n1 ].size()==1 && d_var_contains[ n1 ][ 0 ]==n2 ){
+      return 1;
+    }
+  }else if( n1.getKind()==INST_CONSTANT ){
+    computeVarContains( n2 );
+    //if( std::find( d_var_contains[ n2 ].begin(), d_var_contains[ n2 ].end(), n1 )!=d_var_contains[ n2 ].end() ){
+    //  return -1;
+    //}
+    if( d_var_contains[ n2 ].size()==1 && d_var_contains[ n2 ][ 0 ]==n1 ){
+      return 1;
+    }
+  }
+  return 0;
+}
+
+bool Trigger::isVariableSubsume( Node n1, Node n2 ){
+  if( n1==n2 ){
+    return true;
+  }else{
+    //Notice() << "is variable subsume ? " << n1 << " " << n2 << std::endl;
+    computeVarContains( n1 );
+    computeVarContains( n2 );
+    for( int i=0; i<(int)d_var_contains[n2].size(); i++ ){
+      if( std::find( d_var_contains[n1].begin(), d_var_contains[n1].end(), d_var_contains[n2][i] )==d_var_contains[n1].end() ){
+        //Notice() << "no" << std::endl;
+        return false;
+      }
+    }
+    //Notice() << "yes" << std::endl;
+    return true;
+  }
+}
+
+void Trigger::getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains ){
+  for( int i=0; i<(int)pats.size(); i++ ){
+    computeVarContains( pats[i] );
+    varContains[ pats[i] ].clear();
+    for( int j=0; j<(int)d_var_contains[pats[i]].size(); j++ ){
+      if( d_var_contains[pats[i]][j].getAttribute(InstConstantAttribute())==f ){
+        varContains[ pats[i] ].push_back( d_var_contains[pats[i]][j] );
+      }
+    }
+  }
+}
+
+void Trigger::getVarContainsNode( Node f, Node n, std::vector< Node >& varContains ){
+  computeVarContains( n );
+  for( int j=0; j<(int)d_var_contains[n].size(); j++ ){
+    if( d_var_contains[n][j].getAttribute(InstConstantAttribute())==f ){
+      varContains.push_back( d_var_contains[n][j] );
+    }
+  }
+}
+
+bool Trigger::getPatternArithmetic( Node f, Node n, std::map< Node, Node >& coeffs ){
+  if( n.getKind()==PLUS ){
+    Assert( coeffs.empty() );
+    NodeBuilder<> t(kind::PLUS);
+    for( int i=0; i<(int)n.getNumChildren(); i++ ){
+      if( n[i].hasAttribute(InstConstantAttribute()) ){
+        if( n[i].getKind()==INST_CONSTANT ){
+          if( n[i].getAttribute(InstConstantAttribute())==f ){
+            coeffs[ n[i] ] = Node::null();
+          }else{
+            coeffs.clear();
+            return false;
+          }
+        }else if( !getPatternArithmetic( f, n[i], coeffs ) ){
+          coeffs.clear();
+          return false;
+        }
+      }else{
+        t << n[i];
+      }
+    }
+    if( t.getNumChildren()==0 ){
+      coeffs[ Node::null() ] = NodeManager::currentNM()->mkConst( Rational(0) );
+    }else if( t.getNumChildren()==1 ){
+      coeffs[ Node::null() ]  = t.getChild( 0 );
+    }else{
+      coeffs[ Node::null() ]  = t;
+    }
+    return true;
+  }else if( n.getKind()==MULT ){
+    if( n[0].getKind()==INST_CONSTANT && n[0].getAttribute(InstConstantAttribute())==f ){
+      Assert( !n[1].hasAttribute(InstConstantAttribute()) );
+      coeffs[ n[0] ] = n[1];
+      return true;
+    }else if( n[1].getKind()==INST_CONSTANT && n[1].getAttribute(InstConstantAttribute())==f ){
+      Assert( !n[0].hasAttribute(InstConstantAttribute()) );
+      coeffs[ n[1] ] = n[0];
+      return true;
+    }
+  }
+  return false;
+}
diff --git a/src/theory/quantifiers/trigger.h b/src/theory/quantifiers/trigger.h
new file mode 100644 (file)
index 0000000..207cef5
--- /dev/null
@@ -0,0 +1,171 @@
+/*********************                                                        */
+/*! \file trigger.h
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief trigger class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__QUANTIFIERS__TRIGGER_H
+#define __CVC4__THEORY__QUANTIFIERS__TRIGGER_H
+
+#include "theory/quantifiers/inst_match.h"
+
+namespace CVC4 {
+namespace theory {
+namespace inst {
+
+//a collect of nodes representing a trigger
+class Trigger {
+private:
+  /** computation of variable contains */
+  static std::map< TNode, std::vector< TNode > > d_var_contains;
+  static void computeVarContains( Node n );
+  static void computeVarContains2( Node n, Node parent );
+private:
+  /** the quantifiers engine */
+  QuantifiersEngine* d_quantEngine;
+  /** the quantifier this trigger is for */
+  Node d_f;
+  /** match generators */
+  IMGenerator* d_mg;
+private:
+  /** a trie of triggers */
+  class TrTrie {
+  private:
+    Trigger* getTrigger2( std::vector< Node >& nodes );
+    void addTrigger2( std::vector< Node >& nodes, Trigger* t );
+  public:
+    TrTrie() : d_tr( NULL ){}
+    Trigger* d_tr;
+    std::map< TNode, TrTrie* > d_children;
+    Trigger* getTrigger( std::vector< Node >& nodes ){
+      std::vector< Node > temp;
+      temp.insert( temp.begin(), nodes.begin(), nodes.end() );
+      std::sort( temp.begin(), temp.end() );
+      return getTrigger2( temp );
+    }
+    void addTrigger( std::vector< Node >& nodes, Trigger* t ){
+      std::vector< Node > temp;
+      temp.insert( temp.begin(), nodes.begin(), nodes.end() );
+      std::sort( temp.begin(), temp.end() );
+      return addTrigger2( temp, t );
+    }
+  };/* class Trigger::TrTrie */
+  /** all triggers will be stored in this trie */
+  static TrTrie d_tr_trie;
+private:
+  /** trigger constructor */
+  Trigger( QuantifiersEngine* ie, Node f, std::vector< Node >& nodes, int matchOption = 0, bool smartTriggers = false );
+public:
+  ~Trigger(){}
+public:
+  std::vector< Node > d_nodes;
+public:
+  void debugPrint( const char* c );
+  IMGenerator* getGenerator() { return d_mg; }
+public:
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  void resetInstantiationRound();
+  /** reset, eqc is the equivalence class to search in (search in any if eqc=null) */
+  void reset( Node eqc );
+  /** get next match.  must call reset( eqc ) once before this function. */
+  bool getNextMatch( InstMatch& m );
+  /** get the match against ground term or formula t.
+      the trigger and t should have the same shape.
+      Currently the trigger should not be a multi-trigger.
+  */
+  bool getMatch( Node t, InstMatch& m);
+  /** add ground term t, called when t is added to the TermDb */
+  int addTerm( Node t );
+  /** return true if whatever Node is subsituted for the variables the
+      given Node can't match the pattern */
+  bool nonunifiable( TNode t, const std::vector<Node> & vars){
+    return d_mg->nonunifiable(t,vars);
+  }
+  /** return whether this is a multi-trigger */
+  bool isMultiTrigger() { return d_nodes.size()>1; }
+public:
+  /** add all available instantiations exhaustively, in any equivalence class
+      if limitInst>0, limitInst is the max # of instantiations to try */
+  int addInstantiations( InstMatch& baseMatch );
+  /** mkTrigger method
+     ie     : quantifier engine;
+     f      : forall something ....
+     nodes  : (multi-)trigger
+     matchOption : which policy to use for creating matches (one of InstMatchGenerator::MATCH_GEN_* )
+     keepAll: don't remove unneeded patterns;
+     trOption : policy for dealing with triggers that already existed (see below)
+  */
+  enum{
+    TR_MAKE_NEW,    //make new trigger even if it already may exist
+    TR_GET_OLD,     //return a previous trigger if it had already been created
+    TR_RETURN_NULL  //return null if a duplicate is found
+  };
+  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes,
+                             int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
+                             bool smartTriggers = false );
+  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, Node n,
+                             int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
+                             bool smartTriggers = false );
+private:
+  /** is subterm of trigger usable */
+  static bool isUsable( Node n, Node f );
+  /** collect all APPLY_UF pattern terms for f in n */
+  static bool collectPatTerms2( QuantifiersEngine* qe, Node f, Node n, std::map< Node, bool >& patMap, int tstrt );
+public:
+  //different strategies for choosing trigger terms
+  enum {
+    TS_MAX_TRIGGER = 0,
+    TS_MIN_TRIGGER,
+    TS_ALL,
+  };
+  static void collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, bool filterInst = false );
+public:
+  /** is usable trigger */
+  static bool isUsableTrigger( std::vector< Node >& nodes, Node f );
+  static bool isUsableTrigger( Node n, Node f );
+  static bool isAtomicTrigger( Node n );
+  static bool isSimpleTrigger( Node n );
+  /** filter all nodes that have instances */
+  static void filterInstances( std::vector< Node >& nodes );
+  /** -1: n1 is an instance of n2, 1: n1 is an instance of n2 */
+  static int isInstanceOf( Node n1, Node n2 );
+  /** variables subsume, return true if n1 contains all free variables in n2 */
+  static bool isVariableSubsume( Node n1, Node n2 );
+  /** get var contains */
+  static void getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains );
+  static void getVarContainsNode( Node f, Node n, std::vector< Node >& varContains );
+  /** get pattern arithmetic */
+  static bool getPatternArithmetic( Node f, Node n, std::map< Node, Node >& coeffs );
+
+  inline void toStream(std::ostream& out) const {
+    out << "TRIGGER( ";
+    for( int i=0; i<(int)d_nodes.size(); i++ ){
+      if( i>0 ){ out << ", "; }
+      out << d_nodes[i];
+    }
+    out << " )";
+  }
+};
+
+inline std::ostream& operator<<(std::ostream& out, const Trigger & tr) {
+  tr.toStream(out);
+  return out;
+}
+
+}/* CVC4::theory::inst namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__QUANTIFIERS__TRIGGER_H */
index 4d94d8d83436d02d9fb18811f67e1b816877dbe3..df08312b1b719aa2c09e4616c3825566e3b222a1 100644 (file)
@@ -27,7 +27,7 @@
 #include "theory/quantifiers/instantiation_engine.h"
 #include "theory/quantifiers/first_order_model.h"
 #include "theory/quantifiers/term_database.h"
-#include "theory/rr_candidate_generator.h"
+#include "theory/rewriterules/rr_candidate_generator.h"
 
 using namespace std;
 using namespace CVC4;
@@ -793,4 +793,4 @@ rrinst::CandidateGenerator* QuantifiersEngine::getRRCanGenClass(TypeNode t) {
   // if(eq == NULL) return getInstantiator(id)->getRRCanGenClass();
   // else return eq;
   return getRRCanGenClass();
-}
\ No newline at end of file
+}
index 2ae620e3d29e36acf4c812e6efd730f752e6116e..5afc34bf6bd4afc3d4a1d89a86d8ec7b6cc71cc4 100644 (file)
@@ -21,8 +21,8 @@
 
 #include "theory/theory.h"
 #include "util/hash.h"
-#include "theory/inst_match.h"
-#include "theory/rr_inst_match.h"
+#include "theory/quantifiers/inst_match.h"
+#include "theory/rewriterules/rr_inst_match.h"
 
 #include "util/stats.h"
 
index 46cffda113f228709f159ac0959d360846b487a9..a9eddb81229a029773def2faf2665a7f4026cc0c 100644 (file)
@@ -13,7 +13,14 @@ librewriterules_la_SOURCES = \
        theory_rewriterules_rewriter.h \
        theory_rewriterules_type_rules.h \
        theory_rewriterules_preprocess.h \
-       theory_rewriterules_params.h
+       theory_rewriterules_params.h \
+       rr_inst_match.h \
+       rr_inst_match_impl.h \
+       rr_inst_match.cpp \
+       rr_trigger.h \
+       rr_trigger.cpp \
+       rr_candidate_generator.h \
+       rr_candidate_generator.cpp
 
 EXTRA_DIST = \
        kinds
diff --git a/src/theory/rewriterules/rr_candidate_generator.cpp b/src/theory/rewriterules/rr_candidate_generator.cpp
new file mode 100644 (file)
index 0000000..f01497b
--- /dev/null
@@ -0,0 +1,125 @@
+/*********************                                                        */
+/*! \file rr_candidate_generator.cpp
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: bobot
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of rr candidate generator class
+ **/
+
+#include "theory/rewriterules/rr_candidate_generator.h"
+#include "theory/theory_engine.h"
+#include "theory/uf/theory_uf.h"
+#include "theory/quantifiers/term_database.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::rrinst;
+
+GenericCandidateGeneratorClasses::GenericCandidateGeneratorClasses(QuantifiersEngine * qe){
+  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
+    if(qe->getInstantiator(i) != NULL)
+      d_can_gen[i] = qe->getInstantiator(i)->getRRCanGenClasses();
+    else d_can_gen[i] = NULL;
+  }
+}
+
+GenericCandidateGeneratorClasses::~GenericCandidateGeneratorClasses(){
+  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
+    delete(d_can_gen[i]);
+  }
+}
+
+void GenericCandidateGeneratorClasses::resetInstantiationRound(){
+  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
+    if(d_can_gen[i] != NULL) d_can_gen[i]->resetInstantiationRound();
+  }
+  d_can_gen_id=THEORY_FIRST;
+}
+
+void GenericCandidateGeneratorClasses::reset(TNode eqc){
+  Assert(eqc.isNull());
+  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
+    if(d_can_gen[i] != NULL) d_can_gen[i]->reset(eqc);
+  }
+  d_can_gen_id=THEORY_FIRST;
+  lookForNextTheory();
+}
+
+TNode GenericCandidateGeneratorClasses::getNextCandidate(){
+  Assert(THEORY_FIRST <= d_can_gen_id && d_can_gen_id <= THEORY_LAST);
+  /** No more */
+  if(d_can_gen_id == THEORY_LAST) return TNode::null();
+  /** Try with this theory */
+  TNode cand = d_can_gen[d_can_gen_id]->getNextCandidate();
+  if( !cand.isNull() ) return cand;
+  lookForNextTheory();
+  return getNextCandidate();
+}
+
+void GenericCandidateGeneratorClasses::lookForNextTheory(){
+  do{ /* look for the next available generator */
+    ++d_can_gen_id;
+  } while( d_can_gen_id < THEORY_LAST && d_can_gen[d_can_gen_id] == NULL);
+}
+
+GenericCandidateGeneratorClass::GenericCandidateGeneratorClass(QuantifiersEngine * qe): d_qe(qe) {
+  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
+    if(d_qe->getInstantiator(i) != NULL)
+      d_can_gen[i] = d_qe->getInstantiator(i)->getRRCanGenClass();
+    else d_can_gen[i] = NULL;
+  }
+}
+
+GenericCandidateGeneratorClass::~GenericCandidateGeneratorClass(){
+  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
+    delete(d_can_gen[i]);
+  }
+}
+
+void GenericCandidateGeneratorClass::resetInstantiationRound(){
+  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
+    if(d_can_gen[i] != NULL) d_can_gen[i]->resetInstantiationRound();
+  }
+  d_can_gen_id=THEORY_FIRST;
+}
+
+void GenericCandidateGeneratorClass::reset(TNode eqc){
+  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
+    if(d_can_gen[i] != NULL) d_can_gen[i]->reset(eqc);
+  }
+  d_can_gen_id=THEORY_FIRST;
+  d_node = eqc;
+  lookForNextTheory();
+}
+
+TNode GenericCandidateGeneratorClass::getNextCandidate(){
+  Assert(THEORY_FIRST <= d_can_gen_id && d_can_gen_id <= THEORY_LAST);
+  /** No more */
+  if(d_can_gen_id == THEORY_LAST) return TNode::null();
+  /** Try with this theory */
+  TNode cand = d_can_gen[d_can_gen_id]->getNextCandidate();
+  if( !cand.isNull() ) return cand;
+  lookForNextTheory();
+  return getNextCandidate();
+}
+
+void GenericCandidateGeneratorClass::lookForNextTheory(){
+  do{ /* look for the next available generator, where the element is */
+    ++d_can_gen_id;
+  } while(
+          d_can_gen_id < THEORY_LAST &&
+          (d_can_gen[d_can_gen_id] == NULL ||
+           !d_qe->getInstantiator( d_can_gen_id )->hasTerm( d_node ))
+          );
+}
diff --git a/src/theory/rewriterules/rr_candidate_generator.h b/src/theory/rewriterules/rr_candidate_generator.h
new file mode 100644 (file)
index 0000000..560504f
--- /dev/null
@@ -0,0 +1,209 @@
+/*********************                                                        */
+/*! \file rr_candidate_generator.h
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: bobot
+ ** Minor contributors (to current version): mdeters
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief rr candidate generator
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__REWRITERULES__RR_CANDIDATE_GENERATOR_H
+#define __CVC4__THEORY__REWRITERULES__RR_CANDIDATE_GENERATOR_H
+
+#include "theory/quantifiers_engine.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/rewriterules/rr_inst_match.h"
+
+using namespace CVC4::theory::quantifiers;
+
+namespace CVC4 {
+namespace theory {
+namespace eq {
+
+namespace rrinst{
+typedef CVC4::theory::rrinst::CandidateGenerator CandidateGenerator;
+
+//New CandidateGenerator. They have a simpler semantic than the old one
+
+// Just iterate amoung the equivalence classes
+// node::Null() must be given to reset
+class CandidateGeneratorTheoryEeClasses : public CandidateGenerator{
+private:
+  //the equality classes iterator
+  eq::EqClassesIterator d_eq;
+  //equalityengine pointer
+  EqualityEngine* d_ee;
+public:
+  CandidateGeneratorTheoryEeClasses( EqualityEngine * ee): d_ee( ee ){}
+  ~CandidateGeneratorTheoryEeClasses(){}
+  void resetInstantiationRound(){};
+  void reset( TNode eqc ){
+    Assert(eqc.isNull());
+    d_eq = eq::EqClassesIterator( d_ee );
+  }; //* the argument is not used
+  TNode getNextCandidate(){
+    if( !d_eq.isFinished() ) return (*(d_eq++));
+    else return Node::null();
+  };
+};
+
+// Just iterate amoung the equivalence class of the given node
+// node::Null() *can't* be given to reset
+class CandidateGeneratorTheoryEeClass : public CandidateGenerator{
+private:
+  //instantiator pointer
+  EqualityEngine* d_ee;
+  //the equality class iterator
+  eq::EqClassIterator d_eqc;
+  /* For the case where the given term doesn't exists in uf */
+  Node d_retNode;
+public:
+  CandidateGeneratorTheoryEeClass( EqualityEngine* ee): d_ee( ee ){}
+  ~CandidateGeneratorTheoryEeClass(){}
+  void resetInstantiationRound(){};
+  void reset( TNode eqc ){
+    Assert(!eqc.isNull());
+    if( d_ee->hasTerm( eqc ) ){
+      /* eqc is in uf  */
+      eqc = d_ee->getRepresentative( eqc );
+      d_eqc = eq::EqClassIterator( eqc, d_ee );
+      d_retNode = Node::null();
+    }else{
+      /* If eqc if not a term known by uf, it is the only one in its
+         equivalence class. So we will return only it */
+      d_retNode = eqc;
+      d_eqc = eq::EqClassIterator();
+    }
+  }; //* the argument is not used
+  TNode getNextCandidate(){
+    if(d_retNode.isNull()){
+      if( !d_eqc.isFinished() ) return (*(d_eqc++));
+      else return Node::null();
+    }else{
+      /* the case where eqc not in uf */
+      Node ret = d_retNode;
+      d_retNode = Node::null(); /* d_eqc.isFinished() must be true */
+      return ret;
+    }
+  };
+};
+
+
+} /* namespace rrinst */
+} /* namespace eq */
+
+namespace uf{
+namespace rrinst {
+
+typedef CVC4::theory::rrinst::CandidateGenerator CandidateGenerator;
+
+class CandidateGeneratorTheoryUfOp : public CandidateGenerator{
+private:
+  Node d_op;
+  //instantiator pointer
+  TermDb* d_tdb;
+  // Since new term can appears we restrict ourself to the one that
+  // exists at resetInstantiationRound
+  size_t d_term_iter_limit;
+  size_t d_term_iter;
+public:
+  CandidateGeneratorTheoryUfOp(Node op, TermDb* tdb): d_op(op), d_tdb( tdb ){}
+  ~CandidateGeneratorTheoryUfOp(){}
+  void resetInstantiationRound(){
+    d_term_iter_limit = d_tdb->d_op_map[d_op].size();
+  };
+  void reset( TNode eqc ){
+    Assert(eqc.isNull());
+    d_term_iter = 0;
+  }; //* the argument is not used
+  TNode getNextCandidate(){
+    if( d_term_iter<d_term_iter_limit ){
+      TNode n = d_tdb->d_op_map[d_op][d_term_iter];
+      ++d_term_iter;
+      return n;
+    } else return Node::null();
+  };
+};
+
+class CandidateGeneratorTheoryUfType : public CandidateGenerator{
+private:
+  TypeNode d_type;
+  //instantiator pointer
+  TermDb* d_tdb;
+  // Since new term can appears we restrict ourself to the one that
+  // exists at resetInstantiationRound
+  size_t d_term_iter_limit;
+  size_t d_term_iter;
+public:
+  CandidateGeneratorTheoryUfType(TypeNode type, TermDb* tdb): d_type(type), d_tdb( tdb ){}
+  ~CandidateGeneratorTheoryUfType(){}
+  void resetInstantiationRound(){
+    d_term_iter_limit = d_tdb->d_type_map[d_type].size();
+  };
+  void reset( TNode eqc ){
+    Assert(eqc.isNull());
+    d_term_iter = 0;
+  }; //* the argument is not used
+  TNode getNextCandidate(){
+    if( d_term_iter<d_term_iter_limit ){
+      TNode n = d_tdb->d_type_map[d_type][d_term_iter];
+      ++d_term_iter;
+      return n;
+    } else return Node::null();
+  };
+};
+
+} /* namespace rrinst */
+} /* namespace uf */
+
+class GenericCandidateGeneratorClasses: public rrinst::CandidateGenerator{
+
+  /** The candidate generators */
+  rrinst::CandidateGenerator* d_can_gen[theory::THEORY_LAST];
+  /** The current theory which candidategenerator is used */
+  TheoryId d_can_gen_id;
+
+public:
+  GenericCandidateGeneratorClasses(QuantifiersEngine * qe);
+  ~GenericCandidateGeneratorClasses();
+
+  void resetInstantiationRound();
+  void reset(TNode eqc);
+  TNode getNextCandidate();
+  void lookForNextTheory();
+};
+
+class GenericCandidateGeneratorClass: public rrinst::CandidateGenerator{
+
+  /** The candidate generators */
+  rrinst::CandidateGenerator* d_can_gen[theory::THEORY_LAST];
+  /** The current theory which candidategenerator is used */
+  TheoryId d_can_gen_id;
+  /** current node to look for equivalence class */
+  Node d_node;
+  /** QuantifierEngine */
+  QuantifiersEngine* d_qe;
+
+public:
+  GenericCandidateGeneratorClass(QuantifiersEngine * qe);
+  ~GenericCandidateGeneratorClass();
+  void resetInstantiationRound();
+
+  void reset(TNode eqc);
+  TNode getNextCandidate();
+  void lookForNextTheory();
+};
+
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__REWRITERULES__RR_CANDIDATE_GENERATOR_H */
diff --git a/src/theory/rewriterules/rr_inst_match.cpp b/src/theory/rewriterules/rr_inst_match.cpp
new file mode 100644 (file)
index 0000000..25b184f
--- /dev/null
@@ -0,0 +1,1447 @@
+/*********************                                                        */
+/*! \file rr_inst_match.cpp
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: bobot
+ ** Minor contributors (to current version): mdeters
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of inst match class
+ **/
+
+#include "theory/quantifiers/inst_match.h"
+#include "theory/theory_engine.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/uf/theory_uf_instantiator.h"
+#include "theory/uf/equality_engine.h"
+#include "theory/arrays/theory_arrays.h"
+#include "theory/datatypes/theory_datatypes.h"
+#include "theory/rewriterules/rr_inst_match.h"
+#include "theory/rewriterules/rr_trigger.h"
+#include "theory/rewriterules/rr_inst_match_impl.h"
+#include "theory/rewriterules/rr_candidate_generator.h"
+
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::rrinst;
+using namespace CVC4::theory::uf::rrinst;
+using namespace CVC4::theory::eq::rrinst;
+
+namespace CVC4{
+namespace theory{
+namespace rrinst{
+
+typedef CVC4::theory::inst::InstMatch InstMatch;
+typedef CVC4::theory::inst::CandidateGeneratorQueue CandidateGeneratorQueue;
+
+template<bool modEq>
+class InstMatchTrie2Pairs
+{
+  typename std::vector< std::vector < typename InstMatchTrie2Gen<modEq>::Tree > > d_data;
+  InstMatchTrie2Gen<modEq> d_backtrack;
+public:
+  InstMatchTrie2Pairs(context::Context* c,  QuantifiersEngine* q, size_t n):
+  d_backtrack(c,q) {
+    // resize to a triangle
+    //
+    // |     *
+    // |   * *
+    // | * * *
+    // | -----> i
+    d_data.resize(n);
+    for(size_t i=0; i < n; ++i){
+      d_data[i].resize(i+1,typename InstMatchTrie2Gen<modEq>::Tree(0));
+    }
+  };
+  InstMatchTrie2Pairs(const InstMatchTrie2Pairs &) CVC4_UNDEFINED;
+  const InstMatchTrie2Pairs & operator =(const InstMatchTrie2Pairs & e) CVC4_UNDEFINED;
+  /** add match m in the trie,
+      return true if it was never seen */
+  inline bool addInstMatch( size_t i, size_t j, InstMatch& m){
+    size_t k = std::min(i,j);
+    size_t l = std::max(i,j);
+    return d_backtrack.addInstMatch(m,&(d_data[l][k]));
+  };
+  inline bool addInstMatch( size_t i, InstMatch& m){
+    return d_backtrack.addInstMatch(m,&(d_data[i][i]));
+  };
+
+};
+
+
+// Currently the implementation doesn't take into account that
+// variable should have the same value given.
+// TODO use the d_children way perhaps
+// TODO replace by a real dictionnary
+// We should create a real substitution? slower more precise
+// We don't do that often
+bool nonunifiable( TNode t0, TNode pat, const std::vector<Node> & vars){
+  if(pat.isNull()) return true;
+
+  typedef std::vector<std::pair<TNode,TNode> > tstack;
+  tstack stack(1,std::make_pair(t0,pat)); // t * pat
+
+  while(!stack.empty()){
+    const std::pair<TNode,TNode> p = stack.back(); stack.pop_back();
+    const TNode & t = p.first;
+    const TNode & pat = p.second;
+
+    // t or pat is a variable currently we consider that can match anything
+    if( find(vars.begin(),vars.end(),t) != vars.end() ) continue;
+    if( pat.getKind() == INST_CONSTANT ) continue;
+
+    // t and pat are nonunifiable
+    if( !Trigger::isAtomicTrigger( t ) || !Trigger::isAtomicTrigger( pat ) ) {
+      if(t == pat) continue;
+      else return true;
+    };
+    if( t.getOperator() != pat.getOperator() ) return true;
+
+    //put the children on the stack
+    for( size_t i=0; i < pat.getNumChildren(); i++ ){
+      stack.push_back(std::make_pair(t[i],pat[i]));
+    };
+  }
+  // The heuristic can't find non-unifiability
+  return false;
+};
+
+/** New things */
+class DumbMatcher: public Matcher{
+  void resetInstantiationRound( QuantifiersEngine* qe ){};
+  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe ){
+    return false;
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return false;
+  }
+};
+
+class DumbPatMatcher: public PatMatcher{
+  void resetInstantiationRound( QuantifiersEngine* qe ){};
+  bool reset( InstMatch& m, QuantifiersEngine* qe ){
+    return false;
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return false;
+  }
+};
+
+
+/* The order of the matching is:
+   reset arg1, nextMatch arg1, reset arg2, nextMatch arg2, ... */
+ApplyMatcher::ApplyMatcher( Node pat, QuantifiersEngine* qe): d_pattern(pat){
+  //  Assert( pat.hasAttribute(InstConstantAttribute()) );
+
+  //set-up d_variables, d_constants, d_childrens
+  for( size_t i=0; i< d_pattern.getNumChildren(); ++i ){
+    EqualityQuery* q = qe->getEqualityQuery(d_pattern[i].getType());
+    Assert( q != NULL );
+    if( d_pattern[i].hasAttribute(InstConstantAttribute()) ){
+      if( d_pattern[i].getKind()==INST_CONSTANT ){
+        //It's a variable
+        d_variables.push_back(make_triple((TNode)d_pattern[i],i,q));
+      }else{
+        //It's neither a constant argument neither a variable
+        //we create the matcher for the subpattern
+        d_childrens.push_back(make_triple(mkMatcher((TNode)d_pattern[i], qe),i,q));
+      };
+    }else{
+      // It's a constant
+      d_constants.push_back(make_triple((TNode)d_pattern[i],i,q));
+    }
+  }
+}
+
+void ApplyMatcher::resetInstantiationRound( QuantifiersEngine* qe ){
+  for( size_t i=0; i< d_childrens.size(); i++ ){
+    d_childrens[i].first->resetInstantiationRound( qe );
+  }
+}
+
+bool ApplyMatcher::reset(TNode t, InstMatch & m, QuantifiersEngine* qe){
+  Debug("matching") << "Matching " << t << " against pattern " << d_pattern << " ("
+                    << m.size() << ")"  << std::endl;
+
+  //if t is null
+  Assert( !t.isNull() );
+  Assert( !t.hasAttribute(InstConstantAttribute()) );
+  Assert( t.getKind()==d_pattern.getKind() );
+  Assert( (t.getKind()!=APPLY_UF && t.getKind()!=APPLY_CONSTRUCTOR)
+          || t.getOperator()==d_pattern.getOperator() );
+
+  typedef std::vector< triple<TNode,size_t,EqualityQuery*> >::iterator iterator;
+  for(iterator i = d_constants.begin(), end = d_constants.end();
+      i != end; ++i){
+    if( !i->third->areEqual( i->first, t[i->second] ) ){
+      Debug("matching-fail") << "Match fail arg: " << i->first << " and " << t[i->second] << std::endl;
+      //setMatchFail( qe, d_pattern[i], t[i] );
+      //ground arguments are not equal
+      return false;
+    }
+  }
+
+  d_binded.clear();
+  bool set;
+  for(iterator i = d_variables.begin(), end = d_variables.end();
+      i != end; ++i){
+    if( !m.setMatch( i->third, i->first, t[i->second], set) ){
+      //match is in conflict
+      Debug("matching-debug") << "Match in conflict " << t[i->second] << " and "
+                              << i->first << " because "
+                              << m.get(i->first)
+                              << std::endl;
+      Debug("matching-fail") << "Match fail: " << m.get(i->first) << " and " << t[i->second] << std::endl;
+      //setMatchFail( qe, partial[0].d_map[d_pattern[i]], t[i] );
+      m.erase(d_binded.begin(), d_binded.end());
+      return false;
+    }else{
+      if(set){ //The variable has just been set
+        d_binded.push_back(i->first);
+      }
+    }
+  }
+
+  //now, fit children into match
+  //we will be requesting candidates for matching terms for each child
+  d_reps.clear();
+  for( size_t i=0; i< d_childrens.size(); i++ ){
+    Debug("matching-debug") << "Take the representative of " << t[ d_childrens[i].second ] << std::endl;
+    Assert( d_childrens[i].third->hasTerm(t[ d_childrens[i].second ]) );
+    Node rep = d_childrens[i].third->getRepresentative( t[ d_childrens[i].second ] );
+    d_reps.push_back( rep );
+  }
+
+  if(d_childrens.size() == 0) return true;
+  else return getNextMatch(m, qe, true);
+}
+
+bool ApplyMatcher::getNextMatch(InstMatch& m, QuantifiersEngine* qe, bool reset){
+  Assert(d_childrens.size() > 0);
+  const size_t max = d_childrens.size() - 1;
+  size_t index = reset ? 0 : max;
+  Assert(d_childrens.size() == d_reps.size());
+  while(true){
+    if(reset ?
+       d_childrens[index].first->reset( d_reps[index], m, qe ) :
+       d_childrens[index].first->getNextMatch( m, qe )){
+      if(index==max) return true;
+      ++index;
+      reset=true;
+    }else{
+      if(index==0){
+        m.erase(d_binded.begin(), d_binded.end());
+        return false;
+      }
+      --index;
+      reset=false;
+    };
+  }
+}
+
+bool ApplyMatcher::getNextMatch(InstMatch& m, QuantifiersEngine* qe){
+  if(d_childrens.size() == 0){
+    m.erase(d_binded.begin(), d_binded.end());
+    return false;
+  } else return getNextMatch(m, qe, false);
+}
+
+/** Proxy that call the sub-matcher on the result return by the given candidate generator */
+template <class CG, class M>
+class CandidateGeneratorMatcher: public Matcher{
+  /** candidate generator */
+  CG d_cg;
+  /** the sub-matcher */
+  M d_m;
+public:
+  CandidateGeneratorMatcher(CG cg, M m): d_cg(cg), d_m(m)
+  {/* last is Null */};
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cg.resetInstantiationRound();
+    d_m.resetInstantiationRound(qe);
+  };
+  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe ){
+    d_cg.reset(n);
+    return findMatch(m,qe);
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    // The sub-matcher has another match
+    return d_m.getNextMatch(m, qe) || findMatch(m,qe);
+  }
+private:
+  bool findMatch( InstMatch& m, QuantifiersEngine* qe ){
+    // Otherwise try to find a new candidate that has at least one match
+    while(true){
+      TNode n = d_cg.getNextCandidate();//kept somewhere Term-db
+      Debug("matching") << "GenCand " << n << " (" << this << ")" << std::endl;
+      if(n.isNull()) return false;
+      if(d_m.reset(n,m,qe)) return true;
+    };
+  }
+};
+
+/** Proxy that call the sub-matcher on the result return by the given candidate generator */
+template<class M>
+class PatOfMatcher: public PatMatcher{
+  M d_m;
+public:
+  inline PatOfMatcher(M m): d_m(m){}
+  void resetInstantiationRound(QuantifiersEngine* qe){
+    d_m.resetInstantiationRound(qe);
+  }
+  bool reset(InstMatch& m, QuantifiersEngine* qe){
+    return d_m.reset(Node::null(),m,qe);
+  };
+  bool getNextMatch(InstMatch& m, QuantifiersEngine* qe){
+    return d_m.getNextMatch(m,qe);
+  };
+};
+
+class ArithMatcher: public Matcher{
+private:
+  /** for arithmetic matching */
+  std::map< Node, Node > d_arith_coeffs;
+  /** get the match against ground term or formula t.
+      d_match_mattern and t should have the same shape.
+      only valid for use where !d_match_pattern.isNull().
+  */
+  /** the variable that are set by this matcher */
+  std::vector< TNode > d_binded; /* TNode because the variables are already in d_arith_coeffs */
+  Node d_pattern; //for debugging
+public:
+  ArithMatcher(Node pat, QuantifiersEngine* qe);
+  void resetInstantiationRound( QuantifiersEngine* qe ){};
+  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe );
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe );
+};
+
+/** Match just a variable */
+class VarMatcher: public Matcher{
+  Node d_var;
+  bool d_binded; /* True if the reset bind the variable to some value */
+  EqualityQuery* d_q;
+public:
+  VarMatcher(Node var, QuantifiersEngine* qe): d_var(var), d_binded(false){
+    d_q = qe->getEqualityQuery(var.getType());
+  }
+  void resetInstantiationRound( QuantifiersEngine* qe ){};
+  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe ){
+    if(!m.setMatch( d_q, d_var, n, d_binded )){
+      //match is in conflict
+      Debug("matching-fail") << "Match fail: " << m.get(d_var)
+                             << " and " << n << std::endl;
+      return false;
+    } else return true;
+  };
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    //match is in conflict
+    if (d_binded) m.erase(d_var);
+    return false;
+  }
+};
+
+template <class M, class Test >
+class TestMatcher: public Matcher{
+  M d_m;
+  Test d_test;
+public:
+  inline TestMatcher(M m, Test test): d_m(m), d_test(test){}
+  inline void resetInstantiationRound(QuantifiersEngine* qe){
+    d_m.resetInstantiationRound(qe);
+  }
+  inline bool reset(TNode n, InstMatch& m, QuantifiersEngine* qe){
+    return d_test(n) && d_m.reset(n, m, qe);
+  }
+  inline bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_m.getNextMatch(m, qe);
+  }
+};
+
+class LegalOpTest/*: public unary_function<TNode,bool>*/ {
+  Node d_op;
+public:
+  inline LegalOpTest(Node op): d_op(op){}
+  inline bool operator() (TNode n) {
+    return
+      CandidateGenerator::isLegalCandidate(n) &&
+      // ( // n.getKind()==SELECT || n.getKind()==STORE ||
+      //  n.getKind()==APPLY_UF || n.getKind()==APPLY_CONSTRUCTOR) &&
+      n.hasOperator() &&
+      n.getOperator()==d_op;
+  };
+};
+
+class LegalKindTest/* : public unary_function<TNode,bool>*/ {
+  Kind d_kind;
+public:
+  inline LegalKindTest(Kind kind): d_kind(kind){}
+  inline bool operator() (TNode n) {
+    return
+      CandidateGenerator::isLegalCandidate(n) &&
+      n.getKind()==d_kind;
+  };
+};
+
+class LegalTypeTest/* : public unary_function<TNode,bool>*/ {
+  TypeNode d_type;
+public:
+  inline LegalTypeTest(TypeNode type): d_type(type){}
+  inline bool operator() (TNode n) {
+    return
+      CandidateGenerator::isLegalCandidate(n) &&
+      n.getType()==d_type;
+  };
+};
+
+class LegalTest/* : public unary_function<TNode,bool>*/ {
+public:
+  inline bool operator() (TNode n) {
+    return CandidateGenerator::isLegalCandidate(n);
+  };
+};
+
+size_t numFreeVar(TNode t){
+  size_t n = 0;
+  for( size_t i=0, size =t.getNumChildren(); i < size; ++i ){
+    if( t[i].hasAttribute(InstConstantAttribute()) ){
+      if( t[i].getKind()==INST_CONSTANT ){
+        //variable
+        ++n;
+      }else{
+        //neither variable nor constant
+        n += numFreeVar(t[i]);
+      }
+    }
+  }
+  return n;
+}
+
+class OpMatcher: public Matcher{
+  /* The matcher */
+  typedef ApplyMatcher AuxMatcher3;
+  typedef TestMatcher< AuxMatcher3, LegalOpTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass, AuxMatcher2> AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
+    Assert( pat.getKind() == kind::APPLY_UF );
+    /** In reverse order of matcher sequence */
+    AuxMatcher3 am3(pat,qe);
+    /** Keep only the one that have the good operator */
+    AuxMatcher2 am2(am3,LegalOpTest(pat.getOperator()));
+    /** Iter on the equivalence class of the given term */
+    uf::TheoryUF* uf = static_cast<uf::TheoryUF *>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF ));
+    eq::EqualityEngine* ee = static_cast<eq::EqualityEngine*>(uf->getEqualityEngine());
+    CandidateGeneratorTheoryEeClass cdtUfEq(ee);
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(cdtUfEq,am2);
+    return am1;
+  }
+  size_t d_num_var;
+  Node d_pat;
+public:
+  OpMatcher( Node pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)),d_num_var(numFreeVar(pat)),
+    d_pat(pat) {}
+
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
+    // size_t m_size = m.d_map.size();
+    // if(m_size == d_num_var){
+    //   uf::EqualityEngine<uf::TheoryUF::NotifyClass>* ee = (static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF )))->getEqualityEngine();
+    //   std::cout << "!";
+    //   return ee->areEqual(m.subst(d_pat),t);
+    // }else{
+    // std::cout << m.d_map.size() << std::endl;
+    return d_cgm.reset(t, m, qe);
+    // }
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+class DatatypesMatcher: public Matcher{
+  /* The matcher */
+  typedef ApplyMatcher AuxMatcher3;
+  typedef TestMatcher< AuxMatcher3, LegalOpTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass, AuxMatcher2> AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
+    Assert( pat.getKind() == kind::APPLY_CONSTRUCTOR,
+            "For datatypes only constructor are accepted in pattern" );
+    /** In reverse order of matcher sequence */
+    AuxMatcher3 am3(pat,qe);
+    /** Keep only the one that have the good operator */
+    AuxMatcher2 am2(am3,LegalOpTest(pat.getOperator()));
+    /** Iter on the equivalence class of the given term */
+    datatypes::TheoryDatatypes* dt = static_cast<datatypes::TheoryDatatypes *>(qe->getTheoryEngine()->getTheory( theory::THEORY_DATATYPES ));
+    eq::EqualityEngine* ee = static_cast<eq::EqualityEngine*>(dt->getEqualityEngine());
+    CandidateGeneratorTheoryEeClass cdtDtEq(ee);
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(cdtDtEq,am2);
+    return am1;
+  }
+  Node d_pat;
+public:
+  DatatypesMatcher( Node pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)),
+    d_pat(pat) {}
+
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
+    Debug("matching") << "datatypes: " << t << " matches " << d_pat << std::endl;
+    return d_cgm.reset(t, m, qe);
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+class ArrayMatcher: public Matcher{
+  /* The matcher */
+  typedef ApplyMatcher AuxMatcher3;
+  typedef TestMatcher< AuxMatcher3, LegalKindTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass, AuxMatcher2> AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
+    Assert( pat.getKind() == kind::SELECT || pat.getKind() == kind::STORE );
+    /** In reverse order of matcher sequence */
+    AuxMatcher3 am3(pat,qe);
+    /** Keep only the one that have the good operator */
+    AuxMatcher2 am2(am3, LegalKindTest(pat.getKind()));
+    /** Iter on the equivalence class of the given term */
+    arrays::TheoryArrays* ar = static_cast<arrays::TheoryArrays *>(qe->getTheoryEngine()->getTheory( theory::THEORY_ARRAY ));
+    eq::EqualityEngine* ee =
+      static_cast<eq::EqualityEngine*>(ar->getEqualityEngine());
+    CandidateGeneratorTheoryEeClass cdtUfEq(ee);
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(cdtUfEq,am2);
+    return am1;
+  }
+  size_t d_num_var;
+  Node d_pat;
+public:
+  ArrayMatcher( Node pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)),d_num_var(numFreeVar(pat)),
+    d_pat(pat) {}
+
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
+    // size_t m_size = m.d_map.size();
+    // if(m_size == d_num_var){
+    //   uf::EqualityEngine<uf::TheoryUF::NotifyClass>* ee = (static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF )))->getEqualityEngine();
+    //   std::cout << "!";
+    //   return ee->areEqual(m.subst(d_pat),t);
+    // }else{
+    // std::cout << m.d_map.size() << std::endl;
+    return d_cgm.reset(t, m, qe);
+    // }
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+class AllOpMatcher: public PatMatcher{
+  /* The matcher */
+  typedef ApplyMatcher AuxMatcher3;
+  typedef TestMatcher< AuxMatcher3, LegalTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryUfOp, AuxMatcher2> AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
+    Assert( pat.hasOperator() );
+    /** In reverse order of matcher sequence */
+    AuxMatcher3 am3(pat,qe);
+    /** Keep only the one that have the good operator */
+    AuxMatcher2 am2(am3,LegalTest());
+    /** Iter on the equivalence class of the given term */
+    TermDb* tdb = qe->getTermDatabase();
+    CandidateGeneratorTheoryUfOp cdtUfEq(pat.getOperator(),tdb);
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(cdtUfEq,am2);
+    return am1;
+  }
+  size_t d_num_var;
+  Node d_pat;
+public:
+  AllOpMatcher( TNode pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)), d_num_var(numFreeVar(pat)),
+    d_pat(pat) {}
+
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( InstMatch& m, QuantifiersEngine* qe ){
+    //    std::cout << m.d_map.size() << "/" << d_num_var << std::endl;
+    return d_cgm.reset(Node::null(), m, qe);
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+template <bool classes> /** true classes | false class */
+class GenericCandidateGeneratorClasses: public CandidateGenerator{
+private:
+  CandidateGenerator* d_cg;
+  QuantifiersEngine* d_qe;
+
+public:
+  void mkCandidateGenerator(){
+    if(classes)
+      d_cg = d_qe->getRRCanGenClasses();
+    else
+     d_cg = d_qe->getRRCanGenClass();
+  }
+
+  GenericCandidateGeneratorClasses(QuantifiersEngine* qe):
+    d_qe(qe) {
+    mkCandidateGenerator();
+  }
+  ~GenericCandidateGeneratorClasses(){
+    delete(d_cg);
+  }
+  const GenericCandidateGeneratorClasses & operator =(const GenericCandidateGeneratorClasses & m){
+    mkCandidateGenerator();
+    return m;
+  };
+  GenericCandidateGeneratorClasses(const GenericCandidateGeneratorClasses & m):
+  d_qe(m.d_qe){
+    mkCandidateGenerator();
+  }
+  void resetInstantiationRound(){
+    d_cg->resetInstantiationRound();
+  };
+  void reset( TNode eqc ){
+    Assert( !classes || eqc.isNull() );
+    d_cg->reset(eqc);
+  }; //* the argument is not used
+  TNode getNextCandidate(){
+    return d_cg->getNextCandidate();
+  };
+}; /* MetaCandidateGeneratorClasses */
+
+
+class GenericMatcher: public Matcher{
+  /* The matcher */
+  typedef ApplyMatcher AuxMatcher3;
+  typedef TestMatcher< AuxMatcher3, LegalOpTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< GenericCandidateGeneratorClasses<false>, AuxMatcher2> AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
+    /** In reverse order of matcher sequence */
+    AuxMatcher3 am3(pat,qe);
+    /** Keep only the one that have the good operator */
+    AuxMatcher2 am2(am3,LegalOpTest(pat.getOperator()));
+    /** Iter on the equivalence class of the given term */
+    GenericCandidateGeneratorClasses<false> cdtG(qe);
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(cdtG,am2);
+    return am1;
+  }
+  Node d_pat;
+public:
+  GenericMatcher( Node pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)),
+    d_pat(pat) {}
+
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.reset(t, m, qe);
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+
+class GenericPatMatcher: public PatMatcher{
+  /* The matcher */
+  typedef ApplyMatcher AuxMatcher3;
+  typedef TestMatcher< AuxMatcher3, LegalOpTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< GenericCandidateGeneratorClasses<true>, AuxMatcher2> AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
+    /** In reverse order of matcher sequence */
+    AuxMatcher3 am3(pat,qe);
+    /** Keep only the one that have the good operator */
+    AuxMatcher2 am2(am3,LegalOpTest(pat.getOperator()));
+    /** Iter on the equivalence class of the given term */
+    GenericCandidateGeneratorClasses<true> cdtG(qe);
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(cdtG,am2);
+    return am1;
+  }
+  Node d_pat;
+public:
+  GenericPatMatcher( Node pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)),
+    d_pat(pat) {}
+
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.reset(Node::null(), m, qe);
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+class MetaCandidateGeneratorClasses: public CandidateGenerator{
+private:
+  CandidateGenerator* d_cg;
+  TypeNode d_ty;
+  TheoryEngine* d_te;
+
+public:
+  CandidateGenerator* mkCandidateGenerator(TypeNode ty, TheoryEngine* te){
+    Debug("inst-match-gen") << "MetaCandidateGenerator for type: " << ty
+                            << " Theory : " << Theory::theoryOf(ty) << std::endl;
+    if( Theory::theoryOf(ty) == theory::THEORY_DATATYPES ){
+      // datatypes::TheoryDatatypes* dt = static_cast<datatypes::TheoryDatatypes *>(te->getTheory( theory::THEORY_DATATYPES ));
+      // return new datatypes::rrinst::CandidateGeneratorTheoryClasses(dt);
+      Unimplemented("MetaCandidateGeneratorClasses for THEORY_DATATYPES");
+    }else if ( Theory::theoryOf(ty) == theory::THEORY_ARRAY ){
+      arrays::TheoryArrays* ar = static_cast<arrays::TheoryArrays *>(te->getTheory( theory::THEORY_ARRAY ));
+      eq::EqualityEngine* ee =
+        static_cast<eq::EqualityEngine*>(ar->getEqualityEngine());
+      return new CandidateGeneratorTheoryEeClasses(ee);
+    } else {
+      uf::TheoryUF* uf = static_cast<uf::TheoryUF*>(te->getTheory( theory::THEORY_UF ));
+      eq::EqualityEngine* ee =
+        static_cast<eq::EqualityEngine*>(uf->getEqualityEngine());
+      return new CandidateGeneratorTheoryEeClasses(ee);
+    }
+  }
+  MetaCandidateGeneratorClasses(TypeNode ty, TheoryEngine* te):
+    d_ty(ty), d_te(te) {
+    d_cg = mkCandidateGenerator(ty,te);
+  }
+  ~MetaCandidateGeneratorClasses(){
+    delete(d_cg);
+  }
+  const MetaCandidateGeneratorClasses & operator =(const MetaCandidateGeneratorClasses & m){
+    d_cg = mkCandidateGenerator(m.d_ty, m.d_te);
+    return m;
+  };
+  MetaCandidateGeneratorClasses(const MetaCandidateGeneratorClasses & m):
+  d_ty(m.d_ty), d_te(m.d_te){
+    d_cg = mkCandidateGenerator(m.d_ty, m.d_te);
+  }
+  void resetInstantiationRound(){
+    d_cg->resetInstantiationRound();
+  };
+  void reset( TNode eqc ){
+    d_cg->reset(eqc);
+  }; //* the argument is not used
+  TNode getNextCandidate(){
+    return d_cg->getNextCandidate();
+  };
+}; /* MetaCandidateGeneratorClasses */
+
+/** Match just a variable */
+class AllVarMatcher: public PatMatcher{
+private:
+  /* generator */
+  typedef VarMatcher AuxMatcher3;
+  typedef TestMatcher< AuxMatcher3, LegalTypeTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< MetaCandidateGeneratorClasses, AuxMatcher2 > AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  static inline AuxMatcher1 createCgm(TNode pat, QuantifiersEngine* qe){
+    Assert( pat.getKind()==INST_CONSTANT );
+    TypeNode ty = pat.getType();
+    Debug("inst-match-gen") << "create AllVarMatcher for type: " << ty << std::endl;
+    /** In reverse order of matcher sequence */
+    /** Distribute it to all the pattern */
+    AuxMatcher3 am3(pat,qe);
+    /** Keep only the one that have the good type */
+    AuxMatcher2 am2(am3,LegalTypeTest(ty));
+    /** Generate one term by eq classes */
+    MetaCandidateGeneratorClasses mcdt(ty,qe->getTheoryEngine());
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(mcdt,am2);
+    return am1;
+  }
+public:
+  AllVarMatcher( TNode pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)){}
+
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.reset(Node::null(), m, qe); //cdtUfEq doesn't use it's argument for reset
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+/** Match all the pattern with the same term */
+class SplitMatcher: public Matcher{
+private:
+  const size_t size;
+  ApplyMatcher d_m; /** Use ApplyMatcher by creating a fake application */
+public:
+  SplitMatcher(std::vector< Node > pats, QuantifiersEngine* qe):
+    size(pats.size()),
+    d_m(NodeManager::currentNM()->mkNode(kind::INST_PATTERN,pats), qe) {}
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_m.resetInstantiationRound(qe);
+  };
+  bool reset( TNode ex, InstMatch& m, QuantifiersEngine* qe ){
+    NodeBuilder<> n(kind::INST_PATTERN);
+    for(size_t i = 0; i < size; ++i) n << ex;
+    Node nn = n;
+    return d_m.reset(nn,m,qe);
+  };
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return getNextMatch(m, qe);
+  }
+};
+
+
+/** Match uf term in a fixed equivalence class */
+class UfCstEqMatcher: public PatMatcher{
+private:
+  /* equivalence class to match */
+  Node d_cst;
+  /* generator */
+  OpMatcher d_cgm;
+public:
+  UfCstEqMatcher( Node pat, Node cst, QuantifiersEngine* qe ):
+    d_cst(cst),
+    d_cgm(OpMatcher(pat,qe)) {};
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.reset(d_cst, m, qe);
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+/** Match equalities */
+class UfEqMatcher: public PatMatcher{
+private:
+  /* generator */
+  typedef SplitMatcher AuxMatcher3;
+  typedef TestMatcher< AuxMatcher3, LegalTypeTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClasses, AuxMatcher2 > AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  static inline AuxMatcher1 createCgm(std::vector<Node> & pat, QuantifiersEngine* qe){
+    Assert( pat.size() > 0);
+    TypeNode ty = pat[0].getType();
+    for(size_t i = 1; i < pat.size(); ++i){
+      Assert(pat[i].getType() == ty);
+    }
+    /** In reverse order of matcher sequence */
+    /** Distribute it to all the pattern */
+    AuxMatcher3 am3(pat,qe);
+    /** Keep only the one that have the good type */
+    AuxMatcher2 am2(am3,LegalTypeTest(ty));
+    /** Generate one term by eq classes */
+    uf::TheoryUF* uf = static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF ));
+    eq::EqualityEngine* ee =
+      static_cast<eq::EqualityEngine*>(uf->getEqualityEngine());
+    CandidateGeneratorTheoryEeClasses cdtUfEq(ee);
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(cdtUfEq,am2);
+    return am1;
+  }
+public:
+  UfEqMatcher( std::vector<Node> & pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)){}
+
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.reset(Node::null(), m, qe); //cdtUfEq doesn't use it's argument for reset
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+
+/** Match dis-equalities */
+class UfDeqMatcher: public PatMatcher{
+private:
+  /* generator */
+  typedef ApplyMatcher AuxMatcher3;
+
+  class EqTest/* : public unary_function<Node,bool>*/ {
+    TypeNode d_type;
+  public:
+    inline EqTest(TypeNode type): d_type(type){};
+    inline bool operator() (Node n) {
+      return
+        CandidateGenerator::isLegalCandidate(n) &&
+        n.getKind() == kind::EQUAL &&
+        n[0].getType()==d_type;
+    };
+  };
+  typedef TestMatcher< AuxMatcher3, EqTest > AuxMatcher2;
+  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass, AuxMatcher2 > AuxMatcher1;
+  AuxMatcher1 d_cgm;
+  Node false_term;
+  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
+    Assert( pat.getKind() == kind::NOT);
+    TNode eq = pat[0];
+    Assert( eq.getKind() == kind::EQUAL);
+    TypeNode ty = eq[0].getType();
+    /** In reverse order of matcher sequence */
+    /** Distribute it to all the pattern */
+    AuxMatcher3 am3(eq,qe);
+    /** Keep only the one that have the good type */
+    AuxMatcher2 am2(am3,EqTest(ty));
+    /** Will generate all the terms of the eq class of false */
+    uf::TheoryUF* uf = static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF ));
+    eq::EqualityEngine* ee =
+      static_cast<eq::EqualityEngine*>(uf->getEqualityEngine());
+    CandidateGeneratorTheoryEeClass cdtUfEq(ee);
+    /* Create a matcher from the candidate generator */
+    AuxMatcher1 am1(cdtUfEq,am2);
+    return am1;
+  }
+public:
+  UfDeqMatcher( Node pat, QuantifiersEngine* qe ):
+    d_cgm(createCgm(pat, qe)),
+    false_term((static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF )))->getEqualityEngine()->
+                getRepresentative(NodeManager::currentNM()->mkConst<bool>(false) )){};
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    d_cgm.resetInstantiationRound(qe);
+  };
+  bool reset( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.reset(false_term, m, qe);
+  }
+  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+    return d_cgm.getNextMatch(m, qe);
+  }
+};
+
+Matcher* mkMatcher( Node pat, QuantifiersEngine* qe ){
+  Debug("inst-match-gen") << "mkMatcher: Pattern term is " << pat << std::endl;
+
+  // if( pat.getKind() == kind::APPLY_UF){
+  //   return new OpMatcher(pat, qe);
+  // } else if( pat.getKind() == kind::APPLY_CONSTRUCTOR ){
+  //   return new DatatypesMatcher(pat, qe);
+  // } else if( pat.getKind() == kind::SELECT || pat.getKind() == kind::STORE ){
+  //   return new ArrayMatcher(pat, qe);
+  if( pat.getKind() == kind::APPLY_UF ||
+      pat.getKind() == kind::APPLY_CONSTRUCTOR ||
+      pat.getKind() == kind::SELECT || pat.getKind() == kind::STORE ){
+    return new GenericMatcher(pat, qe);
+  } else { /* Arithmetic? */
+    /** TODO: something simpler to see if the pattern is a good
+        arithmetic pattern */
+    std::map< Node, Node > d_arith_coeffs;
+    if( !Trigger::getPatternArithmetic( pat.getAttribute(InstConstantAttribute()), pat, d_arith_coeffs ) ){
+      Message() << "(?) Unknown matching pattern is " << pat << std::endl;
+      Unimplemented("pattern not implemented");
+      return new DumbMatcher();
+    }else{
+      Debug("matching-arith") << "Generated arithmetic pattern for " << pat << ": " << std::endl;
+      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
+        Debug("matching-arith") << "   " << it->first << " -> " << it->second << std::endl;
+      }
+      ArithMatcher am3 (pat, qe);
+      TestMatcher<ArithMatcher, LegalTypeTest>
+        am2(am3,LegalTypeTest(pat.getType()));
+      /* generator */
+      uf::TheoryUF* uf = static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF ));
+      eq::EqualityEngine* ee =
+        static_cast<eq::EqualityEngine*> (uf->getEqualityEngine());
+      CandidateGeneratorTheoryEeClass cdtUfEq(ee);
+      return new CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass,
+        TestMatcher<ArithMatcher, LegalTypeTest> > (cdtUfEq,am2);
+    }
+  }
+};
+
+PatMatcher* mkPattern( Node pat, QuantifiersEngine* qe ){
+  Debug("inst-match-gen") << "Pattern term is " << pat << std::endl;
+  Assert( pat.hasAttribute(InstConstantAttribute()) );
+
+  if( pat.getKind()==kind::NOT && pat[0].getKind() == kind::EQUAL){
+    /* Difference */
+    return new UfDeqMatcher(pat, qe);
+  } else if (pat.getKind() == kind::EQUAL){
+    if( !pat[0].hasAttribute(InstConstantAttribute() )){
+        Assert(pat[1].hasAttribute(InstConstantAttribute()));
+        return new UfCstEqMatcher(pat[1], pat[0], qe);
+    }else if( !pat[1].hasAttribute(InstConstantAttribute() )){
+      Assert(pat[0].hasAttribute(InstConstantAttribute()));
+      return new UfCstEqMatcher(pat[0], pat[1], qe);
+    }else{
+      std::vector< Node > pats(pat.begin(),pat.end());
+      return new UfEqMatcher(pats,qe);
+    }
+  } else if( Trigger::isAtomicTrigger( pat ) ){
+    return new AllOpMatcher(pat, qe);
+    // return new GenericPatMatcher(pat, qe);
+  } else if( pat.getKind()==INST_CONSTANT ){
+    // just a variable
+    return new AllVarMatcher(pat, qe);
+  } else { /* Arithmetic? */
+    /** TODO: something simpler to see if the pattern is a good
+        arithmetic pattern */
+    std::map< Node, Node > d_arith_coeffs;
+    if( !Trigger::getPatternArithmetic( pat.getAttribute(InstConstantAttribute()), pat, d_arith_coeffs ) ){
+      Debug("inst-match-gen") << "(?) Unknown matching pattern is " << pat << std::endl;
+      Message() << "(?) Unknown matching pattern is " << pat << std::endl;
+      return new DumbPatMatcher();
+    }else{
+      Debug("matching-arith") << "Generated arithmetic pattern for " << pat << ": " << std::endl;
+      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
+        Debug("matching-arith") << "   " << it->first << " -> " << it->second << std::endl;
+      }
+      ArithMatcher am3 (pat, qe);
+      TestMatcher<ArithMatcher, LegalTest>
+        am2(am3,LegalTest());
+      /* generator */
+      TermDb* tdb = qe->getTermDatabase();
+      CandidateGeneratorTheoryUfType cdtUfEq(pat.getType(),tdb);
+      typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryUfType,
+                                          TestMatcher<ArithMatcher, LegalTest> > AuxMatcher1;
+      return new PatOfMatcher<AuxMatcher1>(AuxMatcher1(cdtUfEq,am2));
+    }
+  }
+};
+
+ArithMatcher::ArithMatcher(Node pat, QuantifiersEngine* qe): d_pattern(pat){
+
+  if(Trigger::getPatternArithmetic(pat.getAttribute(InstConstantAttribute()), pat, d_arith_coeffs ) )
+    {
+    Debug("inst-match-gen") << "(?) Unknown matching pattern is " << d_pattern << std::endl;
+    Assert(false);
+  }else{
+    Debug("matching-arith") << "Generated arithmetic pattern for " << d_pattern << ": " << std::endl;
+    for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
+      Debug("matching-arith") << "   " << it->first << " -> " << it->second << std::endl;
+    }
+  }
+
+};
+
+bool ArithMatcher::reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
+  Debug("matching-arith") << "Matching " << t << " " << d_pattern << std::endl;
+  d_binded.clear();
+  if( !d_arith_coeffs.empty() ){
+    NodeBuilder<> tb(kind::PLUS);
+    Node ic = Node::null();
+    for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
+      Debug("matching-arith") << it->first << " -> " << it->second << std::endl;
+      if( !it->first.isNull() ){
+        if( m.find( it->first )==m.end() ){
+          //see if we can choose this to set
+          if( ic.isNull() && ( it->second.isNull() || !it->first.getType().isInteger() ) ){
+            ic = it->first;
+          }
+        }else{
+          Debug("matching-arith") << "already set " << m.get( it->first ) << std::endl;
+          Node tm = m.get( it->first );
+          if( !it->second.isNull() ){
+            tm = NodeManager::currentNM()->mkNode( MULT, it->second, tm );
+          }
+          tb << tm;
+        }
+      }else{
+        tb << it->second;
+      }
+    }
+    if( !ic.isNull() ){
+      Node tm;
+      if( tb.getNumChildren()==0 ){
+        tm = t;
+      }else{
+        tm = tb.getNumChildren()==1 ? tb.getChild( 0 ) : tb;
+        tm = NodeManager::currentNM()->mkNode( MINUS, t, tm );
+      }
+      if( !d_arith_coeffs[ ic ].isNull() ){
+        Assert( !ic.getType().isInteger() );
+        Node coeff = NodeManager::currentNM()->mkConst( Rational(1) / d_arith_coeffs[ ic ].getConst<Rational>() );
+        tm = NodeManager::currentNM()->mkNode( MULT, coeff, tm );
+      }
+      m.set( ic, Rewriter::rewrite( tm ));
+      d_binded.push_back(ic);
+      //set the rest to zeros
+      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
+        if( !it->first.isNull() ){
+          if( m.find( it->first )==m.end() ){
+            m.set( it->first, NodeManager::currentNM()->mkConst( Rational(0) ));
+            d_binded.push_back(ic);
+          }
+        }
+      }
+      Debug("matching-arith") << "Setting " << ic << " to " << tm << std::endl;
+      return true;
+    }else{
+      m.erase(d_binded.begin(), d_binded.end());
+      return false;
+    }
+  }else{
+    m.erase(d_binded.begin(), d_binded.end());
+    return false;
+  }
+};
+
+bool ArithMatcher::getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
+  m.erase(d_binded.begin(), d_binded.end());
+  return false;
+};
+
+
+class MultiPatsMatcher: public PatsMatcher{
+private:
+  bool d_reset_done;
+  std::vector< PatMatcher* > d_patterns;
+  InstMatch d_im;
+  bool reset( QuantifiersEngine* qe ){
+    d_im.clear();
+    d_reset_done = true;
+
+    return getNextMatch(qe,true);
+  };
+
+  bool getNextMatch(QuantifiersEngine* qe, bool reset){
+    const size_t max = d_patterns.size() - 1;
+    size_t index = reset ? 0 : max;
+    while(true){
+      Debug("matching") << "MultiPatsMatcher::index " << index << "/"
+                        << max << (reset ? " reset_phase" : "") << std::endl;
+      if(reset ?
+         d_patterns[index]->reset( d_im, qe ) :
+         d_patterns[index]->getNextMatch( d_im, qe )){
+        if(index==max) return true;
+        ++index;
+        reset=true;
+      }else{
+        if(index==0) return false;
+        --index;
+        reset=false;
+      };
+    }
+  }
+
+public:
+  MultiPatsMatcher(std::vector< Node > & pats, QuantifiersEngine* qe):
+    d_reset_done(false){
+    Assert(pats.size() > 0);
+    for( size_t i=0; i< pats.size(); i++ ){
+      d_patterns.push_back(mkPattern(pats[i],qe));
+    };
+  };
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    for( size_t i=0; i< d_patterns.size(); i++ ){
+      d_patterns[i]->resetInstantiationRound( qe );
+    };
+    d_reset_done = false;
+    d_im.clear();
+  };
+  bool getNextMatch( QuantifiersEngine* qe ){
+    Assert(d_patterns.size()>0);
+    if(d_reset_done) return getNextMatch(qe,false);
+    else return reset(qe);
+  }
+  const InstMatch& getInstMatch(){return d_im;};
+
+  int addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe);
+};
+
+enum EffiStep{
+  ES_STOP,
+  ES_GET_MONO_CANDIDATE,
+  ES_GET_MULTI_CANDIDATE,
+  ES_RESET1,
+  ES_RESET2,
+  ES_NEXT1,
+  ES_NEXT2,
+  ES_RESET_OTHER,
+  ES_NEXT_OTHER,
+};
+static inline std::ostream& operator<<(std::ostream& out, const EffiStep& step) {
+  switch(step){
+  case ES_STOP: out << "STOP"; break;
+  case ES_GET_MONO_CANDIDATE: out << "GET_MONO_CANDIDATE"; break;
+  case ES_GET_MULTI_CANDIDATE: out << "GET_MULTI_CANDIDATE"; break;
+  case ES_RESET1: out << "RESET1"; break;
+  case ES_RESET2: out << "RESET2"; break;
+  case ES_NEXT1: out << "NEXT1"; break;
+  case ES_NEXT2: out << "NEXT2"; break;
+  case ES_RESET_OTHER: out << "RESET_OTHER"; break;
+  case ES_NEXT_OTHER: out << "NEXT_OTHER"; break;
+  }
+  return out;
+}
+
+
+int MultiPatsMatcher::addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe){
+  //now, try to add instantiation for each match produced
+  int addedLemmas = 0;
+  resetInstantiationRound( qe );
+  d_im.add( baseMatch );
+  while( getNextMatch( qe ) ){
+    InstMatch im_copy = getInstMatch();
+    //m.makeInternal( d_quantEngine->getEqualityQuery() );
+    if( qe->addInstantiation( quant, im_copy ) ){
+      addedLemmas++;
+    }
+  }
+  //return number of lemmas added
+  return addedLemmas;
+}
+
+PatsMatcher* mkPatterns( std::vector< Node > pat, QuantifiersEngine* qe ){
+  return new MultiPatsMatcher( pat, qe);
+}
+
+class MultiEfficientPatsMatcher: public PatsMatcher{
+private:
+  bool d_phase_mono;
+  bool d_phase_new_term;
+  std::vector< PatMatcher* > d_patterns;
+  std::vector< Matcher* > d_direct_patterns;
+  InstMatch d_im;
+  uf::EfficientHandler d_eh;
+  uf::EfficientHandler::MultiCandidate d_mc;
+  InstMatchTrie2Pairs<true> d_cache;
+  std::vector<Node> d_pats;
+  // bool indexDone( size_t i){
+  //   return i == d_c.first.second ||
+  //     ( i == d_c.second.second && d_c.second.first.empty());
+  // }
+
+
+
+  static const EffiStep ES_START = ES_GET_MONO_CANDIDATE;
+  EffiStep d_step;
+
+  //return true if it becomes bigger than d_patterns.size() - 1
+  bool incrIndex(size_t & index){
+    if(index == d_patterns.size() - 1) return true;
+    ++index;
+    if(index == d_mc.first.second
+       || (!d_phase_mono && index == d_mc.second.second))
+      return incrIndex(index);
+    else return false;
+  }
+
+  //return true if it becomes smaller than 0
+  bool decrIndex(size_t & index){
+    if(index == 0) return true;
+    --index;
+    if(index == d_mc.first.second
+       || (!d_phase_mono && index == d_mc.second.second))
+      return decrIndex(index);
+    else return false;
+  }
+
+  bool resetOther( QuantifiersEngine* qe ){
+    return getNextMatchOther(qe,true);
+  };
+
+
+  bool getNextMatchOther(QuantifiersEngine* qe, bool reset){
+    size_t index = reset ? 0 : d_patterns.size();
+    if(!reset && decrIndex(index)) return false;
+    if( reset &&
+        (index == d_mc.first.second
+         || (!d_phase_mono && index == d_mc.second.second))
+        && incrIndex(index)) return true;
+    while(true){
+      Debug("matching") << "MultiEfficientPatsMatcher::index " << index << "/"
+                        << d_patterns.size() - 1 << std::endl;
+      if(reset ?
+         d_patterns[index]->reset( d_im, qe ) :
+         d_patterns[index]->getNextMatch( d_im, qe )){
+        if(incrIndex(index)) return true;
+        reset=true;
+      }else{
+        if(decrIndex(index)) return false;
+        reset=false;
+      };
+    }
+  }
+
+  inline EffiStep TestMonoCache(QuantifiersEngine* qe){
+    if( //!d_phase_new_term ||
+       d_pats.size() == 1) return ES_RESET_OTHER;
+    if(d_cache.addInstMatch(d_mc.first.second,d_im)){
+      Debug("inst-match::cache") << "Cache miss" << d_im << std::endl;
+      ++qe->d_statistics.d_mono_candidates_cache_miss;
+      return ES_RESET_OTHER;
+    } else {
+      Debug("inst-match::cache") << "Cache hit" << d_im << std::endl;
+      ++qe->d_statistics.d_mono_candidates_cache_hit;
+      return ES_NEXT1;
+    }
+    // ++qe->d_statistics.d_mono_candidates_cache_miss;
+    // return ES_RESET_OTHER;
+  }
+
+  inline EffiStep TestMultiCache(QuantifiersEngine* qe){
+    if(d_cache.addInstMatch(d_mc.first.second,d_mc.second.second,d_im)){
+      ++qe->d_statistics.d_multi_candidates_cache_miss;
+      return ES_RESET_OTHER;
+    } else {
+      ++qe->d_statistics.d_multi_candidates_cache_hit;
+      return ES_NEXT2;
+    }
+  }
+
+
+public:
+
+  bool getNextMatch( QuantifiersEngine* qe ){
+    Assert( d_step == ES_START || d_step == ES_NEXT_OTHER || d_step == ES_STOP );
+    while(true){
+      Debug("matching") << "d_step=" << d_step << " "
+                        << "d_im=" << d_im << std::endl;
+      switch(d_step){
+      case ES_GET_MONO_CANDIDATE:
+        Assert(d_im.empty());
+        if(d_phase_new_term ? d_eh.getNextMonoCandidate(d_mc.first) : d_eh.getNextMonoCandidateNewTerm(d_mc.first)){
+          if(d_phase_new_term) ++qe->d_statistics.d_num_mono_candidates_new_term;
+          else ++qe->d_statistics.d_num_mono_candidates;
+          d_phase_mono = true;
+          d_step = ES_RESET1;
+        } else if (!d_phase_new_term){
+          d_phase_new_term = true;
+          d_step = ES_GET_MONO_CANDIDATE;
+        } else {
+          d_phase_new_term = false;
+          d_step = ES_GET_MULTI_CANDIDATE;
+        }
+        break;
+      case ES_GET_MULTI_CANDIDATE:
+        Assert(d_im.empty());
+        if(d_eh.getNextMultiCandidate(d_mc)){
+          ++qe->d_statistics.d_num_multi_candidates;
+          d_phase_mono = false;
+          d_step = ES_RESET1;
+        } else d_step = ES_STOP;
+        break;
+      case ES_RESET1:
+        if(d_direct_patterns[d_mc.first.second]->reset(d_mc.first.first,d_im,qe))
+          d_step = d_phase_mono ? TestMonoCache(qe) : ES_RESET2;
+        else d_step = d_phase_mono ? ES_GET_MONO_CANDIDATE : ES_GET_MULTI_CANDIDATE;
+        break;
+      case ES_RESET2:
+        Assert(!d_phase_mono);
+        if(d_direct_patterns[d_mc.second.second]->reset(d_mc.second.first,d_im,qe))
+          d_step = TestMultiCache(qe);
+        else d_step = ES_NEXT1;
+        break;
+      case ES_NEXT1:
+        if(d_direct_patterns[d_mc.first.second]->getNextMatch(d_im,qe))
+          d_step = d_phase_mono ? TestMonoCache(qe) : ES_RESET2;
+        else d_step = d_phase_mono ? ES_GET_MONO_CANDIDATE : ES_GET_MULTI_CANDIDATE;
+        break;
+      case ES_NEXT2:
+        if(d_direct_patterns[d_mc.second.second]->getNextMatch(d_im,qe))
+          d_step = TestMultiCache(qe);
+        else d_step = ES_NEXT1;
+        break;
+      case ES_RESET_OTHER:
+        if(resetOther(qe)){
+          d_step = ES_NEXT_OTHER;
+          return true;
+        } else d_step = d_phase_mono ? ES_NEXT1 : ES_NEXT2;
+        break;
+      case ES_NEXT_OTHER:
+        {
+          if(!getNextMatchOther(qe,false)){
+            d_step = d_phase_mono ? ES_NEXT1 : ES_NEXT2;
+          }else{
+            d_step = ES_NEXT_OTHER;
+            return true;
+          }
+        }
+        break;
+      case ES_STOP:
+        Assert(d_im.empty());
+        return false;
+      }
+    }
+  }
+
+  MultiEfficientPatsMatcher(std::vector< Node > & pats, QuantifiersEngine* qe):
+    d_eh(qe->getTheoryEngine()->getSatContext()),
+    d_cache(qe->getTheoryEngine()->getSatContext(),qe,pats.size()),
+    d_pats(pats), d_step(ES_START) {
+    Assert(pats.size() > 0);
+    for( size_t i=0; i< pats.size(); i++ ){
+      d_patterns.push_back(mkPattern(pats[i],qe));
+      if(pats[i].getKind()==kind::INST_CONSTANT){
+        d_direct_patterns.push_back(new VarMatcher(pats[i],qe));
+      } else if( pats[i].getKind() == kind::NOT && pats[i][0].getKind() == kind::EQUAL){
+        d_direct_patterns.push_back(new ApplyMatcher(pats[i][0],qe));
+      } else {
+        d_direct_patterns.push_back(new ApplyMatcher(pats[i],qe));
+      }
+    };
+    Theory* th_uf = qe->getTheoryEngine()->getTheory( theory::THEORY_UF );
+    uf::InstantiatorTheoryUf* ith = (uf::InstantiatorTheoryUf*)th_uf->getInstantiator();
+    ith->registerEfficientHandler(d_eh, pats);
+  };
+  void resetInstantiationRound( QuantifiersEngine* qe ){
+    Assert(d_step == ES_START || d_step == ES_STOP);
+    for( size_t i=0; i< d_patterns.size(); i++ ){
+      d_patterns[i]->resetInstantiationRound( qe );
+      d_direct_patterns[i]->resetInstantiationRound( qe );
+    };
+    d_step = ES_START;
+    d_phase_new_term = false;
+    Assert(d_im.empty());
+  };
+
+  const InstMatch& getInstMatch(){return d_im;};
+
+  int addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe);
+};
+
+int MultiEfficientPatsMatcher::addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe){
+  //now, try to add instantiation for each match produced
+  int addedLemmas = 0;
+  Assert(baseMatch.empty());
+  resetInstantiationRound( qe );
+  while( getNextMatch( qe ) ){
+    InstMatch im_copy = getInstMatch();
+    //m.makeInternal( d_quantEngine->getEqualityQuery() );
+    if( qe->addInstantiation( quant, im_copy ) ){
+      addedLemmas++;
+    }
+  }
+  //return number of lemmas added
+  return addedLemmas;
+};
+
+PatsMatcher* mkPatternsEfficient( std::vector< Node > pat, QuantifiersEngine* qe ){
+  return new MultiEfficientPatsMatcher( pat, qe);
+}
+
+} /* CVC4::theory::rrinst */
+} /* CVC4::theory */
+} /* CVC4 */
diff --git a/src/theory/rewriterules/rr_inst_match.h b/src/theory/rewriterules/rr_inst_match.h
new file mode 100644 (file)
index 0000000..d2a2467
--- /dev/null
@@ -0,0 +1,266 @@
+/*********************                                                        */
+/*! \file rr_inst_match.h
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: bobot
+ ** Minor contributors (to current version): mdeters
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief inst match class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__REWRITERULES__RR_INST_MATCH_H
+#define __CVC4__THEORY__REWRITERULES__RR_INST_MATCH_H
+
+#include "theory/theory.h"
+#include "util/hash.h"
+#include "util/ntuple.h"
+
+#include <ext/hash_set>
+#include <iostream>
+#include <map>
+
+#include "theory/uf/equality_engine.h"
+#include "theory/uf/theory_uf.h"
+#include "context/cdlist.h"
+
+#include "theory/quantifiers/inst_match.h"
+#include "expr/node_manager.h"
+#include "expr/node_builder.h"
+
+#include "theory/quantifiers/options.h"
+#include "theory/rewriterules/options.h"
+
+//#define USE_EFFICIENT_E_MATCHING
+
+namespace CVC4 {
+namespace theory {
+
+namespace rrinst{
+
+class CandidateGenerator
+{
+public:
+  CandidateGenerator(){}
+  virtual ~CandidateGenerator(){};
+
+  /** Get candidates functions.  These set up a context to get all match candidates.
+      cg->reset( eqc );
+      do{
+        Node cand = cg->getNextCandidate();
+        //.......
+      }while( !cand.isNull() );
+      
+      eqc is the equivalence class you are searching in
+  */
+  virtual void reset( TNode eqc ) = 0;
+  virtual TNode getNextCandidate() = 0;
+  /** call this at the beginning of each instantiation round */
+  virtual void resetInstantiationRound() = 0;
+public:
+  /** legal candidate */
+  static inline bool isLegalCandidate( TNode n ){
+    return !n.getAttribute(NoMatchAttribute()) &&
+      ( !options::cbqi() || !n.hasAttribute(InstConstantAttribute())) &&
+      ( !options::efficientEMatching() || n.hasAttribute(AvailableInTermDb()) );
+}
+
+};
+
+
+inline std::ostream& operator<<(std::ostream& out, const InstMatch& m) {
+  m.toStream(out);
+  return out;
+}
+
+template<bool modEq = false> class InstMatchTrie2;
+template<bool modEq = false> class InstMatchTrie2Pairs;
+
+template<bool modEq = false>
+class InstMatchTrie2Gen
+{
+  friend class InstMatchTrie2<modEq>;
+  friend class InstMatchTrie2Pairs<modEq>;
+
+private:
+
+  class Tree {
+  public:
+    typedef std::hash_map< Node, Tree *, NodeHashFunction > MLevel;
+    MLevel e;
+    const size_t level; //context level of creation
+    Tree() CVC4_UNDEFINED;
+    const Tree & operator =(const Tree & t){
+      Assert(t.e.empty()); Assert(e.empty());
+      Assert(t.level == level);
+      return t;
+    }
+    Tree(size_t l): level(l) {};
+    ~Tree(){
+      for(typename MLevel::iterator i = e.begin(); i!=e.end(); ++i)
+        delete(i->second);
+    };
+  };
+
+
+  typedef std::pair<Tree *, TNode> Mod;
+
+  class CleanUp{
+  public:
+    inline void operator()(Mod * m){
+      typename Tree::MLevel::iterator i = m->first->e.find(m->second);
+      Assert (i != m->first->e.end()); //should not have been already removed
+      m->first->e.erase(i);
+    };
+  };
+
+  EqualityQuery* d_eQ;
+  CandidateGenerator * d_cG;
+
+  context::Context* d_context;
+  context::CDList<Mod, CleanUp, std::allocator<Mod> > d_mods;
+
+
+  typedef std::map<Node, Node>::const_iterator mapIter;
+
+  /** add the substitution given by the iterator*/
+  void addSubTree( Tree * root, mapIter current, mapIter end, size_t currLevel);
+  /** test if it exists match, modulo uf-equations if modEq is true if
+   *  return false the deepest point of divergence is put in [e] and
+   *  [diverge].
+   */
+  bool existsInstMatch( Tree * root,
+                        mapIter & current, mapIter & end,
+                        Tree * & e, mapIter & diverge) const;
+
+  /** add match m in the trie root
+      return true if it was never seen */
+  bool addInstMatch( InstMatch& m, Tree * root);
+
+public:
+  InstMatchTrie2Gen(context::Context* c,  QuantifiersEngine* q);
+  InstMatchTrie2Gen(const InstMatchTrie2Gen &) CVC4_UNDEFINED;
+  const InstMatchTrie2Gen & operator =(const InstMatchTrie2Gen & e) CVC4_UNDEFINED;
+};
+
+template<bool modEq>
+class InstMatchTrie2
+{
+  typename InstMatchTrie2Gen<modEq>::Tree d_data;
+  InstMatchTrie2Gen<modEq> d_backtrack;
+public:
+  InstMatchTrie2(context::Context* c,  QuantifiersEngine* q): d_data(0),
+                                                              d_backtrack(c,q) {};
+  InstMatchTrie2(const InstMatchTrie2 &) CVC4_UNDEFINED;
+  const InstMatchTrie2 & operator =(const InstMatchTrie2 & e) CVC4_UNDEFINED;
+  /** add match m in the trie,
+      return true if it was never seen */
+  inline bool addInstMatch( InstMatch& m){
+    return d_backtrack.addInstMatch(m,&d_data);
+  };
+
+};/* class InstMatchTrie2 */
+
+class Matcher
+{
+public:
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  virtual void resetInstantiationRound( QuantifiersEngine* qe ) = 0;
+  /** reset the term to match, return false if there is no such term */
+  virtual bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe ) = 0;
+  /** get the next match. If it return false once you shouldn't call
+      getNextMatch again before doing a reset */
+  virtual bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) = 0;
+  /** If reset, or getNextMatch return false they remove from the
+      InstMatch the binding that they have previously created */
+
+  /** virtual Matcher in order to have definned behavior */
+  virtual ~Matcher(){};
+};
+
+
+class ApplyMatcher: public Matcher{
+private:
+  /** What to check first: constant and variable */
+  std::vector< triple< TNode,size_t,EqualityQuery* > > d_constants;
+  std::vector< triple< TNode,size_t,EqualityQuery* > > d_variables;
+  /** children generators, only the sub-pattern which are
+      neither a variable neither a constant appears */
+  std::vector< triple< Matcher*, size_t, EqualityQuery* > > d_childrens;
+  /** the variable that have been set by this matcher (during its own reset) */
+  std::vector< TNode > d_binded; /* TNode because the variable are already in d_pattern */
+  /** the representant of the argument of the term given by the last reset */
+  std::vector< Node > d_reps;
+public:
+  /** The pattern we are producing matches for */
+  Node d_pattern;
+public:
+  /** constructors */
+  ApplyMatcher( Node pat, QuantifiersEngine* qe);
+  /** destructor */
+  ~ApplyMatcher(){/*TODO delete dandling pointers? */}
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  void resetInstantiationRound( QuantifiersEngine* qe );
+  /** reset the term to match */
+  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe );
+  /** get the next match. */
+  bool getNextMatch(InstMatch& m, QuantifiersEngine* qe);
+private:
+  bool getNextMatch(InstMatch& m, QuantifiersEngine* qe, bool reset);
+};
+
+
+/* Match literal so you don't choose the equivalence class( */
+class PatMatcher
+{
+public:
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  virtual void resetInstantiationRound( QuantifiersEngine* qe ) = 0;
+  /** reset the matcher, return false if there is no such term */
+  virtual bool reset( InstMatch& m, QuantifiersEngine* qe ) = 0;
+  /** get the next match. If it return false once you shouldn't call
+      getNextMatch again before doing a reset */
+  virtual bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) = 0;
+  /** If reset, or getNextMatch return false they remove from the
+      InstMatch the binding that they have previously created */
+};
+
+Matcher* mkMatcher( Node pat, QuantifiersEngine* qe );
+PatMatcher* mkPattern( Node pat, QuantifiersEngine* qe );
+
+/* Match literal so you don't choose the equivalence class( */
+class PatsMatcher
+{
+public:
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  virtual void resetInstantiationRound( QuantifiersEngine* qe ) = 0;
+  /** reset the matcher, return false if there is no such term */
+  virtual bool getNextMatch( QuantifiersEngine* qe ) = 0;
+  virtual const InstMatch& getInstMatch() = 0;
+  /** Add directly the instantiation to quantifiers engine */
+  virtual int addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe) = 0;
+};
+
+PatsMatcher* mkPatterns( std::vector< Node > pat, QuantifiersEngine* qe );
+PatsMatcher* mkPatternsEfficient( std::vector< Node > pat, QuantifiersEngine* qe );
+
+/** return true if whatever Node is subsituted for the variables the
+    given Node can't match the pattern */
+bool nonunifiable( TNode t, TNode pat, const std::vector<Node> & vars);
+
+class InstMatchGenerator;
+
+}/* CVC4::theory rrinst */
+
+}/* CVC4::theory namespace */
+
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__REWRITERULES__RR_INST_MATCH_H */
diff --git a/src/theory/rewriterules/rr_inst_match_impl.h b/src/theory/rewriterules/rr_inst_match_impl.h
new file mode 100644 (file)
index 0000000..aa6cf81
--- /dev/null
@@ -0,0 +1,128 @@
+/*********************                                                        */
+/*! \file rr_inst_match_impl.h
+ ** \verbatim
+ ** Original author: bobot
+ ** Major contributors: none
+ ** Minor contributors (to current version): ajreynol, mdeters
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief inst match class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__REWRITERULES__RR_INST_MATCH_IMPL_H
+#define __CVC4__THEORY__REWRITERULES__RR_INST_MATCH_IMPL_H
+
+#include "theory/rewriterules/rr_inst_match.h"
+#include "theory/theory_engine.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/rewriterules/rr_candidate_generator.h"
+#include "theory/uf/equality_engine.h"
+
+namespace CVC4 {
+namespace theory {
+namespace rrinst {
+
+template<bool modEq>
+InstMatchTrie2Gen<modEq>::InstMatchTrie2Gen(context::Context* c,  QuantifiersEngine* qe):
+  d_context(c), d_mods(c) {
+  d_eQ = qe->getEqualityQuery();
+  d_cG = qe->getRRCanGenClass();
+};
+
+/** add match m for quantifier f starting at index, take into account equalities q, return true if successful */
+template<bool modEq>
+void InstMatchTrie2Gen<modEq>::addSubTree( Tree * root, mapIter current, mapIter end, size_t currLevel ) {
+  if( current == end ) return;
+
+  Assert(root->e.find(current->second) == root->e.end());
+  Tree * root2 = new Tree(currLevel);
+  root->e.insert(std::make_pair(current->second, root2));
+  addSubTree(root2, ++current, end, currLevel );
+}
+
+/** exists match */
+template<bool modEq>
+bool InstMatchTrie2Gen<modEq>::existsInstMatch(InstMatchTrie2Gen<modEq>::Tree * root,
+                                            mapIter & current, mapIter & end,
+                                            Tree * & e, mapIter & diverge) const{
+  if( current == end ) {
+    Debug("Trie2") << "Trie2 Bottom " << std::endl;
+    --current;
+    return true;
+  }; //Already their
+
+  if (current->first > diverge->first){
+    // this point is the deepest point currently seen map are ordered
+    e = root;
+    diverge = current;
+  };
+
+  TNode n = current->second;
+  typename InstMatchTrie2Gen<modEq>::Tree::MLevel::iterator it =
+    root->e.find( n );
+  if( it!=root->e.end() &&
+      existsInstMatch( (*it).second, ++current, end, e, diverge) ){
+    Debug("Trie2") << "Trie2 Directly here " << n << std::endl;
+    --current;
+    return true;
+  }
+  Assert( it==root->e.end() || e != root );
+
+  // Even if n is in the trie others of the equivalence class
+  // can also be in it since the equality can have appeared
+  // after they have been added
+  if( modEq && d_eQ->hasTerm( n ) ){
+    //check modulo equality if any other instantiation match exists
+    d_cG->reset( d_eQ->getRepresentative( n ) );
+    for(TNode en = d_cG->getNextCandidate() ; !en.isNull() ;
+        en = d_cG->getNextCandidate() ){
+      if( en == n ) continue; // already tested
+      typename InstMatchTrie2Gen<modEq>::Tree::MLevel::iterator itc =
+        root->e.find( en );
+      if( itc!=root->e.end() &&
+          existsInstMatch( (*itc).second, ++current, end, e, diverge) ){
+        Debug("Trie2") << "Trie2 Indirectly here by equality " << n << " = " << en << std::endl;
+        --current;
+        return true;
+      }
+      Assert( itc==root->e.end() || e != root );
+    }
+  }
+  --current;
+  return false;
+}
+
+template<bool modEq>
+bool InstMatchTrie2Gen<modEq>::
+addInstMatch( InstMatch& m, InstMatchTrie2Gen<modEq>::Tree* e ) {
+  d_cG->resetInstantiationRound();
+ mapIter begin = m.begin();
+ mapIter end = m.end();
+ mapIter diverge = begin;
+ if( !existsInstMatch(e, begin, end, e, diverge ) ){
+   Assert(!diverge->second.isNull());
+   size_t currLevel = d_context->getLevel();
+   addSubTree( e, diverge, end, currLevel );
+   if(e->level != currLevel)
+     //If same level that e, will be removed at the same time than e
+     d_mods.push_back(std::make_pair(e,diverge->second));
+   return true;
+ }else{
+   return false;
+ }
+}
+
+}/* CVC4::theory::rrinst namespace */
+
+}/* CVC4::theory namespace */
+
+}/* CVC4 namespace */
+
+#endif /*  __CVC4__THEORY__REWRITERULES__RR_INST_MATCH_IMPL_H */
diff --git a/src/theory/rewriterules/rr_trigger.cpp b/src/theory/rewriterules/rr_trigger.cpp
new file mode 100644 (file)
index 0000000..78c0e94
--- /dev/null
@@ -0,0 +1,523 @@
+/*********************                                                        */
+/*! \file rr_trigger.cpp
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: mdeters
+ ** Minor contributors (to current version): bobot
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Implementation of trigger class
+ **/
+
+#include "theory/rewriterules/rr_trigger.h"
+#include "theory/theory_engine.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/uf/theory_uf_instantiator.h"
+#include "theory/rewriterules/rr_candidate_generator.h"
+#include "theory/uf/equality_engine.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::context;
+using namespace CVC4::theory;
+using namespace CVC4::theory::rrinst;
+
+//#define NESTED_PATTERN_SELECTION
+
+Trigger* Trigger::TrTrie::getTrigger2( std::vector< Node >& nodes ){
+  if( nodes.empty() ){
+    return d_tr;
+  }else{
+    Node n = nodes.back();
+    nodes.pop_back();
+    if( d_children.find( n )!=d_children.end() ){
+      return d_children[n]->getTrigger2( nodes );
+    }else{
+      return NULL;
+    }
+  }
+}
+void Trigger::TrTrie::addTrigger2( std::vector< Node >& nodes, Trigger* t ){
+  if( nodes.empty() ){
+    d_tr = t;
+  }else{
+    Node n = nodes.back();
+    nodes.pop_back();
+    if( d_children.find( n )==d_children.end() ){
+      d_children[n] = new TrTrie;
+    }
+    d_children[n]->addTrigger2( nodes, t );
+  }
+}
+
+/** trigger static members */
+std::map< Node, std::vector< Node > > Trigger::d_var_contains;
+int Trigger::trCount = 0;
+Trigger::TrTrie Trigger::d_tr_trie;
+
+/** trigger class constructor */
+Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool smartTriggers ) :
+d_quantEngine( qe ), d_f( f ){
+  trCount++;
+  d_nodes.insert( d_nodes.begin(), nodes.begin(), nodes.end() );
+  Debug("trigger") << "Trigger for " << f << ": " << d_nodes << std::endl;
+  if(matchOption == MATCH_GEN_DEFAULT) d_mg = mkPatterns( d_nodes, qe );
+  else d_mg = mkPatternsEfficient( d_nodes, qe );
+  if( d_nodes.size()==1 ){
+    if( isSimpleTrigger( d_nodes[0] ) ){
+      ++(qe->d_statistics.d_triggers);
+    }else{
+      ++(qe->d_statistics.d_simple_triggers);
+    }
+  }else{
+    Debug("multi-trigger") << "Multi-trigger " << (*this) << std::endl;
+    //std::cout << "Multi-trigger for " << f << " : " << std::endl;
+    //std::cout << "   " << (*this) << std::endl;
+    ++(qe->d_statistics.d_multi_triggers);
+  }
+}
+void Trigger::computeVarContains( Node n ) {
+  if( d_var_contains.find( n )==d_var_contains.end() ){
+    d_var_contains[n].clear();
+    computeVarContains2( n, n );
+  }
+}
+
+void Trigger::computeVarContains2( Node n, Node parent ){
+  if( n.getKind()==INST_CONSTANT ){
+    if( std::find( d_var_contains[parent].begin(), d_var_contains[parent].end(), n )==d_var_contains[parent].end() ){
+      d_var_contains[parent].push_back( n );
+    }
+  }else{
+    for( int i=0; i<(int)n.getNumChildren(); i++ ){
+      computeVarContains2( n[i], parent );
+    }
+  }
+}
+
+void Trigger::resetInstantiationRound(){
+  d_mg->resetInstantiationRound( d_quantEngine );
+}
+
+
+bool Trigger::getNextMatch(){
+  bool retVal = d_mg->getNextMatch( d_quantEngine );
+  //m.makeInternal( d_quantEngine->getEqualityQuery() );
+  return retVal;
+}
+
+// bool Trigger::getMatch( Node t, InstMatch& m ){
+//   //FIXME: this assumes d_mg is an inst match generator
+//   return ((InstMatchGenerator*)d_mg)->getMatch( t, m, d_quantEngine );
+// }
+
+
+int Trigger::addInstantiations( InstMatch& baseMatch ){
+  int addedLemmas = d_mg->addInstantiations( baseMatch,
+                                             d_nodes[0].getAttribute(InstConstantAttribute()),
+                                             d_quantEngine);
+  if( addedLemmas>0 ){
+    Debug("inst-trigger") << "Added " << addedLemmas << " lemmas, trigger was ";
+    for( int i=0; i<(int)d_nodes.size(); i++ ){
+      Debug("inst-trigger") << d_nodes[i] << " ";
+    }
+    Debug("inst-trigger") << std::endl;
+  }
+  return addedLemmas;
+}
+
+Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool keepAll, int trOption,
+                             bool smartTriggers ){
+  std::vector< Node > trNodes;
+  if( !keepAll ){
+    //only take nodes that contribute variables to the trigger when added
+    std::vector< Node > temp;
+    temp.insert( temp.begin(), nodes.begin(), nodes.end() );
+    std::map< Node, bool > vars;
+    std::map< Node, std::vector< Node > > patterns;
+    for( int i=0; i<(int)temp.size(); i++ ){
+      bool foundVar = false;
+      computeVarContains( temp[i] );
+      for( int j=0; j<(int)d_var_contains[ temp[i] ].size(); j++ ){
+        Node v = d_var_contains[ temp[i] ][j];
+        if( v.getAttribute(InstConstantAttribute())==f ){
+          if( vars.find( v )==vars.end() ){
+            vars[ v ] = true;
+            foundVar = true;
+          }
+        }
+      }
+      if( foundVar ){
+        trNodes.push_back( temp[i] );
+        for( int j=0; j<(int)d_var_contains[ temp[i] ].size(); j++ ){
+          Node v = d_var_contains[ temp[i] ][j];
+          patterns[ v ].push_back( temp[i] );
+        }
+      }
+    }
+    //now, minimalize the trigger
+    for( int i=0; i<(int)trNodes.size(); i++ ){
+      bool keepPattern = false;
+      Node n = trNodes[i];
+      for( int j=0; j<(int)d_var_contains[ n ].size(); j++ ){
+        Node v = d_var_contains[ n ][j];
+        if( patterns[v].size()==1 ){
+          keepPattern = true;
+          break;
+        }
+      }
+      if( !keepPattern ){
+        //remove from pattern vector
+        for( int j=0; j<(int)d_var_contains[ n ].size(); j++ ){
+          Node v = d_var_contains[ n ][j];
+          for( int k=0; k<(int)patterns[v].size(); k++ ){
+            if( patterns[v][k]==n ){
+              patterns[v].erase( patterns[v].begin() + k, patterns[v].begin() + k + 1 );
+              break;
+            }
+          }
+        }
+        //remove from trigger nodes
+        trNodes.erase( trNodes.begin() + i, trNodes.begin() + i + 1 );
+        i--;
+      }
+    }
+  }else{
+    trNodes.insert( trNodes.begin(), nodes.begin(), nodes.end() );
+  }
+
+  //check for duplicate?
+  if( trOption==TR_MAKE_NEW ){
+    //static int trNew = 0;
+    //static int trOld = 0;
+    //Trigger* t = d_tr_trie.getTrigger( trNodes );
+    //if( t ){
+    //  trOld++;
+    //}else{
+    //  trNew++;
+    //}
+    //if( (trNew+trOld)%100==0 ){
+    //  std::cout << "Trigger new old = " << trNew << " " << trOld << std::endl;
+    //}
+  }else{
+    Trigger* t = d_tr_trie.getTrigger( trNodes );
+    if( t ){
+      if( trOption==TR_GET_OLD ){
+        //just return old trigger
+        return t;
+      }else{
+        return NULL;
+      }
+    }
+  }
+  Trigger* t = new Trigger( qe, f, trNodes, matchOption, smartTriggers );
+  d_tr_trie.addTrigger( trNodes, t );
+  return t;
+}
+Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, Node n, int matchOption, bool keepAll, int trOption, bool smartTriggers ){
+  std::vector< Node > nodes;
+  nodes.push_back( n );
+  return mkTrigger( qe, f, nodes, matchOption, keepAll, trOption, smartTriggers );
+}
+
+bool Trigger::isUsableTrigger( std::vector< Node >& nodes, Node f ){
+  for( int i=0; i<(int)nodes.size(); i++ ){
+    if( !isUsableTrigger( nodes[i], f ) ){
+      return false;
+    }
+  }
+  return true;
+}
+
+bool Trigger::isUsable( Node n, Node f ){
+  if( n.getAttribute(InstConstantAttribute())==f ){
+    if( !isAtomicTrigger( n ) && n.getKind()!=INST_CONSTANT ){
+      std::map< Node, Node > coeffs;
+      return getPatternArithmetic( f, n, coeffs );
+    }else{
+      for( int i=0; i<(int)n.getNumChildren(); i++ ){
+        if( !isUsable( n[i], f ) ){
+          return false;
+        }
+      }
+      return true;
+    }
+  }else{
+    return true;
+  }
+}
+
+bool Trigger::isSimpleTrigger( Node n ){
+  if( isAtomicTrigger( n ) ){
+    for( int i=0; i<(int)n.getNumChildren(); i++ ){
+      if( n[i].getKind()!=INST_CONSTANT && n[i].hasAttribute(InstConstantAttribute()) ){
+        return false;
+      }
+    }
+    return true;
+  }else{
+    return false;
+  }
+}
+
+/** filter all nodes that have instances */
+void Trigger::filterInstances( std::vector< Node >& nodes ){
+  std::vector< bool > active;
+  active.resize( nodes.size(), true );
+  for( int i=0; i<(int)nodes.size(); i++ ){
+    for( int j=i+1; j<(int)nodes.size(); j++ ){
+      if( active[i] && active[j] ){
+        int result = isInstanceOf( nodes[i], nodes[j] );
+        if( result==1 ){
+          active[j] = false;
+        }else if( result==-1 ){
+          active[i] = false;
+        }
+      }
+    }
+  }
+  std::vector< Node > temp;
+  for( int i=0; i<(int)nodes.size(); i++ ){
+    if( active[i] ){
+      temp.push_back( nodes[i] );
+    }
+  }
+  nodes.clear();
+  nodes.insert( nodes.begin(), temp.begin(), temp.end() );
+}
+
+
+bool Trigger::collectPatTerms2( QuantifiersEngine* qe, Node f, Node n, std::map< Node, bool >& patMap, int tstrt ){
+  if( patMap.find( n )==patMap.end() ){
+    patMap[ n ] = false;
+    if( tstrt==TS_MIN_TRIGGER ){
+      if( n.getKind()==FORALL ){
+#ifdef NESTED_PATTERN_SELECTION
+        //return collectPatTerms2( qe, f, qe->getOrCreateCounterexampleBody( n ), patMap, tstrt );
+        return collectPatTerms2( qe, f, qe->getBoundBody( n ), patMap, tstrt );
+#else
+        return false;
+#endif
+      }else{
+        bool retVal = false;
+        for( int i=0; i<(int)n.getNumChildren(); i++ ){
+          if( collectPatTerms2( qe, f, n[i], patMap, tstrt ) ){
+            retVal = true;
+          }
+        }
+        if( retVal ){
+          return true;
+        }else if( isUsableTrigger( n, f ) ){
+          patMap[ n ] = true;
+          return true;
+        }else{
+          return false;
+        }
+      }
+    }else{
+      bool retVal = false;
+      if( isUsableTrigger( n, f ) ){
+        patMap[ n ] = true;
+        if( tstrt==TS_MAX_TRIGGER ){
+          return true;
+        }else{
+          retVal = true;
+        }
+      }
+      if( n.getKind()==FORALL ){
+#ifdef NESTED_PATTERN_SELECTION
+        //if( collectPatTerms2( qe, f, qe->getOrCreateCounterexampleBody( n ), patMap, tstrt ) ){
+        //  retVal = true;
+        //}
+        if( collectPatTerms2( qe, f, qe->getBoundBody( n ), patMap, tstrt ) ){
+          retVal = true;
+        }
+#endif
+      }else{
+        for( int i=0; i<(int)n.getNumChildren(); i++ ){
+          if( collectPatTerms2( qe, f, n[i], patMap, tstrt ) ){
+            retVal = true;
+          }
+        }
+      }
+      return retVal;
+    }
+  }else{
+    return patMap[ n ];
+  }
+}
+
+void Trigger::collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, bool filterInst ){
+  std::map< Node, bool > patMap;
+  if( filterInst ){
+    //immediately do not consider any term t for which another term is an instance of t
+    std::vector< Node > patTerms2;
+    collectPatTerms( qe, f, n, patTerms2, TS_ALL, false );
+    std::vector< Node > temp;
+    temp.insert( temp.begin(), patTerms2.begin(), patTerms2.end() );
+    filterInstances( temp );
+    if( temp.size()!=patTerms2.size() ){
+      Debug("trigger-filter-instance") << "Filtered an instance: " << std::endl;
+      Debug("trigger-filter-instance") << "Old: ";
+      for( int i=0; i<(int)patTerms2.size(); i++ ){
+        Debug("trigger-filter-instance") << patTerms2[i] << " ";
+      }
+      Debug("trigger-filter-instance") << std::endl << "New: ";
+      for( int i=0; i<(int)temp.size(); i++ ){
+        Debug("trigger-filter-instance") << temp[i] << " ";
+      }
+      Debug("trigger-filter-instance") << std::endl;
+    }
+    if( tstrt==TS_ALL ){
+      patTerms.insert( patTerms.begin(), temp.begin(), temp.end() );
+      return;
+    }else{
+      //do not consider terms that have instances
+      for( int i=0; i<(int)patTerms2.size(); i++ ){
+        if( std::find( temp.begin(), temp.end(), patTerms2[i] )==temp.end() ){
+          patMap[ patTerms2[i] ] = false;
+        }
+      }
+    }
+  }
+  collectPatTerms2( qe, f, n, patMap, tstrt );
+  for( std::map< Node, bool >::iterator it = patMap.begin(); it != patMap.end(); ++it ){
+    if( it->second ){
+      patTerms.push_back( it->first );
+    }
+  }
+}
+
+/** is n1 an instance of n2 or vice versa? */
+int Trigger::isInstanceOf( Node n1, Node n2 ){
+  if( n1==n2 ){
+    return 1;
+  }else if( n1.getKind()==n2.getKind() ){
+    if( n1.getKind()==APPLY_UF ){
+      if( n1.getOperator()==n2.getOperator() ){
+        int result = 0;
+        for( int i=0; i<(int)n1.getNumChildren(); i++ ){
+          if( n1[i]!=n2[i] ){
+            int cResult = isInstanceOf( n1[i], n2[i] );
+            if( cResult==0 ){
+              return 0;
+            }else if( cResult!=result ){
+              if( result!=0 ){
+                return 0;
+              }else{
+                result = cResult;
+              }
+            }
+          }
+        }
+        return result;
+      }
+    }
+    return 0;
+  }else if( n2.getKind()==INST_CONSTANT ){
+    computeVarContains( n1 );
+    //if( std::find( d_var_contains[ n1 ].begin(), d_var_contains[ n1 ].end(), n2 )!=d_var_contains[ n1 ].end() ){
+    //  return 1;
+    //}
+    if( d_var_contains[ n1 ].size()==1 && d_var_contains[ n1 ][ 0 ]==n2 ){
+      return 1;
+    }
+  }else if( n1.getKind()==INST_CONSTANT ){
+    computeVarContains( n2 );
+    //if( std::find( d_var_contains[ n2 ].begin(), d_var_contains[ n2 ].end(), n1 )!=d_var_contains[ n2 ].end() ){
+    //  return -1;
+    //}
+    if( d_var_contains[ n2 ].size()==1 && d_var_contains[ n2 ][ 0 ]==n1 ){
+      return 1;
+    }
+  }
+  return 0;
+}
+
+bool Trigger::isVariableSubsume( Node n1, Node n2 ){
+  if( n1==n2 ){
+    return true;
+  }else{
+    //std::cout << "is variable subsume ? " << n1 << " " << n2 << std::endl;
+    computeVarContains( n1 );
+    computeVarContains( n2 );
+    for( int i=0; i<(int)d_var_contains[n2].size(); i++ ){
+      if( std::find( d_var_contains[n1].begin(), d_var_contains[n1].end(), d_var_contains[n2][i] )==d_var_contains[n1].end() ){
+        //std::cout << "no" << std::endl;
+        return false;
+      }
+    }
+    //std::cout << "yes" << std::endl;
+    return true;
+  }
+}
+
+void Trigger::getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains ){
+  for( int i=0; i<(int)pats.size(); i++ ){
+    computeVarContains( pats[i] );
+    varContains[ pats[i] ].clear();
+    for( int j=0; j<(int)d_var_contains[pats[i]].size(); j++ ){
+      if( d_var_contains[pats[i]][j].getAttribute(InstConstantAttribute())==f ){
+        varContains[ pats[i] ].push_back( d_var_contains[pats[i]][j] );
+      }
+    }
+  }
+}
+
+void Trigger::getVarContainsNode( Node f, Node n, std::vector< Node >& varContains ){
+  computeVarContains( n );
+  for( int j=0; j<(int)d_var_contains[n].size(); j++ ){
+    if( d_var_contains[n][j].getAttribute(InstConstantAttribute())==f ){
+      varContains.push_back( d_var_contains[n][j] );
+    }
+  }
+}
+
+bool Trigger::getPatternArithmetic( Node f, Node n, std::map< Node, Node >& coeffs ){
+  if( n.getKind()==PLUS ){
+    Assert( coeffs.empty() );
+    NodeBuilder<> t(kind::PLUS);
+    for( int i=0; i<(int)n.getNumChildren(); i++ ){
+      if( n[i].hasAttribute(InstConstantAttribute()) ){
+        if( n[i].getKind()==INST_CONSTANT ){
+          if( n[i].getAttribute(InstConstantAttribute())==f ){
+            coeffs[ n[i] ] = Node::null();
+          }else{
+            coeffs.clear();
+            return false;
+          }
+        }else if( !getPatternArithmetic( f, n[i], coeffs ) ){
+          coeffs.clear();
+          return false;
+        }
+      }else{
+        t << n[i];
+      }
+    }
+    if( t.getNumChildren()==0 ){
+      coeffs[ Node::null() ] = NodeManager::currentNM()->mkConst( Rational(0) );
+    }else if( t.getNumChildren()==1 ){
+      coeffs[ Node::null() ]  = t.getChild( 0 );
+    }else{
+      coeffs[ Node::null() ]  = t;
+    }
+    return true;
+  }else if( n.getKind()==MULT ){
+    if( n[0].getKind()==INST_CONSTANT && n[0].getAttribute(InstConstantAttribute())==f ){
+      Assert( !n[1].hasAttribute(InstConstantAttribute()) );
+      coeffs[ n[0] ] = n[1];
+      return true;
+    }else if( n[1].getKind()==INST_CONSTANT && n[1].getAttribute(InstConstantAttribute())==f ){
+      Assert( !n[0].hasAttribute(InstConstantAttribute()) );
+      coeffs[ n[1] ] = n[0];
+      return true;
+    }
+  }
+  return false;
+}
diff --git a/src/theory/rewriterules/rr_trigger.h b/src/theory/rewriterules/rr_trigger.h
new file mode 100644 (file)
index 0000000..096fbdb
--- /dev/null
@@ -0,0 +1,176 @@
+/*********************                                                        */
+/*! \file rr_trigger.h
+ ** \verbatim
+ ** Original author: ajreynol
+ ** Major contributors: bobot
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief trigger class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__REWRITERULES__RR_TRIGGER_H
+#define __CVC4__THEORY__REWRITERULES__RR_TRIGGER_H
+
+#include "theory/rewriterules/rr_inst_match.h"
+
+namespace CVC4 {
+namespace theory {
+namespace rrinst {
+
+//a collect of nodes representing a trigger
+class Trigger {
+public:
+  static int trCount;
+private:
+  /** computation of variable contains */
+  static std::map< Node, std::vector< Node > > d_var_contains;
+  static void computeVarContains( Node n );
+  static void computeVarContains2( Node n, Node parent );
+private:
+  /** the quantifiers engine */
+  QuantifiersEngine* d_quantEngine;
+  /** the quantifier this trigger is for */
+  Node d_f;
+  /** match generators */
+  PatsMatcher * d_mg;
+private:
+  /** a trie of triggers */
+  class TrTrie
+  {
+  private:
+    Trigger* getTrigger2( std::vector< Node >& nodes );
+    void addTrigger2( std::vector< Node >& nodes, Trigger* t );
+  public:
+    TrTrie() : d_tr( NULL ){}
+    Trigger* d_tr;
+    std::map< Node, TrTrie* > d_children;
+    Trigger* getTrigger( std::vector< Node >& nodes ){
+      std::vector< Node > temp;
+      temp.insert( temp.begin(), nodes.begin(), nodes.end() );
+      std::sort( temp.begin(), temp.end() );
+      return getTrigger2( temp );
+    }
+    void addTrigger( std::vector< Node >& nodes, Trigger* t ){
+      std::vector< Node > temp;
+      temp.insert( temp.begin(), nodes.begin(), nodes.end() );
+      std::sort( temp.begin(), temp.end() );
+      return addTrigger2( temp, t );
+    }
+  };
+  /** all triggers will be stored in this trie */
+  static TrTrie d_tr_trie;
+private:
+  /** trigger constructor */
+  Trigger( QuantifiersEngine* ie, Node f, std::vector< Node >& nodes, int matchOption = 0, bool smartTriggers = false );
+public:
+  ~Trigger(){}
+public:
+  std::vector< Node > d_nodes;
+public:
+  void debugPrint( const char* c );
+  PatsMatcher* getGenerator() { return d_mg; }
+public:
+  /** reset instantiation round (call this whenever equivalence classes have changed) */
+  void resetInstantiationRound();
+  /** get next match.  must call reset( eqc ) once before this function. */
+  bool getNextMatch();
+  const InstMatch & getInstMatch(){return d_mg->getInstMatch();};
+  /** return whether this is a multi-trigger */
+  bool isMultiTrigger() { return d_nodes.size()>1; }
+public:
+  /** add all available instantiations exhaustively, in any equivalence class
+      if limitInst>0, limitInst is the max # of instantiations to try */
+  int addInstantiations( InstMatch& baseMatch);
+  /** mkTrigger method
+     ie     : quantifier engine;
+     f      : forall something ....
+     nodes  : (multi-)trigger
+     matchOption : which policy to use for creating matches (one of InstMatchGenerator::MATCH_GEN_* )
+     keepAll: don't remove unneeded patterns;
+     trOption : policy for dealing with triggers that already existed (see below)
+  */
+  enum {
+    //options for producing matches
+    MATCH_GEN_DEFAULT = 0,
+    MATCH_GEN_EFFICIENT_E_MATCH,   //generate matches via Efficient E
+  };
+  enum{
+    TR_MAKE_NEW,    //make new trigger even if it already may exist
+    TR_GET_OLD,     //return a previous trigger if it had already been created
+    TR_RETURN_NULL  //return null if a duplicate is found
+  };
+  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes,
+                             int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
+                             bool smartTriggers = false );
+  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, Node n,
+                             int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
+                             bool smartTriggers = false );
+private:
+  /** is subterm of trigger usable */
+  static bool isUsable( Node n, Node f );
+  /** collect all APPLY_UF pattern terms for f in n */
+  static bool collectPatTerms2( QuantifiersEngine* qe, Node f, Node n, std::map< Node, bool >& patMap, int tstrt );
+public:
+  //different strategies for choosing trigger terms
+  enum {
+    TS_MAX_TRIGGER = 0,
+    TS_MIN_TRIGGER,
+    TS_ALL,
+  };
+  static void collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, bool filterInst = false );
+public:
+  /** is usable trigger */
+  static inline bool isUsableTrigger( TNode n, TNode f ){
+    //return n.getAttribute(InstConstantAttribute())==f && n.getKind()==APPLY_UF;
+    return n.getAttribute(InstConstantAttribute())==f && isAtomicTrigger( n ) && isUsable( n, f );
+  }
+  static inline bool isAtomicTrigger( TNode n ){
+    return
+      n.getKind()==kind::APPLY_UF ||
+      n.getKind()==kind::SELECT ||
+      n.getKind()==kind::STORE;
+  }
+  static bool isUsableTrigger( std::vector< Node >& nodes, Node f );
+  static bool isSimpleTrigger( Node n );
+  /** filter all nodes that have instances */
+  static void filterInstances( std::vector< Node >& nodes );
+  /** -1: n1 is an instance of n2, 1: n1 is an instance of n2 */
+  static int isInstanceOf( Node n1, Node n2 );
+  /** variables subsume, return true if n1 contains all free variables in n2 */
+  static bool isVariableSubsume( Node n1, Node n2 );
+  /** get var contains */
+  static void getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains );
+  static void getVarContainsNode( Node f, Node n, std::vector< Node >& varContains );
+  /** get pattern arithmetic */
+  static bool getPatternArithmetic( Node f, Node n, std::map< Node, Node >& coeffs );
+
+  inline void toStream(std::ostream& out) const {
+    out << "TRIGGER( ";
+    for( int i=0; i<(int)d_nodes.size(); i++ ){
+      if( i>0 ){ out << ", "; }
+      out << d_nodes[i];
+    }
+    out << " )";
+  }
+};
+
+inline std::ostream& operator<<(std::ostream& out, const Trigger & tr) {
+  tr.toStream(out);
+  return out;
+}
+
+}/* CVC4::theory::rrinst namespace */
+
+}/* CVC4::theory namespace */
+
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__REWRITERULES__RR_TRIGGER_H */
index fcbdfe8b9f8e7c745fad0fdcece5cc85bec23f02..bb5537474a6632bcee81b817dc9addb63ca9bb2f 100644 (file)
@@ -27,9 +27,9 @@
 #include "theory/theory_engine.h"
 #include "theory/quantifiers_engine.h"
 #include "context/context_mm.h"
-#include "theory/rr_inst_match_impl.h"
-#include "theory/rr_trigger.h"
-#include "theory/rr_inst_match.h"
+#include "theory/rewriterules/rr_inst_match_impl.h"
+#include "theory/rewriterules/rr_trigger.h"
+#include "theory/rewriterules/rr_inst_match.h"
 #include "util/stats.h"
 #include "theory/rewriterules/theory_rewriterules_preprocess.h"
 #include "theory/model.h"
diff --git a/src/theory/rr_candidate_generator.cpp b/src/theory/rr_candidate_generator.cpp
deleted file mode 100644 (file)
index a2e895c..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*********************                                                        */
-/*! \file rr_candidate_generator.cpp
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: bobot
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Implementation of rr candidate generator class
- **/
-
-#include "theory/rr_candidate_generator.h"
-#include "theory/theory_engine.h"
-#include "theory/uf/theory_uf.h"
-#include "theory/quantifiers/term_database.h"
-
-using namespace std;
-using namespace CVC4;
-using namespace CVC4::kind;
-using namespace CVC4::context;
-using namespace CVC4::theory;
-using namespace CVC4::theory::rrinst;
-
-GenericCandidateGeneratorClasses::GenericCandidateGeneratorClasses(QuantifiersEngine * qe){
-  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
-    if(qe->getInstantiator(i) != NULL)
-      d_can_gen[i] = qe->getInstantiator(i)->getRRCanGenClasses();
-    else d_can_gen[i] = NULL;
-  }
-}
-
-GenericCandidateGeneratorClasses::~GenericCandidateGeneratorClasses(){
-  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
-    delete(d_can_gen[i]);
-  }
-}
-
-void GenericCandidateGeneratorClasses::resetInstantiationRound(){
-  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
-    if(d_can_gen[i] != NULL) d_can_gen[i]->resetInstantiationRound();
-  }
-  d_can_gen_id=THEORY_FIRST;
-}
-
-void GenericCandidateGeneratorClasses::reset(TNode eqc){
-  Assert(eqc.isNull());
-  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
-    if(d_can_gen[i] != NULL) d_can_gen[i]->reset(eqc);
-  }
-  d_can_gen_id=THEORY_FIRST;
-  lookForNextTheory();
-}
-
-TNode GenericCandidateGeneratorClasses::getNextCandidate(){
-  Assert(THEORY_FIRST <= d_can_gen_id && d_can_gen_id <= THEORY_LAST);
-  /** No more */
-  if(d_can_gen_id == THEORY_LAST) return TNode::null();
-  /** Try with this theory */
-  TNode cand = d_can_gen[d_can_gen_id]->getNextCandidate();
-  if( !cand.isNull() ) return cand;
-  lookForNextTheory();
-  return getNextCandidate();
-}
-
-void GenericCandidateGeneratorClasses::lookForNextTheory(){
-  do{ /* look for the next available generator */
-    ++d_can_gen_id;
-  } while( d_can_gen_id < THEORY_LAST && d_can_gen[d_can_gen_id] == NULL);
-}
-
-GenericCandidateGeneratorClass::GenericCandidateGeneratorClass(QuantifiersEngine * qe): d_qe(qe) {
-  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
-    if(d_qe->getInstantiator(i) != NULL)
-      d_can_gen[i] = d_qe->getInstantiator(i)->getRRCanGenClass();
-    else d_can_gen[i] = NULL;
-  }
-}
-
-GenericCandidateGeneratorClass::~GenericCandidateGeneratorClass(){
-  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
-    delete(d_can_gen[i]);
-  }
-}
-
-void GenericCandidateGeneratorClass::resetInstantiationRound(){
-  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
-    if(d_can_gen[i] != NULL) d_can_gen[i]->resetInstantiationRound();
-  }
-  d_can_gen_id=THEORY_FIRST;
-}
-
-void GenericCandidateGeneratorClass::reset(TNode eqc){
-  for(TheoryId i = THEORY_FIRST; i < theory::THEORY_LAST; ++i){
-    if(d_can_gen[i] != NULL) d_can_gen[i]->reset(eqc);
-  }
-  d_can_gen_id=THEORY_FIRST;
-  d_node = eqc;
-  lookForNextTheory();
-}
-
-TNode GenericCandidateGeneratorClass::getNextCandidate(){
-  Assert(THEORY_FIRST <= d_can_gen_id && d_can_gen_id <= THEORY_LAST);
-  /** No more */
-  if(d_can_gen_id == THEORY_LAST) return TNode::null();
-  /** Try with this theory */
-  TNode cand = d_can_gen[d_can_gen_id]->getNextCandidate();
-  if( !cand.isNull() ) return cand;
-  lookForNextTheory();
-  return getNextCandidate();
-}
-
-void GenericCandidateGeneratorClass::lookForNextTheory(){
-  do{ /* look for the next available generator, where the element is */
-    ++d_can_gen_id;
-  } while(
-          d_can_gen_id < THEORY_LAST &&
-          (d_can_gen[d_can_gen_id] == NULL ||
-           !d_qe->getInstantiator( d_can_gen_id )->hasTerm( d_node ))
-          );
-}
diff --git a/src/theory/rr_candidate_generator.h b/src/theory/rr_candidate_generator.h
deleted file mode 100644 (file)
index 30f6c06..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*********************                                                        */
-/*! \file rr_candidate_generator.h
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: bobot
- ** Minor contributors (to current version): mdeters
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief rr candidate generator
- **/
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__THEORY_UF_CANDIDATE_GENERATOR_H
-#define __CVC4__THEORY_UF_CANDIDATE_GENERATOR_H
-
-#include "theory/quantifiers_engine.h"
-#include "theory/quantifiers/term_database.h"
-#include "theory/rr_inst_match.h"
-
-using namespace CVC4::theory::quantifiers;
-
-namespace CVC4 {
-namespace theory {
-namespace eq {
-
-namespace rrinst{
-typedef CVC4::theory::rrinst::CandidateGenerator CandidateGenerator;
-
-//New CandidateGenerator. They have a simpler semantic than the old one
-
-// Just iterate amoung the equivalence classes
-// node::Null() must be given to reset
-class CandidateGeneratorTheoryEeClasses : public CandidateGenerator{
-private:
-  //the equality classes iterator
-  eq::EqClassesIterator d_eq;
-  //equalityengine pointer
-  EqualityEngine* d_ee;
-public:
-  CandidateGeneratorTheoryEeClasses( EqualityEngine * ee): d_ee( ee ){}
-  ~CandidateGeneratorTheoryEeClasses(){}
-  void resetInstantiationRound(){};
-  void reset( TNode eqc ){
-    Assert(eqc.isNull());
-    d_eq = eq::EqClassesIterator( d_ee );
-  }; //* the argument is not used
-  TNode getNextCandidate(){
-    if( !d_eq.isFinished() ) return (*(d_eq++));
-    else return Node::null();
-  };
-};
-
-// Just iterate amoung the equivalence class of the given node
-// node::Null() *can't* be given to reset
-class CandidateGeneratorTheoryEeClass : public CandidateGenerator{
-private:
-  //instantiator pointer
-  EqualityEngine* d_ee;
-  //the equality class iterator
-  eq::EqClassIterator d_eqc;
-  /* For the case where the given term doesn't exists in uf */
-  Node d_retNode;
-public:
-  CandidateGeneratorTheoryEeClass( EqualityEngine* ee): d_ee( ee ){}
-  ~CandidateGeneratorTheoryEeClass(){}
-  void resetInstantiationRound(){};
-  void reset( TNode eqc ){
-    Assert(!eqc.isNull());
-    if( d_ee->hasTerm( eqc ) ){
-      /* eqc is in uf  */
-      eqc = d_ee->getRepresentative( eqc );
-      d_eqc = eq::EqClassIterator( eqc, d_ee );
-      d_retNode = Node::null();
-    }else{
-      /* If eqc if not a term known by uf, it is the only one in its
-         equivalence class. So we will return only it */
-      d_retNode = eqc;
-      d_eqc = eq::EqClassIterator();
-    }
-  }; //* the argument is not used
-  TNode getNextCandidate(){
-    if(d_retNode.isNull()){
-      if( !d_eqc.isFinished() ) return (*(d_eqc++));
-      else return Node::null();
-    }else{
-      /* the case where eqc not in uf */
-      Node ret = d_retNode;
-      d_retNode = Node::null(); /* d_eqc.isFinished() must be true */
-      return ret;
-    }
-  };
-};
-
-
-} /* namespace rrinst */
-} /* namespace eq */
-
-namespace uf{
-namespace rrinst {
-
-typedef CVC4::theory::rrinst::CandidateGenerator CandidateGenerator;
-
-class CandidateGeneratorTheoryUfOp : public CandidateGenerator{
-private:
-  Node d_op;
-  //instantiator pointer
-  TermDb* d_tdb;
-  // Since new term can appears we restrict ourself to the one that
-  // exists at resetInstantiationRound
-  size_t d_term_iter_limit;
-  size_t d_term_iter;
-public:
-  CandidateGeneratorTheoryUfOp(Node op, TermDb* tdb): d_op(op), d_tdb( tdb ){}
-  ~CandidateGeneratorTheoryUfOp(){}
-  void resetInstantiationRound(){
-    d_term_iter_limit = d_tdb->d_op_map[d_op].size();
-  };
-  void reset( TNode eqc ){
-    Assert(eqc.isNull());
-    d_term_iter = 0;
-  }; //* the argument is not used
-  TNode getNextCandidate(){
-    if( d_term_iter<d_term_iter_limit ){
-      TNode n = d_tdb->d_op_map[d_op][d_term_iter];
-      ++d_term_iter;
-      return n;
-    } else return Node::null();
-  };
-};
-
-class CandidateGeneratorTheoryUfType : public CandidateGenerator{
-private:
-  TypeNode d_type;
-  //instantiator pointer
-  TermDb* d_tdb;
-  // Since new term can appears we restrict ourself to the one that
-  // exists at resetInstantiationRound
-  size_t d_term_iter_limit;
-  size_t d_term_iter;
-public:
-  CandidateGeneratorTheoryUfType(TypeNode type, TermDb* tdb): d_type(type), d_tdb( tdb ){}
-  ~CandidateGeneratorTheoryUfType(){}
-  void resetInstantiationRound(){
-    d_term_iter_limit = d_tdb->d_type_map[d_type].size();
-  };
-  void reset( TNode eqc ){
-    Assert(eqc.isNull());
-    d_term_iter = 0;
-  }; //* the argument is not used
-  TNode getNextCandidate(){
-    if( d_term_iter<d_term_iter_limit ){
-      TNode n = d_tdb->d_type_map[d_type][d_term_iter];
-      ++d_term_iter;
-      return n;
-    } else return Node::null();
-  };
-};
-
-} /* namespace rrinst */
-} /* namespace uf */
-
-class GenericCandidateGeneratorClasses: public rrinst::CandidateGenerator{
-
-  /** The candidate generators */
-  rrinst::CandidateGenerator* d_can_gen[theory::THEORY_LAST];
-  /** The current theory which candidategenerator is used */
-  TheoryId d_can_gen_id;
-
-public:
-  GenericCandidateGeneratorClasses(QuantifiersEngine * qe);
-  ~GenericCandidateGeneratorClasses();
-
-  void resetInstantiationRound();
-  void reset(TNode eqc);
-  TNode getNextCandidate();
-  void lookForNextTheory();
-};
-
-class GenericCandidateGeneratorClass: public rrinst::CandidateGenerator{
-
-  /** The candidate generators */
-  rrinst::CandidateGenerator* d_can_gen[theory::THEORY_LAST];
-  /** The current theory which candidategenerator is used */
-  TheoryId d_can_gen_id;
-  /** current node to look for equivalence class */
-  Node d_node;
-  /** QuantifierEngine */
-  QuantifiersEngine* d_qe;
-
-public:
-  GenericCandidateGeneratorClass(QuantifiersEngine * qe);
-  ~GenericCandidateGeneratorClass();
-  void resetInstantiationRound();
-
-  void reset(TNode eqc);
-  TNode getNextCandidate();
-  void lookForNextTheory();
-};
-
-}/* CVC4::theory namespace */
-}/* CVC4 namespace */
-
-#endif /* __CVC4__THEORY_UF_INSTANTIATOR_H */
diff --git a/src/theory/rr_inst_match.cpp b/src/theory/rr_inst_match.cpp
deleted file mode 100644 (file)
index 0e3e7b9..0000000
+++ /dev/null
@@ -1,1447 +0,0 @@
-/*********************                                                        */
-/*! \file rr_inst_match.cpp
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: bobot
- ** Minor contributors (to current version): mdeters
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Implementation of inst match class
- **/
-
-#include "theory/inst_match.h"
-#include "theory/theory_engine.h"
-#include "theory/quantifiers_engine.h"
-#include "theory/uf/theory_uf_instantiator.h"
-#include "theory/uf/equality_engine.h"
-#include "theory/arrays/theory_arrays.h"
-#include "theory/datatypes/theory_datatypes.h"
-#include "theory/rr_inst_match.h"
-#include "theory/rr_trigger.h"
-#include "theory/rr_inst_match_impl.h"
-#include "theory/rr_candidate_generator.h"
-
-using namespace CVC4;
-using namespace CVC4::kind;
-using namespace CVC4::context;
-using namespace CVC4::theory;
-using namespace CVC4::theory::rrinst;
-using namespace CVC4::theory::uf::rrinst;
-using namespace CVC4::theory::eq::rrinst;
-
-namespace CVC4{
-namespace theory{
-namespace rrinst{
-
-typedef CVC4::theory::inst::InstMatch InstMatch;
-typedef CVC4::theory::inst::CandidateGeneratorQueue CandidateGeneratorQueue;
-
-template<bool modEq>
-class InstMatchTrie2Pairs
-{
-  typename std::vector< std::vector < typename InstMatchTrie2Gen<modEq>::Tree > > d_data;
-  InstMatchTrie2Gen<modEq> d_backtrack;
-public:
-  InstMatchTrie2Pairs(context::Context* c,  QuantifiersEngine* q, size_t n):
-  d_backtrack(c,q) {
-    // resize to a triangle
-    //
-    // |     *
-    // |   * *
-    // | * * *
-    // | -----> i
-    d_data.resize(n);
-    for(size_t i=0; i < n; ++i){
-      d_data[i].resize(i+1,typename InstMatchTrie2Gen<modEq>::Tree(0));
-    }
-  };
-  InstMatchTrie2Pairs(const InstMatchTrie2Pairs &) CVC4_UNDEFINED;
-  const InstMatchTrie2Pairs & operator =(const InstMatchTrie2Pairs & e) CVC4_UNDEFINED;
-  /** add match m in the trie,
-      return true if it was never seen */
-  inline bool addInstMatch( size_t i, size_t j, InstMatch& m){
-    size_t k = std::min(i,j);
-    size_t l = std::max(i,j);
-    return d_backtrack.addInstMatch(m,&(d_data[l][k]));
-  };
-  inline bool addInstMatch( size_t i, InstMatch& m){
-    return d_backtrack.addInstMatch(m,&(d_data[i][i]));
-  };
-
-};
-
-
-// Currently the implementation doesn't take into account that
-// variable should have the same value given.
-// TODO use the d_children way perhaps
-// TODO replace by a real dictionnary
-// We should create a real substitution? slower more precise
-// We don't do that often
-bool nonunifiable( TNode t0, TNode pat, const std::vector<Node> & vars){
-  if(pat.isNull()) return true;
-
-  typedef std::vector<std::pair<TNode,TNode> > tstack;
-  tstack stack(1,std::make_pair(t0,pat)); // t * pat
-
-  while(!stack.empty()){
-    const std::pair<TNode,TNode> p = stack.back(); stack.pop_back();
-    const TNode & t = p.first;
-    const TNode & pat = p.second;
-
-    // t or pat is a variable currently we consider that can match anything
-    if( find(vars.begin(),vars.end(),t) != vars.end() ) continue;
-    if( pat.getKind() == INST_CONSTANT ) continue;
-
-    // t and pat are nonunifiable
-    if( !Trigger::isAtomicTrigger( t ) || !Trigger::isAtomicTrigger( pat ) ) {
-      if(t == pat) continue;
-      else return true;
-    };
-    if( t.getOperator() != pat.getOperator() ) return true;
-
-    //put the children on the stack
-    for( size_t i=0; i < pat.getNumChildren(); i++ ){
-      stack.push_back(std::make_pair(t[i],pat[i]));
-    };
-  }
-  // The heuristic can't find non-unifiability
-  return false;
-};
-
-/** New things */
-class DumbMatcher: public Matcher{
-  void resetInstantiationRound( QuantifiersEngine* qe ){};
-  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe ){
-    return false;
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return false;
-  }
-};
-
-class DumbPatMatcher: public PatMatcher{
-  void resetInstantiationRound( QuantifiersEngine* qe ){};
-  bool reset( InstMatch& m, QuantifiersEngine* qe ){
-    return false;
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return false;
-  }
-};
-
-
-/* The order of the matching is:
-   reset arg1, nextMatch arg1, reset arg2, nextMatch arg2, ... */
-ApplyMatcher::ApplyMatcher( Node pat, QuantifiersEngine* qe): d_pattern(pat){
-  //  Assert( pat.hasAttribute(InstConstantAttribute()) );
-
-  //set-up d_variables, d_constants, d_childrens
-  for( size_t i=0; i< d_pattern.getNumChildren(); ++i ){
-    EqualityQuery* q = qe->getEqualityQuery(d_pattern[i].getType());
-    Assert( q != NULL );
-    if( d_pattern[i].hasAttribute(InstConstantAttribute()) ){
-      if( d_pattern[i].getKind()==INST_CONSTANT ){
-        //It's a variable
-        d_variables.push_back(make_triple((TNode)d_pattern[i],i,q));
-      }else{
-        //It's neither a constant argument neither a variable
-        //we create the matcher for the subpattern
-        d_childrens.push_back(make_triple(mkMatcher((TNode)d_pattern[i], qe),i,q));
-      };
-    }else{
-      // It's a constant
-      d_constants.push_back(make_triple((TNode)d_pattern[i],i,q));
-    }
-  }
-}
-
-void ApplyMatcher::resetInstantiationRound( QuantifiersEngine* qe ){
-  for( size_t i=0; i< d_childrens.size(); i++ ){
-    d_childrens[i].first->resetInstantiationRound( qe );
-  }
-}
-
-bool ApplyMatcher::reset(TNode t, InstMatch & m, QuantifiersEngine* qe){
-  Debug("matching") << "Matching " << t << " against pattern " << d_pattern << " ("
-                    << m.size() << ")"  << std::endl;
-
-  //if t is null
-  Assert( !t.isNull() );
-  Assert( !t.hasAttribute(InstConstantAttribute()) );
-  Assert( t.getKind()==d_pattern.getKind() );
-  Assert( (t.getKind()!=APPLY_UF && t.getKind()!=APPLY_CONSTRUCTOR)
-          || t.getOperator()==d_pattern.getOperator() );
-
-  typedef std::vector< triple<TNode,size_t,EqualityQuery*> >::iterator iterator;
-  for(iterator i = d_constants.begin(), end = d_constants.end();
-      i != end; ++i){
-    if( !i->third->areEqual( i->first, t[i->second] ) ){
-      Debug("matching-fail") << "Match fail arg: " << i->first << " and " << t[i->second] << std::endl;
-      //setMatchFail( qe, d_pattern[i], t[i] );
-      //ground arguments are not equal
-      return false;
-    }
-  }
-
-  d_binded.clear();
-  bool set;
-  for(iterator i = d_variables.begin(), end = d_variables.end();
-      i != end; ++i){
-    if( !m.setMatch( i->third, i->first, t[i->second], set) ){
-      //match is in conflict
-      Debug("matching-debug") << "Match in conflict " << t[i->second] << " and "
-                              << i->first << " because "
-                              << m.get(i->first)
-                              << std::endl;
-      Debug("matching-fail") << "Match fail: " << m.get(i->first) << " and " << t[i->second] << std::endl;
-      //setMatchFail( qe, partial[0].d_map[d_pattern[i]], t[i] );
-      m.erase(d_binded.begin(), d_binded.end());
-      return false;
-    }else{
-      if(set){ //The variable has just been set
-        d_binded.push_back(i->first);
-      }
-    }
-  }
-
-  //now, fit children into match
-  //we will be requesting candidates for matching terms for each child
-  d_reps.clear();
-  for( size_t i=0; i< d_childrens.size(); i++ ){
-    Debug("matching-debug") << "Take the representative of " << t[ d_childrens[i].second ] << std::endl;
-    Assert( d_childrens[i].third->hasTerm(t[ d_childrens[i].second ]) );
-    Node rep = d_childrens[i].third->getRepresentative( t[ d_childrens[i].second ] );
-    d_reps.push_back( rep );
-  }
-
-  if(d_childrens.size() == 0) return true;
-  else return getNextMatch(m, qe, true);
-}
-
-bool ApplyMatcher::getNextMatch(InstMatch& m, QuantifiersEngine* qe, bool reset){
-  Assert(d_childrens.size() > 0);
-  const size_t max = d_childrens.size() - 1;
-  size_t index = reset ? 0 : max;
-  Assert(d_childrens.size() == d_reps.size());
-  while(true){
-    if(reset ?
-       d_childrens[index].first->reset( d_reps[index], m, qe ) :
-       d_childrens[index].first->getNextMatch( m, qe )){
-      if(index==max) return true;
-      ++index;
-      reset=true;
-    }else{
-      if(index==0){
-        m.erase(d_binded.begin(), d_binded.end());
-        return false;
-      }
-      --index;
-      reset=false;
-    };
-  }
-}
-
-bool ApplyMatcher::getNextMatch(InstMatch& m, QuantifiersEngine* qe){
-  if(d_childrens.size() == 0){
-    m.erase(d_binded.begin(), d_binded.end());
-    return false;
-  } else return getNextMatch(m, qe, false);
-}
-
-/** Proxy that call the sub-matcher on the result return by the given candidate generator */
-template <class CG, class M>
-class CandidateGeneratorMatcher: public Matcher{
-  /** candidate generator */
-  CG d_cg;
-  /** the sub-matcher */
-  M d_m;
-public:
-  CandidateGeneratorMatcher(CG cg, M m): d_cg(cg), d_m(m)
-  {/* last is Null */};
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cg.resetInstantiationRound();
-    d_m.resetInstantiationRound(qe);
-  };
-  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe ){
-    d_cg.reset(n);
-    return findMatch(m,qe);
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    // The sub-matcher has another match
-    return d_m.getNextMatch(m, qe) || findMatch(m,qe);
-  }
-private:
-  bool findMatch( InstMatch& m, QuantifiersEngine* qe ){
-    // Otherwise try to find a new candidate that has at least one match
-    while(true){
-      TNode n = d_cg.getNextCandidate();//kept somewhere Term-db
-      Debug("matching") << "GenCand " << n << " (" << this << ")" << std::endl;
-      if(n.isNull()) return false;
-      if(d_m.reset(n,m,qe)) return true;
-    };
-  }
-};
-
-/** Proxy that call the sub-matcher on the result return by the given candidate generator */
-template<class M>
-class PatOfMatcher: public PatMatcher{
-  M d_m;
-public:
-  inline PatOfMatcher(M m): d_m(m){}
-  void resetInstantiationRound(QuantifiersEngine* qe){
-    d_m.resetInstantiationRound(qe);
-  }
-  bool reset(InstMatch& m, QuantifiersEngine* qe){
-    return d_m.reset(Node::null(),m,qe);
-  };
-  bool getNextMatch(InstMatch& m, QuantifiersEngine* qe){
-    return d_m.getNextMatch(m,qe);
-  };
-};
-
-class ArithMatcher: public Matcher{
-private:
-  /** for arithmetic matching */
-  std::map< Node, Node > d_arith_coeffs;
-  /** get the match against ground term or formula t.
-      d_match_mattern and t should have the same shape.
-      only valid for use where !d_match_pattern.isNull().
-  */
-  /** the variable that are set by this matcher */
-  std::vector< TNode > d_binded; /* TNode because the variables are already in d_arith_coeffs */
-  Node d_pattern; //for debugging
-public:
-  ArithMatcher(Node pat, QuantifiersEngine* qe);
-  void resetInstantiationRound( QuantifiersEngine* qe ){};
-  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe );
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe );
-};
-
-/** Match just a variable */
-class VarMatcher: public Matcher{
-  Node d_var;
-  bool d_binded; /* True if the reset bind the variable to some value */
-  EqualityQuery* d_q;
-public:
-  VarMatcher(Node var, QuantifiersEngine* qe): d_var(var), d_binded(false){
-    d_q = qe->getEqualityQuery(var.getType());
-  }
-  void resetInstantiationRound( QuantifiersEngine* qe ){};
-  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe ){
-    if(!m.setMatch( d_q, d_var, n, d_binded )){
-      //match is in conflict
-      Debug("matching-fail") << "Match fail: " << m.get(d_var)
-                             << " and " << n << std::endl;
-      return false;
-    } else return true;
-  };
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    //match is in conflict
-    if (d_binded) m.erase(d_var);
-    return false;
-  }
-};
-
-template <class M, class Test >
-class TestMatcher: public Matcher{
-  M d_m;
-  Test d_test;
-public:
-  inline TestMatcher(M m, Test test): d_m(m), d_test(test){}
-  inline void resetInstantiationRound(QuantifiersEngine* qe){
-    d_m.resetInstantiationRound(qe);
-  }
-  inline bool reset(TNode n, InstMatch& m, QuantifiersEngine* qe){
-    return d_test(n) && d_m.reset(n, m, qe);
-  }
-  inline bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_m.getNextMatch(m, qe);
-  }
-};
-
-class LegalOpTest/*: public unary_function<TNode,bool>*/ {
-  Node d_op;
-public:
-  inline LegalOpTest(Node op): d_op(op){}
-  inline bool operator() (TNode n) {
-    return
-      CandidateGenerator::isLegalCandidate(n) &&
-      // ( // n.getKind()==SELECT || n.getKind()==STORE ||
-      //  n.getKind()==APPLY_UF || n.getKind()==APPLY_CONSTRUCTOR) &&
-      n.hasOperator() &&
-      n.getOperator()==d_op;
-  };
-};
-
-class LegalKindTest/* : public unary_function<TNode,bool>*/ {
-  Kind d_kind;
-public:
-  inline LegalKindTest(Kind kind): d_kind(kind){}
-  inline bool operator() (TNode n) {
-    return
-      CandidateGenerator::isLegalCandidate(n) &&
-      n.getKind()==d_kind;
-  };
-};
-
-class LegalTypeTest/* : public unary_function<TNode,bool>*/ {
-  TypeNode d_type;
-public:
-  inline LegalTypeTest(TypeNode type): d_type(type){}
-  inline bool operator() (TNode n) {
-    return
-      CandidateGenerator::isLegalCandidate(n) &&
-      n.getType()==d_type;
-  };
-};
-
-class LegalTest/* : public unary_function<TNode,bool>*/ {
-public:
-  inline bool operator() (TNode n) {
-    return CandidateGenerator::isLegalCandidate(n);
-  };
-};
-
-size_t numFreeVar(TNode t){
-  size_t n = 0;
-  for( size_t i=0, size =t.getNumChildren(); i < size; ++i ){
-    if( t[i].hasAttribute(InstConstantAttribute()) ){
-      if( t[i].getKind()==INST_CONSTANT ){
-        //variable
-        ++n;
-      }else{
-        //neither variable nor constant
-        n += numFreeVar(t[i]);
-      }
-    }
-  }
-  return n;
-}
-
-class OpMatcher: public Matcher{
-  /* The matcher */
-  typedef ApplyMatcher AuxMatcher3;
-  typedef TestMatcher< AuxMatcher3, LegalOpTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass, AuxMatcher2> AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
-    Assert( pat.getKind() == kind::APPLY_UF );
-    /** In reverse order of matcher sequence */
-    AuxMatcher3 am3(pat,qe);
-    /** Keep only the one that have the good operator */
-    AuxMatcher2 am2(am3,LegalOpTest(pat.getOperator()));
-    /** Iter on the equivalence class of the given term */
-    uf::TheoryUF* uf = static_cast<uf::TheoryUF *>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF ));
-    eq::EqualityEngine* ee = static_cast<eq::EqualityEngine*>(uf->getEqualityEngine());
-    CandidateGeneratorTheoryEeClass cdtUfEq(ee);
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(cdtUfEq,am2);
-    return am1;
-  }
-  size_t d_num_var;
-  Node d_pat;
-public:
-  OpMatcher( Node pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)),d_num_var(numFreeVar(pat)),
-    d_pat(pat) {}
-
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
-    // size_t m_size = m.d_map.size();
-    // if(m_size == d_num_var){
-    //   uf::EqualityEngine<uf::TheoryUF::NotifyClass>* ee = (static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF )))->getEqualityEngine();
-    //   std::cout << "!";
-    //   return ee->areEqual(m.subst(d_pat),t);
-    // }else{
-    // std::cout << m.d_map.size() << std::endl;
-    return d_cgm.reset(t, m, qe);
-    // }
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-class DatatypesMatcher: public Matcher{
-  /* The matcher */
-  typedef ApplyMatcher AuxMatcher3;
-  typedef TestMatcher< AuxMatcher3, LegalOpTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass, AuxMatcher2> AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
-    Assert( pat.getKind() == kind::APPLY_CONSTRUCTOR,
-            "For datatypes only constructor are accepted in pattern" );
-    /** In reverse order of matcher sequence */
-    AuxMatcher3 am3(pat,qe);
-    /** Keep only the one that have the good operator */
-    AuxMatcher2 am2(am3,LegalOpTest(pat.getOperator()));
-    /** Iter on the equivalence class of the given term */
-    datatypes::TheoryDatatypes* dt = static_cast<datatypes::TheoryDatatypes *>(qe->getTheoryEngine()->getTheory( theory::THEORY_DATATYPES ));
-    eq::EqualityEngine* ee = static_cast<eq::EqualityEngine*>(dt->getEqualityEngine());
-    CandidateGeneratorTheoryEeClass cdtDtEq(ee);
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(cdtDtEq,am2);
-    return am1;
-  }
-  Node d_pat;
-public:
-  DatatypesMatcher( Node pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)),
-    d_pat(pat) {}
-
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
-    Debug("matching") << "datatypes: " << t << " matches " << d_pat << std::endl;
-    return d_cgm.reset(t, m, qe);
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-class ArrayMatcher: public Matcher{
-  /* The matcher */
-  typedef ApplyMatcher AuxMatcher3;
-  typedef TestMatcher< AuxMatcher3, LegalKindTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass, AuxMatcher2> AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
-    Assert( pat.getKind() == kind::SELECT || pat.getKind() == kind::STORE );
-    /** In reverse order of matcher sequence */
-    AuxMatcher3 am3(pat,qe);
-    /** Keep only the one that have the good operator */
-    AuxMatcher2 am2(am3, LegalKindTest(pat.getKind()));
-    /** Iter on the equivalence class of the given term */
-    arrays::TheoryArrays* ar = static_cast<arrays::TheoryArrays *>(qe->getTheoryEngine()->getTheory( theory::THEORY_ARRAY ));
-    eq::EqualityEngine* ee =
-      static_cast<eq::EqualityEngine*>(ar->getEqualityEngine());
-    CandidateGeneratorTheoryEeClass cdtUfEq(ee);
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(cdtUfEq,am2);
-    return am1;
-  }
-  size_t d_num_var;
-  Node d_pat;
-public:
-  ArrayMatcher( Node pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)),d_num_var(numFreeVar(pat)),
-    d_pat(pat) {}
-
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
-    // size_t m_size = m.d_map.size();
-    // if(m_size == d_num_var){
-    //   uf::EqualityEngine<uf::TheoryUF::NotifyClass>* ee = (static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF )))->getEqualityEngine();
-    //   std::cout << "!";
-    //   return ee->areEqual(m.subst(d_pat),t);
-    // }else{
-    // std::cout << m.d_map.size() << std::endl;
-    return d_cgm.reset(t, m, qe);
-    // }
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-class AllOpMatcher: public PatMatcher{
-  /* The matcher */
-  typedef ApplyMatcher AuxMatcher3;
-  typedef TestMatcher< AuxMatcher3, LegalTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryUfOp, AuxMatcher2> AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
-    Assert( pat.hasOperator() );
-    /** In reverse order of matcher sequence */
-    AuxMatcher3 am3(pat,qe);
-    /** Keep only the one that have the good operator */
-    AuxMatcher2 am2(am3,LegalTest());
-    /** Iter on the equivalence class of the given term */
-    TermDb* tdb = qe->getTermDatabase();
-    CandidateGeneratorTheoryUfOp cdtUfEq(pat.getOperator(),tdb);
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(cdtUfEq,am2);
-    return am1;
-  }
-  size_t d_num_var;
-  Node d_pat;
-public:
-  AllOpMatcher( TNode pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)), d_num_var(numFreeVar(pat)),
-    d_pat(pat) {}
-
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( InstMatch& m, QuantifiersEngine* qe ){
-    //    std::cout << m.d_map.size() << "/" << d_num_var << std::endl;
-    return d_cgm.reset(Node::null(), m, qe);
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-template <bool classes> /** true classes | false class */
-class GenericCandidateGeneratorClasses: public CandidateGenerator{
-private:
-  CandidateGenerator* d_cg;
-  QuantifiersEngine* d_qe;
-
-public:
-  void mkCandidateGenerator(){
-    if(classes)
-      d_cg = d_qe->getRRCanGenClasses();
-    else
-     d_cg = d_qe->getRRCanGenClass();
-  }
-
-  GenericCandidateGeneratorClasses(QuantifiersEngine* qe):
-    d_qe(qe) {
-    mkCandidateGenerator();
-  }
-  ~GenericCandidateGeneratorClasses(){
-    delete(d_cg);
-  }
-  const GenericCandidateGeneratorClasses & operator =(const GenericCandidateGeneratorClasses & m){
-    mkCandidateGenerator();
-    return m;
-  };
-  GenericCandidateGeneratorClasses(const GenericCandidateGeneratorClasses & m):
-  d_qe(m.d_qe){
-    mkCandidateGenerator();
-  }
-  void resetInstantiationRound(){
-    d_cg->resetInstantiationRound();
-  };
-  void reset( TNode eqc ){
-    Assert( !classes || eqc.isNull() );
-    d_cg->reset(eqc);
-  }; //* the argument is not used
-  TNode getNextCandidate(){
-    return d_cg->getNextCandidate();
-  };
-}; /* MetaCandidateGeneratorClasses */
-
-
-class GenericMatcher: public Matcher{
-  /* The matcher */
-  typedef ApplyMatcher AuxMatcher3;
-  typedef TestMatcher< AuxMatcher3, LegalOpTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< GenericCandidateGeneratorClasses<false>, AuxMatcher2> AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
-    /** In reverse order of matcher sequence */
-    AuxMatcher3 am3(pat,qe);
-    /** Keep only the one that have the good operator */
-    AuxMatcher2 am2(am3,LegalOpTest(pat.getOperator()));
-    /** Iter on the equivalence class of the given term */
-    GenericCandidateGeneratorClasses<false> cdtG(qe);
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(cdtG,am2);
-    return am1;
-  }
-  Node d_pat;
-public:
-  GenericMatcher( Node pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)),
-    d_pat(pat) {}
-
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.reset(t, m, qe);
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-
-class GenericPatMatcher: public PatMatcher{
-  /* The matcher */
-  typedef ApplyMatcher AuxMatcher3;
-  typedef TestMatcher< AuxMatcher3, LegalOpTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< GenericCandidateGeneratorClasses<true>, AuxMatcher2> AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
-    /** In reverse order of matcher sequence */
-    AuxMatcher3 am3(pat,qe);
-    /** Keep only the one that have the good operator */
-    AuxMatcher2 am2(am3,LegalOpTest(pat.getOperator()));
-    /** Iter on the equivalence class of the given term */
-    GenericCandidateGeneratorClasses<true> cdtG(qe);
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(cdtG,am2);
-    return am1;
-  }
-  Node d_pat;
-public:
-  GenericPatMatcher( Node pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)),
-    d_pat(pat) {}
-
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.reset(Node::null(), m, qe);
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-class MetaCandidateGeneratorClasses: public CandidateGenerator{
-private:
-  CandidateGenerator* d_cg;
-  TypeNode d_ty;
-  TheoryEngine* d_te;
-
-public:
-  CandidateGenerator* mkCandidateGenerator(TypeNode ty, TheoryEngine* te){
-    Debug("inst-match-gen") << "MetaCandidateGenerator for type: " << ty
-                            << " Theory : " << Theory::theoryOf(ty) << std::endl;
-    if( Theory::theoryOf(ty) == theory::THEORY_DATATYPES ){
-      // datatypes::TheoryDatatypes* dt = static_cast<datatypes::TheoryDatatypes *>(te->getTheory( theory::THEORY_DATATYPES ));
-      // return new datatypes::rrinst::CandidateGeneratorTheoryClasses(dt);
-      Unimplemented("MetaCandidateGeneratorClasses for THEORY_DATATYPES");
-    }else if ( Theory::theoryOf(ty) == theory::THEORY_ARRAY ){
-      arrays::TheoryArrays* ar = static_cast<arrays::TheoryArrays *>(te->getTheory( theory::THEORY_ARRAY ));
-      eq::EqualityEngine* ee =
-        static_cast<eq::EqualityEngine*>(ar->getEqualityEngine());
-      return new CandidateGeneratorTheoryEeClasses(ee);
-    } else {
-      uf::TheoryUF* uf = static_cast<uf::TheoryUF*>(te->getTheory( theory::THEORY_UF ));
-      eq::EqualityEngine* ee =
-        static_cast<eq::EqualityEngine*>(uf->getEqualityEngine());
-      return new CandidateGeneratorTheoryEeClasses(ee);
-    }
-  }
-  MetaCandidateGeneratorClasses(TypeNode ty, TheoryEngine* te):
-    d_ty(ty), d_te(te) {
-    d_cg = mkCandidateGenerator(ty,te);
-  }
-  ~MetaCandidateGeneratorClasses(){
-    delete(d_cg);
-  }
-  const MetaCandidateGeneratorClasses & operator =(const MetaCandidateGeneratorClasses & m){
-    d_cg = mkCandidateGenerator(m.d_ty, m.d_te);
-    return m;
-  };
-  MetaCandidateGeneratorClasses(const MetaCandidateGeneratorClasses & m):
-  d_ty(m.d_ty), d_te(m.d_te){
-    d_cg = mkCandidateGenerator(m.d_ty, m.d_te);
-  }
-  void resetInstantiationRound(){
-    d_cg->resetInstantiationRound();
-  };
-  void reset( TNode eqc ){
-    d_cg->reset(eqc);
-  }; //* the argument is not used
-  TNode getNextCandidate(){
-    return d_cg->getNextCandidate();
-  };
-}; /* MetaCandidateGeneratorClasses */
-
-/** Match just a variable */
-class AllVarMatcher: public PatMatcher{
-private:
-  /* generator */
-  typedef VarMatcher AuxMatcher3;
-  typedef TestMatcher< AuxMatcher3, LegalTypeTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< MetaCandidateGeneratorClasses, AuxMatcher2 > AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  static inline AuxMatcher1 createCgm(TNode pat, QuantifiersEngine* qe){
-    Assert( pat.getKind()==INST_CONSTANT );
-    TypeNode ty = pat.getType();
-    Debug("inst-match-gen") << "create AllVarMatcher for type: " << ty << std::endl;
-    /** In reverse order of matcher sequence */
-    /** Distribute it to all the pattern */
-    AuxMatcher3 am3(pat,qe);
-    /** Keep only the one that have the good type */
-    AuxMatcher2 am2(am3,LegalTypeTest(ty));
-    /** Generate one term by eq classes */
-    MetaCandidateGeneratorClasses mcdt(ty,qe->getTheoryEngine());
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(mcdt,am2);
-    return am1;
-  }
-public:
-  AllVarMatcher( TNode pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)){}
-
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.reset(Node::null(), m, qe); //cdtUfEq doesn't use it's argument for reset
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-/** Match all the pattern with the same term */
-class SplitMatcher: public Matcher{
-private:
-  const size_t size;
-  ApplyMatcher d_m; /** Use ApplyMatcher by creating a fake application */
-public:
-  SplitMatcher(std::vector< Node > pats, QuantifiersEngine* qe):
-    size(pats.size()),
-    d_m(NodeManager::currentNM()->mkNode(kind::INST_PATTERN,pats), qe) {}
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_m.resetInstantiationRound(qe);
-  };
-  bool reset( TNode ex, InstMatch& m, QuantifiersEngine* qe ){
-    NodeBuilder<> n(kind::INST_PATTERN);
-    for(size_t i = 0; i < size; ++i) n << ex;
-    Node nn = n;
-    return d_m.reset(nn,m,qe);
-  };
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return getNextMatch(m, qe);
-  }
-};
-
-
-/** Match uf term in a fixed equivalence class */
-class UfCstEqMatcher: public PatMatcher{
-private:
-  /* equivalence class to match */
-  Node d_cst;
-  /* generator */
-  OpMatcher d_cgm;
-public:
-  UfCstEqMatcher( Node pat, Node cst, QuantifiersEngine* qe ):
-    d_cst(cst),
-    d_cgm(OpMatcher(pat,qe)) {};
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.reset(d_cst, m, qe);
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-/** Match equalities */
-class UfEqMatcher: public PatMatcher{
-private:
-  /* generator */
-  typedef SplitMatcher AuxMatcher3;
-  typedef TestMatcher< AuxMatcher3, LegalTypeTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClasses, AuxMatcher2 > AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  static inline AuxMatcher1 createCgm(std::vector<Node> & pat, QuantifiersEngine* qe){
-    Assert( pat.size() > 0);
-    TypeNode ty = pat[0].getType();
-    for(size_t i = 1; i < pat.size(); ++i){
-      Assert(pat[i].getType() == ty);
-    }
-    /** In reverse order of matcher sequence */
-    /** Distribute it to all the pattern */
-    AuxMatcher3 am3(pat,qe);
-    /** Keep only the one that have the good type */
-    AuxMatcher2 am2(am3,LegalTypeTest(ty));
-    /** Generate one term by eq classes */
-    uf::TheoryUF* uf = static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF ));
-    eq::EqualityEngine* ee =
-      static_cast<eq::EqualityEngine*>(uf->getEqualityEngine());
-    CandidateGeneratorTheoryEeClasses cdtUfEq(ee);
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(cdtUfEq,am2);
-    return am1;
-  }
-public:
-  UfEqMatcher( std::vector<Node> & pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)){}
-
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.reset(Node::null(), m, qe); //cdtUfEq doesn't use it's argument for reset
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-
-/** Match dis-equalities */
-class UfDeqMatcher: public PatMatcher{
-private:
-  /* generator */
-  typedef ApplyMatcher AuxMatcher3;
-
-  class EqTest/* : public unary_function<Node,bool>*/ {
-    TypeNode d_type;
-  public:
-    inline EqTest(TypeNode type): d_type(type){};
-    inline bool operator() (Node n) {
-      return
-        CandidateGenerator::isLegalCandidate(n) &&
-        n.getKind() == kind::EQUAL &&
-        n[0].getType()==d_type;
-    };
-  };
-  typedef TestMatcher< AuxMatcher3, EqTest > AuxMatcher2;
-  typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass, AuxMatcher2 > AuxMatcher1;
-  AuxMatcher1 d_cgm;
-  Node false_term;
-  static inline AuxMatcher1 createCgm(Node pat, QuantifiersEngine* qe){
-    Assert( pat.getKind() == kind::NOT);
-    TNode eq = pat[0];
-    Assert( eq.getKind() == kind::EQUAL);
-    TypeNode ty = eq[0].getType();
-    /** In reverse order of matcher sequence */
-    /** Distribute it to all the pattern */
-    AuxMatcher3 am3(eq,qe);
-    /** Keep only the one that have the good type */
-    AuxMatcher2 am2(am3,EqTest(ty));
-    /** Will generate all the terms of the eq class of false */
-    uf::TheoryUF* uf = static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF ));
-    eq::EqualityEngine* ee =
-      static_cast<eq::EqualityEngine*>(uf->getEqualityEngine());
-    CandidateGeneratorTheoryEeClass cdtUfEq(ee);
-    /* Create a matcher from the candidate generator */
-    AuxMatcher1 am1(cdtUfEq,am2);
-    return am1;
-  }
-public:
-  UfDeqMatcher( Node pat, QuantifiersEngine* qe ):
-    d_cgm(createCgm(pat, qe)),
-    false_term((static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF )))->getEqualityEngine()->
-                getRepresentative(NodeManager::currentNM()->mkConst<bool>(false) )){};
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    d_cgm.resetInstantiationRound(qe);
-  };
-  bool reset( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.reset(false_term, m, qe);
-  }
-  bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-    return d_cgm.getNextMatch(m, qe);
-  }
-};
-
-Matcher* mkMatcher( Node pat, QuantifiersEngine* qe ){
-  Debug("inst-match-gen") << "mkMatcher: Pattern term is " << pat << std::endl;
-
-  // if( pat.getKind() == kind::APPLY_UF){
-  //   return new OpMatcher(pat, qe);
-  // } else if( pat.getKind() == kind::APPLY_CONSTRUCTOR ){
-  //   return new DatatypesMatcher(pat, qe);
-  // } else if( pat.getKind() == kind::SELECT || pat.getKind() == kind::STORE ){
-  //   return new ArrayMatcher(pat, qe);
-  if( pat.getKind() == kind::APPLY_UF ||
-      pat.getKind() == kind::APPLY_CONSTRUCTOR ||
-      pat.getKind() == kind::SELECT || pat.getKind() == kind::STORE ){
-    return new GenericMatcher(pat, qe);
-  } else { /* Arithmetic? */
-    /** TODO: something simpler to see if the pattern is a good
-        arithmetic pattern */
-    std::map< Node, Node > d_arith_coeffs;
-    if( !Trigger::getPatternArithmetic( pat.getAttribute(InstConstantAttribute()), pat, d_arith_coeffs ) ){
-      Message() << "(?) Unknown matching pattern is " << pat << std::endl;
-      Unimplemented("pattern not implemented");
-      return new DumbMatcher();
-    }else{
-      Debug("matching-arith") << "Generated arithmetic pattern for " << pat << ": " << std::endl;
-      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
-        Debug("matching-arith") << "   " << it->first << " -> " << it->second << std::endl;
-      }
-      ArithMatcher am3 (pat, qe);
-      TestMatcher<ArithMatcher, LegalTypeTest>
-        am2(am3,LegalTypeTest(pat.getType()));
-      /* generator */
-      uf::TheoryUF* uf = static_cast<uf::TheoryUF*>(qe->getTheoryEngine()->getTheory( theory::THEORY_UF ));
-      eq::EqualityEngine* ee =
-        static_cast<eq::EqualityEngine*> (uf->getEqualityEngine());
-      CandidateGeneratorTheoryEeClass cdtUfEq(ee);
-      return new CandidateGeneratorMatcher< CandidateGeneratorTheoryEeClass,
-        TestMatcher<ArithMatcher, LegalTypeTest> > (cdtUfEq,am2);
-    }
-  }
-};
-
-PatMatcher* mkPattern( Node pat, QuantifiersEngine* qe ){
-  Debug("inst-match-gen") << "Pattern term is " << pat << std::endl;
-  Assert( pat.hasAttribute(InstConstantAttribute()) );
-
-  if( pat.getKind()==kind::NOT && pat[0].getKind() == kind::EQUAL){
-    /* Difference */
-    return new UfDeqMatcher(pat, qe);
-  } else if (pat.getKind() == kind::EQUAL){
-    if( !pat[0].hasAttribute(InstConstantAttribute() )){
-        Assert(pat[1].hasAttribute(InstConstantAttribute()));
-        return new UfCstEqMatcher(pat[1], pat[0], qe);
-    }else if( !pat[1].hasAttribute(InstConstantAttribute() )){
-      Assert(pat[0].hasAttribute(InstConstantAttribute()));
-      return new UfCstEqMatcher(pat[0], pat[1], qe);
-    }else{
-      std::vector< Node > pats(pat.begin(),pat.end());
-      return new UfEqMatcher(pats,qe);
-    }
-  } else if( Trigger::isAtomicTrigger( pat ) ){
-    return new AllOpMatcher(pat, qe);
-    // return new GenericPatMatcher(pat, qe);
-  } else if( pat.getKind()==INST_CONSTANT ){
-    // just a variable
-    return new AllVarMatcher(pat, qe);
-  } else { /* Arithmetic? */
-    /** TODO: something simpler to see if the pattern is a good
-        arithmetic pattern */
-    std::map< Node, Node > d_arith_coeffs;
-    if( !Trigger::getPatternArithmetic( pat.getAttribute(InstConstantAttribute()), pat, d_arith_coeffs ) ){
-      Debug("inst-match-gen") << "(?) Unknown matching pattern is " << pat << std::endl;
-      Message() << "(?) Unknown matching pattern is " << pat << std::endl;
-      return new DumbPatMatcher();
-    }else{
-      Debug("matching-arith") << "Generated arithmetic pattern for " << pat << ": " << std::endl;
-      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
-        Debug("matching-arith") << "   " << it->first << " -> " << it->second << std::endl;
-      }
-      ArithMatcher am3 (pat, qe);
-      TestMatcher<ArithMatcher, LegalTest>
-        am2(am3,LegalTest());
-      /* generator */
-      TermDb* tdb = qe->getTermDatabase();
-      CandidateGeneratorTheoryUfType cdtUfEq(pat.getType(),tdb);
-      typedef CandidateGeneratorMatcher< CandidateGeneratorTheoryUfType,
-                                          TestMatcher<ArithMatcher, LegalTest> > AuxMatcher1;
-      return new PatOfMatcher<AuxMatcher1>(AuxMatcher1(cdtUfEq,am2));
-    }
-  }
-};
-
-ArithMatcher::ArithMatcher(Node pat, QuantifiersEngine* qe): d_pattern(pat){
-
-  if(Trigger::getPatternArithmetic(pat.getAttribute(InstConstantAttribute()), pat, d_arith_coeffs ) )
-    {
-    Debug("inst-match-gen") << "(?) Unknown matching pattern is " << d_pattern << std::endl;
-    Assert(false);
-  }else{
-    Debug("matching-arith") << "Generated arithmetic pattern for " << d_pattern << ": " << std::endl;
-    for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
-      Debug("matching-arith") << "   " << it->first << " -> " << it->second << std::endl;
-    }
-  }
-
-};
-
-bool ArithMatcher::reset( TNode t, InstMatch& m, QuantifiersEngine* qe ){
-  Debug("matching-arith") << "Matching " << t << " " << d_pattern << std::endl;
-  d_binded.clear();
-  if( !d_arith_coeffs.empty() ){
-    NodeBuilder<> tb(kind::PLUS);
-    Node ic = Node::null();
-    for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
-      Debug("matching-arith") << it->first << " -> " << it->second << std::endl;
-      if( !it->first.isNull() ){
-        if( m.find( it->first )==m.end() ){
-          //see if we can choose this to set
-          if( ic.isNull() && ( it->second.isNull() || !it->first.getType().isInteger() ) ){
-            ic = it->first;
-          }
-        }else{
-          Debug("matching-arith") << "already set " << m.get( it->first ) << std::endl;
-          Node tm = m.get( it->first );
-          if( !it->second.isNull() ){
-            tm = NodeManager::currentNM()->mkNode( MULT, it->second, tm );
-          }
-          tb << tm;
-        }
-      }else{
-        tb << it->second;
-      }
-    }
-    if( !ic.isNull() ){
-      Node tm;
-      if( tb.getNumChildren()==0 ){
-        tm = t;
-      }else{
-        tm = tb.getNumChildren()==1 ? tb.getChild( 0 ) : tb;
-        tm = NodeManager::currentNM()->mkNode( MINUS, t, tm );
-      }
-      if( !d_arith_coeffs[ ic ].isNull() ){
-        Assert( !ic.getType().isInteger() );
-        Node coeff = NodeManager::currentNM()->mkConst( Rational(1) / d_arith_coeffs[ ic ].getConst<Rational>() );
-        tm = NodeManager::currentNM()->mkNode( MULT, coeff, tm );
-      }
-      m.set( ic, Rewriter::rewrite( tm ));
-      d_binded.push_back(ic);
-      //set the rest to zeros
-      for( std::map< Node, Node >::iterator it = d_arith_coeffs.begin(); it != d_arith_coeffs.end(); ++it ){
-        if( !it->first.isNull() ){
-          if( m.find( it->first )==m.end() ){
-            m.set( it->first, NodeManager::currentNM()->mkConst( Rational(0) ));
-            d_binded.push_back(ic);
-          }
-        }
-      }
-      Debug("matching-arith") << "Setting " << ic << " to " << tm << std::endl;
-      return true;
-    }else{
-      m.erase(d_binded.begin(), d_binded.end());
-      return false;
-    }
-  }else{
-    m.erase(d_binded.begin(), d_binded.end());
-    return false;
-  }
-};
-
-bool ArithMatcher::getNextMatch( InstMatch& m, QuantifiersEngine* qe ){
-  m.erase(d_binded.begin(), d_binded.end());
-  return false;
-};
-
-
-class MultiPatsMatcher: public PatsMatcher{
-private:
-  bool d_reset_done;
-  std::vector< PatMatcher* > d_patterns;
-  InstMatch d_im;
-  bool reset( QuantifiersEngine* qe ){
-    d_im.clear();
-    d_reset_done = true;
-
-    return getNextMatch(qe,true);
-  };
-
-  bool getNextMatch(QuantifiersEngine* qe, bool reset){
-    const size_t max = d_patterns.size() - 1;
-    size_t index = reset ? 0 : max;
-    while(true){
-      Debug("matching") << "MultiPatsMatcher::index " << index << "/"
-                        << max << (reset ? " reset_phase" : "") << std::endl;
-      if(reset ?
-         d_patterns[index]->reset( d_im, qe ) :
-         d_patterns[index]->getNextMatch( d_im, qe )){
-        if(index==max) return true;
-        ++index;
-        reset=true;
-      }else{
-        if(index==0) return false;
-        --index;
-        reset=false;
-      };
-    }
-  }
-
-public:
-  MultiPatsMatcher(std::vector< Node > & pats, QuantifiersEngine* qe):
-    d_reset_done(false){
-    Assert(pats.size() > 0);
-    for( size_t i=0; i< pats.size(); i++ ){
-      d_patterns.push_back(mkPattern(pats[i],qe));
-    };
-  };
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    for( size_t i=0; i< d_patterns.size(); i++ ){
-      d_patterns[i]->resetInstantiationRound( qe );
-    };
-    d_reset_done = false;
-    d_im.clear();
-  };
-  bool getNextMatch( QuantifiersEngine* qe ){
-    Assert(d_patterns.size()>0);
-    if(d_reset_done) return getNextMatch(qe,false);
-    else return reset(qe);
-  }
-  const InstMatch& getInstMatch(){return d_im;};
-
-  int addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe);
-};
-
-enum EffiStep{
-  ES_STOP,
-  ES_GET_MONO_CANDIDATE,
-  ES_GET_MULTI_CANDIDATE,
-  ES_RESET1,
-  ES_RESET2,
-  ES_NEXT1,
-  ES_NEXT2,
-  ES_RESET_OTHER,
-  ES_NEXT_OTHER,
-};
-static inline std::ostream& operator<<(std::ostream& out, const EffiStep& step) {
-  switch(step){
-  case ES_STOP: out << "STOP"; break;
-  case ES_GET_MONO_CANDIDATE: out << "GET_MONO_CANDIDATE"; break;
-  case ES_GET_MULTI_CANDIDATE: out << "GET_MULTI_CANDIDATE"; break;
-  case ES_RESET1: out << "RESET1"; break;
-  case ES_RESET2: out << "RESET2"; break;
-  case ES_NEXT1: out << "NEXT1"; break;
-  case ES_NEXT2: out << "NEXT2"; break;
-  case ES_RESET_OTHER: out << "RESET_OTHER"; break;
-  case ES_NEXT_OTHER: out << "NEXT_OTHER"; break;
-  }
-  return out;
-}
-
-
-int MultiPatsMatcher::addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe){
-  //now, try to add instantiation for each match produced
-  int addedLemmas = 0;
-  resetInstantiationRound( qe );
-  d_im.add( baseMatch );
-  while( getNextMatch( qe ) ){
-    InstMatch im_copy = getInstMatch();
-    //m.makeInternal( d_quantEngine->getEqualityQuery() );
-    if( qe->addInstantiation( quant, im_copy ) ){
-      addedLemmas++;
-    }
-  }
-  //return number of lemmas added
-  return addedLemmas;
-}
-
-PatsMatcher* mkPatterns( std::vector< Node > pat, QuantifiersEngine* qe ){
-  return new MultiPatsMatcher( pat, qe);
-}
-
-class MultiEfficientPatsMatcher: public PatsMatcher{
-private:
-  bool d_phase_mono;
-  bool d_phase_new_term;
-  std::vector< PatMatcher* > d_patterns;
-  std::vector< Matcher* > d_direct_patterns;
-  InstMatch d_im;
-  uf::EfficientHandler d_eh;
-  uf::EfficientHandler::MultiCandidate d_mc;
-  InstMatchTrie2Pairs<true> d_cache;
-  std::vector<Node> d_pats;
-  // bool indexDone( size_t i){
-  //   return i == d_c.first.second ||
-  //     ( i == d_c.second.second && d_c.second.first.empty());
-  // }
-
-
-
-  static const EffiStep ES_START = ES_GET_MONO_CANDIDATE;
-  EffiStep d_step;
-
-  //return true if it becomes bigger than d_patterns.size() - 1
-  bool incrIndex(size_t & index){
-    if(index == d_patterns.size() - 1) return true;
-    ++index;
-    if(index == d_mc.first.second
-       || (!d_phase_mono && index == d_mc.second.second))
-      return incrIndex(index);
-    else return false;
-  }
-
-  //return true if it becomes smaller than 0
-  bool decrIndex(size_t & index){
-    if(index == 0) return true;
-    --index;
-    if(index == d_mc.first.second
-       || (!d_phase_mono && index == d_mc.second.second))
-      return decrIndex(index);
-    else return false;
-  }
-
-  bool resetOther( QuantifiersEngine* qe ){
-    return getNextMatchOther(qe,true);
-  };
-
-
-  bool getNextMatchOther(QuantifiersEngine* qe, bool reset){
-    size_t index = reset ? 0 : d_patterns.size();
-    if(!reset && decrIndex(index)) return false;
-    if( reset &&
-        (index == d_mc.first.second
-         || (!d_phase_mono && index == d_mc.second.second))
-        && incrIndex(index)) return true;
-    while(true){
-      Debug("matching") << "MultiEfficientPatsMatcher::index " << index << "/"
-                        << d_patterns.size() - 1 << std::endl;
-      if(reset ?
-         d_patterns[index]->reset( d_im, qe ) :
-         d_patterns[index]->getNextMatch( d_im, qe )){
-        if(incrIndex(index)) return true;
-        reset=true;
-      }else{
-        if(decrIndex(index)) return false;
-        reset=false;
-      };
-    }
-  }
-
-  inline EffiStep TestMonoCache(QuantifiersEngine* qe){
-    if( //!d_phase_new_term ||
-       d_pats.size() == 1) return ES_RESET_OTHER;
-    if(d_cache.addInstMatch(d_mc.first.second,d_im)){
-      Debug("inst-match::cache") << "Cache miss" << d_im << std::endl;
-      ++qe->d_statistics.d_mono_candidates_cache_miss;
-      return ES_RESET_OTHER;
-    } else {
-      Debug("inst-match::cache") << "Cache hit" << d_im << std::endl;
-      ++qe->d_statistics.d_mono_candidates_cache_hit;
-      return ES_NEXT1;
-    }
-    // ++qe->d_statistics.d_mono_candidates_cache_miss;
-    // return ES_RESET_OTHER;
-  }
-
-  inline EffiStep TestMultiCache(QuantifiersEngine* qe){
-    if(d_cache.addInstMatch(d_mc.first.second,d_mc.second.second,d_im)){
-      ++qe->d_statistics.d_multi_candidates_cache_miss;
-      return ES_RESET_OTHER;
-    } else {
-      ++qe->d_statistics.d_multi_candidates_cache_hit;
-      return ES_NEXT2;
-    }
-  }
-
-
-public:
-
-  bool getNextMatch( QuantifiersEngine* qe ){
-    Assert( d_step == ES_START || d_step == ES_NEXT_OTHER || d_step == ES_STOP );
-    while(true){
-      Debug("matching") << "d_step=" << d_step << " "
-                        << "d_im=" << d_im << std::endl;
-      switch(d_step){
-      case ES_GET_MONO_CANDIDATE:
-        Assert(d_im.empty());
-        if(d_phase_new_term ? d_eh.getNextMonoCandidate(d_mc.first) : d_eh.getNextMonoCandidateNewTerm(d_mc.first)){
-          if(d_phase_new_term) ++qe->d_statistics.d_num_mono_candidates_new_term;
-          else ++qe->d_statistics.d_num_mono_candidates;
-          d_phase_mono = true;
-          d_step = ES_RESET1;
-        } else if (!d_phase_new_term){
-          d_phase_new_term = true;
-          d_step = ES_GET_MONO_CANDIDATE;
-        } else {
-          d_phase_new_term = false;
-          d_step = ES_GET_MULTI_CANDIDATE;
-        }
-        break;
-      case ES_GET_MULTI_CANDIDATE:
-        Assert(d_im.empty());
-        if(d_eh.getNextMultiCandidate(d_mc)){
-          ++qe->d_statistics.d_num_multi_candidates;
-          d_phase_mono = false;
-          d_step = ES_RESET1;
-        } else d_step = ES_STOP;
-        break;
-      case ES_RESET1:
-        if(d_direct_patterns[d_mc.first.second]->reset(d_mc.first.first,d_im,qe))
-          d_step = d_phase_mono ? TestMonoCache(qe) : ES_RESET2;
-        else d_step = d_phase_mono ? ES_GET_MONO_CANDIDATE : ES_GET_MULTI_CANDIDATE;
-        break;
-      case ES_RESET2:
-        Assert(!d_phase_mono);
-        if(d_direct_patterns[d_mc.second.second]->reset(d_mc.second.first,d_im,qe))
-          d_step = TestMultiCache(qe);
-        else d_step = ES_NEXT1;
-        break;
-      case ES_NEXT1:
-        if(d_direct_patterns[d_mc.first.second]->getNextMatch(d_im,qe))
-          d_step = d_phase_mono ? TestMonoCache(qe) : ES_RESET2;
-        else d_step = d_phase_mono ? ES_GET_MONO_CANDIDATE : ES_GET_MULTI_CANDIDATE;
-        break;
-      case ES_NEXT2:
-        if(d_direct_patterns[d_mc.second.second]->getNextMatch(d_im,qe))
-          d_step = TestMultiCache(qe);
-        else d_step = ES_NEXT1;
-        break;
-      case ES_RESET_OTHER:
-        if(resetOther(qe)){
-          d_step = ES_NEXT_OTHER;
-          return true;
-        } else d_step = d_phase_mono ? ES_NEXT1 : ES_NEXT2;
-        break;
-      case ES_NEXT_OTHER:
-        {
-          if(!getNextMatchOther(qe,false)){
-            d_step = d_phase_mono ? ES_NEXT1 : ES_NEXT2;
-          }else{
-            d_step = ES_NEXT_OTHER;
-            return true;
-          }
-        }
-        break;
-      case ES_STOP:
-        Assert(d_im.empty());
-        return false;
-      }
-    }
-  }
-
-  MultiEfficientPatsMatcher(std::vector< Node > & pats, QuantifiersEngine* qe):
-    d_eh(qe->getTheoryEngine()->getSatContext()),
-    d_cache(qe->getTheoryEngine()->getSatContext(),qe,pats.size()),
-    d_pats(pats), d_step(ES_START) {
-    Assert(pats.size() > 0);
-    for( size_t i=0; i< pats.size(); i++ ){
-      d_patterns.push_back(mkPattern(pats[i],qe));
-      if(pats[i].getKind()==kind::INST_CONSTANT){
-        d_direct_patterns.push_back(new VarMatcher(pats[i],qe));
-      } else if( pats[i].getKind() == kind::NOT && pats[i][0].getKind() == kind::EQUAL){
-        d_direct_patterns.push_back(new ApplyMatcher(pats[i][0],qe));
-      } else {
-        d_direct_patterns.push_back(new ApplyMatcher(pats[i],qe));
-      }
-    };
-    Theory* th_uf = qe->getTheoryEngine()->getTheory( theory::THEORY_UF );
-    uf::InstantiatorTheoryUf* ith = (uf::InstantiatorTheoryUf*)th_uf->getInstantiator();
-    ith->registerEfficientHandler(d_eh, pats);
-  };
-  void resetInstantiationRound( QuantifiersEngine* qe ){
-    Assert(d_step == ES_START || d_step == ES_STOP);
-    for( size_t i=0; i< d_patterns.size(); i++ ){
-      d_patterns[i]->resetInstantiationRound( qe );
-      d_direct_patterns[i]->resetInstantiationRound( qe );
-    };
-    d_step = ES_START;
-    d_phase_new_term = false;
-    Assert(d_im.empty());
-  };
-
-  const InstMatch& getInstMatch(){return d_im;};
-
-  int addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe);
-};
-
-int MultiEfficientPatsMatcher::addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe){
-  //now, try to add instantiation for each match produced
-  int addedLemmas = 0;
-  Assert(baseMatch.empty());
-  resetInstantiationRound( qe );
-  while( getNextMatch( qe ) ){
-    InstMatch im_copy = getInstMatch();
-    //m.makeInternal( d_quantEngine->getEqualityQuery() );
-    if( qe->addInstantiation( quant, im_copy ) ){
-      addedLemmas++;
-    }
-  }
-  //return number of lemmas added
-  return addedLemmas;
-};
-
-PatsMatcher* mkPatternsEfficient( std::vector< Node > pat, QuantifiersEngine* qe ){
-  return new MultiEfficientPatsMatcher( pat, qe);
-}
-
-} /* CVC4::theory::rrinst */
-} /* CVC4::theory */
-} /* CVC4 */
diff --git a/src/theory/rr_inst_match.h b/src/theory/rr_inst_match.h
deleted file mode 100644 (file)
index 468fe6a..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/*********************                                                        */
-/*! \file rr_inst_match.h
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: bobot
- ** Minor contributors (to current version): mdeters
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief inst match class
- **/
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__RR_INST_MATCH_H
-#define __CVC4__RR_INST_MATCH_H
-
-#include "theory/theory.h"
-#include "util/hash.h"
-#include "util/ntuple.h"
-
-#include <ext/hash_set>
-#include <iostream>
-#include <map>
-
-#include "theory/uf/equality_engine.h"
-#include "theory/uf/theory_uf.h"
-#include "context/cdlist.h"
-
-#include "theory/inst_match.h"
-#include "expr/node_manager.h"
-#include "expr/node_builder.h"
-
-#include "theory/quantifiers/options.h"
-#include "theory/rewriterules/options.h"
-
-//#define USE_EFFICIENT_E_MATCHING
-
-namespace CVC4 {
-namespace theory {
-
-namespace rrinst{
-
-class CandidateGenerator
-{
-public:
-  CandidateGenerator(){}
-  virtual ~CandidateGenerator(){};
-
-  /** Get candidates functions.  These set up a context to get all match candidates.
-      cg->reset( eqc );
-      do{
-        Node cand = cg->getNextCandidate();
-        //.......
-      }while( !cand.isNull() );
-      
-      eqc is the equivalence class you are searching in
-  */
-  virtual void reset( TNode eqc ) = 0;
-  virtual TNode getNextCandidate() = 0;
-  /** call this at the beginning of each instantiation round */
-  virtual void resetInstantiationRound() = 0;
-public:
-  /** legal candidate */
-  static inline bool isLegalCandidate( TNode n ){
-    return !n.getAttribute(NoMatchAttribute()) &&
-      ( !options::cbqi() || !n.hasAttribute(InstConstantAttribute())) &&
-      ( !options::efficientEMatching() || n.hasAttribute(AvailableInTermDb()) );
-}
-
-};
-
-
-inline std::ostream& operator<<(std::ostream& out, const InstMatch& m) {
-  m.toStream(out);
-  return out;
-}
-
-template<bool modEq = false> class InstMatchTrie2;
-template<bool modEq = false> class InstMatchTrie2Pairs;
-
-template<bool modEq = false>
-class InstMatchTrie2Gen
-{
-  friend class InstMatchTrie2<modEq>;
-  friend class InstMatchTrie2Pairs<modEq>;
-
-private:
-
-  class Tree {
-  public:
-    typedef std::hash_map< Node, Tree *, NodeHashFunction > MLevel;
-    MLevel e;
-    const size_t level; //context level of creation
-    Tree() CVC4_UNDEFINED;
-    const Tree & operator =(const Tree & t){
-      Assert(t.e.empty()); Assert(e.empty());
-      Assert(t.level == level);
-      return t;
-    }
-    Tree(size_t l): level(l) {};
-    ~Tree(){
-      for(typename MLevel::iterator i = e.begin(); i!=e.end(); ++i)
-        delete(i->second);
-    };
-  };
-
-
-  typedef std::pair<Tree *, TNode> Mod;
-
-  class CleanUp{
-  public:
-    inline void operator()(Mod * m){
-      typename Tree::MLevel::iterator i = m->first->e.find(m->second);
-      Assert (i != m->first->e.end()); //should not have been already removed
-      m->first->e.erase(i);
-    };
-  };
-
-  EqualityQuery* d_eQ;
-  CandidateGenerator * d_cG;
-
-  context::Context* d_context;
-  context::CDList<Mod, CleanUp, std::allocator<Mod> > d_mods;
-
-
-  typedef std::map<Node, Node>::const_iterator mapIter;
-
-  /** add the substitution given by the iterator*/
-  void addSubTree( Tree * root, mapIter current, mapIter end, size_t currLevel);
-  /** test if it exists match, modulo uf-equations if modEq is true if
-   *  return false the deepest point of divergence is put in [e] and
-   *  [diverge].
-   */
-  bool existsInstMatch( Tree * root,
-                        mapIter & current, mapIter & end,
-                        Tree * & e, mapIter & diverge) const;
-
-  /** add match m in the trie root
-      return true if it was never seen */
-  bool addInstMatch( InstMatch& m, Tree * root);
-
-public:
-  InstMatchTrie2Gen(context::Context* c,  QuantifiersEngine* q);
-  InstMatchTrie2Gen(const InstMatchTrie2Gen &) CVC4_UNDEFINED;
-  const InstMatchTrie2Gen & operator =(const InstMatchTrie2Gen & e) CVC4_UNDEFINED;
-};
-
-template<bool modEq>
-class InstMatchTrie2
-{
-  typename InstMatchTrie2Gen<modEq>::Tree d_data;
-  InstMatchTrie2Gen<modEq> d_backtrack;
-public:
-  InstMatchTrie2(context::Context* c,  QuantifiersEngine* q): d_data(0),
-                                                              d_backtrack(c,q) {};
-  InstMatchTrie2(const InstMatchTrie2 &) CVC4_UNDEFINED;
-  const InstMatchTrie2 & operator =(const InstMatchTrie2 & e) CVC4_UNDEFINED;
-  /** add match m in the trie,
-      return true if it was never seen */
-  inline bool addInstMatch( InstMatch& m){
-    return d_backtrack.addInstMatch(m,&d_data);
-  };
-
-};/* class InstMatchTrie2 */
-
-class Matcher
-{
-public:
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  virtual void resetInstantiationRound( QuantifiersEngine* qe ) = 0;
-  /** reset the term to match, return false if there is no such term */
-  virtual bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe ) = 0;
-  /** get the next match. If it return false once you shouldn't call
-      getNextMatch again before doing a reset */
-  virtual bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) = 0;
-  /** If reset, or getNextMatch return false they remove from the
-      InstMatch the binding that they have previously created */
-
-  /** virtual Matcher in order to have definned behavior */
-  virtual ~Matcher(){};
-};
-
-
-class ApplyMatcher: public Matcher{
-private:
-  /** What to check first: constant and variable */
-  std::vector< triple< TNode,size_t,EqualityQuery* > > d_constants;
-  std::vector< triple< TNode,size_t,EqualityQuery* > > d_variables;
-  /** children generators, only the sub-pattern which are
-      neither a variable neither a constant appears */
-  std::vector< triple< Matcher*, size_t, EqualityQuery* > > d_childrens;
-  /** the variable that have been set by this matcher (during its own reset) */
-  std::vector< TNode > d_binded; /* TNode because the variable are already in d_pattern */
-  /** the representant of the argument of the term given by the last reset */
-  std::vector< Node > d_reps;
-public:
-  /** The pattern we are producing matches for */
-  Node d_pattern;
-public:
-  /** constructors */
-  ApplyMatcher( Node pat, QuantifiersEngine* qe);
-  /** destructor */
-  ~ApplyMatcher(){/*TODO delete dandling pointers? */}
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  void resetInstantiationRound( QuantifiersEngine* qe );
-  /** reset the term to match */
-  bool reset( TNode n, InstMatch& m, QuantifiersEngine* qe );
-  /** get the next match. */
-  bool getNextMatch(InstMatch& m, QuantifiersEngine* qe);
-private:
-  bool getNextMatch(InstMatch& m, QuantifiersEngine* qe, bool reset);
-};
-
-
-/* Match literal so you don't choose the equivalence class( */
-class PatMatcher
-{
-public:
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  virtual void resetInstantiationRound( QuantifiersEngine* qe ) = 0;
-  /** reset the matcher, return false if there is no such term */
-  virtual bool reset( InstMatch& m, QuantifiersEngine* qe ) = 0;
-  /** get the next match. If it return false once you shouldn't call
-      getNextMatch again before doing a reset */
-  virtual bool getNextMatch( InstMatch& m, QuantifiersEngine* qe ) = 0;
-  /** If reset, or getNextMatch return false they remove from the
-      InstMatch the binding that they have previously created */
-};
-
-Matcher* mkMatcher( Node pat, QuantifiersEngine* qe );
-PatMatcher* mkPattern( Node pat, QuantifiersEngine* qe );
-
-/* Match literal so you don't choose the equivalence class( */
-class PatsMatcher
-{
-public:
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  virtual void resetInstantiationRound( QuantifiersEngine* qe ) = 0;
-  /** reset the matcher, return false if there is no such term */
-  virtual bool getNextMatch( QuantifiersEngine* qe ) = 0;
-  virtual const InstMatch& getInstMatch() = 0;
-  /** Add directly the instantiation to quantifiers engine */
-  virtual int addInstantiations( InstMatch& baseMatch, Node quant, QuantifiersEngine* qe) = 0;
-};
-
-PatsMatcher* mkPatterns( std::vector< Node > pat, QuantifiersEngine* qe );
-PatsMatcher* mkPatternsEfficient( std::vector< Node > pat, QuantifiersEngine* qe );
-
-/** return true if whatever Node is subsituted for the variables the
-    given Node can't match the pattern */
-bool nonunifiable( TNode t, TNode pat, const std::vector<Node> & vars);
-
-class InstMatchGenerator;
-
-}/* CVC4::theory rrinst */
-
-}/* CVC4::theory namespace */
-
-}/* CVC4 namespace */
-
-#endif /* __CVC4__RR_INST_MATCH_H */
diff --git a/src/theory/rr_inst_match_impl.h b/src/theory/rr_inst_match_impl.h
deleted file mode 100644 (file)
index 4bf04cb..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*********************                                                        */
-/*! \file rr_inst_match_impl.h
- ** \verbatim
- ** Original author: bobot
- ** Major contributors: none
- ** Minor contributors (to current version): ajreynol, mdeters
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief inst match class
- **/
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__RR_INST_MATCH_IMPL_H
-#define __CVC4__RR_INST_MATCH_IMPL_H
-
-#include "theory/rr_inst_match.h"
-#include "theory/theory_engine.h"
-#include "theory/quantifiers_engine.h"
-#include "theory/rr_candidate_generator.h"
-#include "theory/uf/equality_engine.h"
-
-namespace CVC4 {
-namespace theory {
-namespace rrinst {
-
-template<bool modEq>
-InstMatchTrie2Gen<modEq>::InstMatchTrie2Gen(context::Context* c,  QuantifiersEngine* qe):
-  d_context(c), d_mods(c) {
-  d_eQ = qe->getEqualityQuery();
-  d_cG = qe->getRRCanGenClass();
-};
-
-/** add match m for quantifier f starting at index, take into account equalities q, return true if successful */
-template<bool modEq>
-void InstMatchTrie2Gen<modEq>::addSubTree( Tree * root, mapIter current, mapIter end, size_t currLevel ) {
-  if( current == end ) return;
-
-  Assert(root->e.find(current->second) == root->e.end());
-  Tree * root2 = new Tree(currLevel);
-  root->e.insert(std::make_pair(current->second, root2));
-  addSubTree(root2, ++current, end, currLevel );
-}
-
-/** exists match */
-template<bool modEq>
-bool InstMatchTrie2Gen<modEq>::existsInstMatch(InstMatchTrie2Gen<modEq>::Tree * root,
-                                            mapIter & current, mapIter & end,
-                                            Tree * & e, mapIter & diverge) const{
-  if( current == end ) {
-    Debug("Trie2") << "Trie2 Bottom " << std::endl;
-    --current;
-    return true;
-  }; //Already their
-
-  if (current->first > diverge->first){
-    // this point is the deepest point currently seen map are ordered
-    e = root;
-    diverge = current;
-  };
-
-  TNode n = current->second;
-  typename InstMatchTrie2Gen<modEq>::Tree::MLevel::iterator it =
-    root->e.find( n );
-  if( it!=root->e.end() &&
-      existsInstMatch( (*it).second, ++current, end, e, diverge) ){
-    Debug("Trie2") << "Trie2 Directly here " << n << std::endl;
-    --current;
-    return true;
-  }
-  Assert( it==root->e.end() || e != root );
-
-  // Even if n is in the trie others of the equivalence class
-  // can also be in it since the equality can have appeared
-  // after they have been added
-  if( modEq && d_eQ->hasTerm( n ) ){
-    //check modulo equality if any other instantiation match exists
-    d_cG->reset( d_eQ->getRepresentative( n ) );
-    for(TNode en = d_cG->getNextCandidate() ; !en.isNull() ;
-        en = d_cG->getNextCandidate() ){
-      if( en == n ) continue; // already tested
-      typename InstMatchTrie2Gen<modEq>::Tree::MLevel::iterator itc =
-        root->e.find( en );
-      if( itc!=root->e.end() &&
-          existsInstMatch( (*itc).second, ++current, end, e, diverge) ){
-        Debug("Trie2") << "Trie2 Indirectly here by equality " << n << " = " << en << std::endl;
-        --current;
-        return true;
-      }
-      Assert( itc==root->e.end() || e != root );
-    }
-  }
-  --current;
-  return false;
-}
-
-template<bool modEq>
-bool InstMatchTrie2Gen<modEq>::
-addInstMatch( InstMatch& m, InstMatchTrie2Gen<modEq>::Tree* e ) {
-  d_cG->resetInstantiationRound();
- mapIter begin = m.begin();
- mapIter end = m.end();
- mapIter diverge = begin;
- if( !existsInstMatch(e, begin, end, e, diverge ) ){
-   Assert(!diverge->second.isNull());
-   size_t currLevel = d_context->getLevel();
-   addSubTree( e, diverge, end, currLevel );
-   if(e->level != currLevel)
-     //If same level that e, will be removed at the same time than e
-     d_mods.push_back(std::make_pair(e,diverge->second));
-   return true;
- }else{
-   return false;
- }
-}
-
-}/* CVC4::theory::rrinst namespace */
-
-}/* CVC4::theory namespace */
-
-}/* CVC4 namespace */
-
-#endif /*  __CVC4__RR_INST_MATCH_IMPL_H */
diff --git a/src/theory/rr_trigger.cpp b/src/theory/rr_trigger.cpp
deleted file mode 100644 (file)
index 5d56147..0000000
+++ /dev/null
@@ -1,523 +0,0 @@
-/*********************                                                        */
-/*! \file rr_trigger.cpp
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: mdeters
- ** Minor contributors (to current version): bobot
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Implementation of trigger class
- **/
-
-#include "theory/rr_trigger.h"
-#include "theory/theory_engine.h"
-#include "theory/quantifiers_engine.h"
-#include "theory/uf/theory_uf_instantiator.h"
-#include "theory/rr_candidate_generator.h"
-#include "theory/uf/equality_engine.h"
-
-using namespace std;
-using namespace CVC4;
-using namespace CVC4::kind;
-using namespace CVC4::context;
-using namespace CVC4::theory;
-using namespace CVC4::theory::rrinst;
-
-//#define NESTED_PATTERN_SELECTION
-
-Trigger* Trigger::TrTrie::getTrigger2( std::vector< Node >& nodes ){
-  if( nodes.empty() ){
-    return d_tr;
-  }else{
-    Node n = nodes.back();
-    nodes.pop_back();
-    if( d_children.find( n )!=d_children.end() ){
-      return d_children[n]->getTrigger2( nodes );
-    }else{
-      return NULL;
-    }
-  }
-}
-void Trigger::TrTrie::addTrigger2( std::vector< Node >& nodes, Trigger* t ){
-  if( nodes.empty() ){
-    d_tr = t;
-  }else{
-    Node n = nodes.back();
-    nodes.pop_back();
-    if( d_children.find( n )==d_children.end() ){
-      d_children[n] = new TrTrie;
-    }
-    d_children[n]->addTrigger2( nodes, t );
-  }
-}
-
-/** trigger static members */
-std::map< Node, std::vector< Node > > Trigger::d_var_contains;
-int Trigger::trCount = 0;
-Trigger::TrTrie Trigger::d_tr_trie;
-
-/** trigger class constructor */
-Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool smartTriggers ) :
-d_quantEngine( qe ), d_f( f ){
-  trCount++;
-  d_nodes.insert( d_nodes.begin(), nodes.begin(), nodes.end() );
-  Debug("trigger") << "Trigger for " << f << ": " << d_nodes << std::endl;
-  if(matchOption == MATCH_GEN_DEFAULT) d_mg = mkPatterns( d_nodes, qe );
-  else d_mg = mkPatternsEfficient( d_nodes, qe );
-  if( d_nodes.size()==1 ){
-    if( isSimpleTrigger( d_nodes[0] ) ){
-      ++(qe->d_statistics.d_triggers);
-    }else{
-      ++(qe->d_statistics.d_simple_triggers);
-    }
-  }else{
-    Debug("multi-trigger") << "Multi-trigger " << (*this) << std::endl;
-    //std::cout << "Multi-trigger for " << f << " : " << std::endl;
-    //std::cout << "   " << (*this) << std::endl;
-    ++(qe->d_statistics.d_multi_triggers);
-  }
-}
-void Trigger::computeVarContains( Node n ) {
-  if( d_var_contains.find( n )==d_var_contains.end() ){
-    d_var_contains[n].clear();
-    computeVarContains2( n, n );
-  }
-}
-
-void Trigger::computeVarContains2( Node n, Node parent ){
-  if( n.getKind()==INST_CONSTANT ){
-    if( std::find( d_var_contains[parent].begin(), d_var_contains[parent].end(), n )==d_var_contains[parent].end() ){
-      d_var_contains[parent].push_back( n );
-    }
-  }else{
-    for( int i=0; i<(int)n.getNumChildren(); i++ ){
-      computeVarContains2( n[i], parent );
-    }
-  }
-}
-
-void Trigger::resetInstantiationRound(){
-  d_mg->resetInstantiationRound( d_quantEngine );
-}
-
-
-bool Trigger::getNextMatch(){
-  bool retVal = d_mg->getNextMatch( d_quantEngine );
-  //m.makeInternal( d_quantEngine->getEqualityQuery() );
-  return retVal;
-}
-
-// bool Trigger::getMatch( Node t, InstMatch& m ){
-//   //FIXME: this assumes d_mg is an inst match generator
-//   return ((InstMatchGenerator*)d_mg)->getMatch( t, m, d_quantEngine );
-// }
-
-
-int Trigger::addInstantiations( InstMatch& baseMatch ){
-  int addedLemmas = d_mg->addInstantiations( baseMatch,
-                                             d_nodes[0].getAttribute(InstConstantAttribute()),
-                                             d_quantEngine);
-  if( addedLemmas>0 ){
-    Debug("inst-trigger") << "Added " << addedLemmas << " lemmas, trigger was ";
-    for( int i=0; i<(int)d_nodes.size(); i++ ){
-      Debug("inst-trigger") << d_nodes[i] << " ";
-    }
-    Debug("inst-trigger") << std::endl;
-  }
-  return addedLemmas;
-}
-
-Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool keepAll, int trOption,
-                             bool smartTriggers ){
-  std::vector< Node > trNodes;
-  if( !keepAll ){
-    //only take nodes that contribute variables to the trigger when added
-    std::vector< Node > temp;
-    temp.insert( temp.begin(), nodes.begin(), nodes.end() );
-    std::map< Node, bool > vars;
-    std::map< Node, std::vector< Node > > patterns;
-    for( int i=0; i<(int)temp.size(); i++ ){
-      bool foundVar = false;
-      computeVarContains( temp[i] );
-      for( int j=0; j<(int)d_var_contains[ temp[i] ].size(); j++ ){
-        Node v = d_var_contains[ temp[i] ][j];
-        if( v.getAttribute(InstConstantAttribute())==f ){
-          if( vars.find( v )==vars.end() ){
-            vars[ v ] = true;
-            foundVar = true;
-          }
-        }
-      }
-      if( foundVar ){
-        trNodes.push_back( temp[i] );
-        for( int j=0; j<(int)d_var_contains[ temp[i] ].size(); j++ ){
-          Node v = d_var_contains[ temp[i] ][j];
-          patterns[ v ].push_back( temp[i] );
-        }
-      }
-    }
-    //now, minimalize the trigger
-    for( int i=0; i<(int)trNodes.size(); i++ ){
-      bool keepPattern = false;
-      Node n = trNodes[i];
-      for( int j=0; j<(int)d_var_contains[ n ].size(); j++ ){
-        Node v = d_var_contains[ n ][j];
-        if( patterns[v].size()==1 ){
-          keepPattern = true;
-          break;
-        }
-      }
-      if( !keepPattern ){
-        //remove from pattern vector
-        for( int j=0; j<(int)d_var_contains[ n ].size(); j++ ){
-          Node v = d_var_contains[ n ][j];
-          for( int k=0; k<(int)patterns[v].size(); k++ ){
-            if( patterns[v][k]==n ){
-              patterns[v].erase( patterns[v].begin() + k, patterns[v].begin() + k + 1 );
-              break;
-            }
-          }
-        }
-        //remove from trigger nodes
-        trNodes.erase( trNodes.begin() + i, trNodes.begin() + i + 1 );
-        i--;
-      }
-    }
-  }else{
-    trNodes.insert( trNodes.begin(), nodes.begin(), nodes.end() );
-  }
-
-  //check for duplicate?
-  if( trOption==TR_MAKE_NEW ){
-    //static int trNew = 0;
-    //static int trOld = 0;
-    //Trigger* t = d_tr_trie.getTrigger( trNodes );
-    //if( t ){
-    //  trOld++;
-    //}else{
-    //  trNew++;
-    //}
-    //if( (trNew+trOld)%100==0 ){
-    //  std::cout << "Trigger new old = " << trNew << " " << trOld << std::endl;
-    //}
-  }else{
-    Trigger* t = d_tr_trie.getTrigger( trNodes );
-    if( t ){
-      if( trOption==TR_GET_OLD ){
-        //just return old trigger
-        return t;
-      }else{
-        return NULL;
-      }
-    }
-  }
-  Trigger* t = new Trigger( qe, f, trNodes, matchOption, smartTriggers );
-  d_tr_trie.addTrigger( trNodes, t );
-  return t;
-}
-Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, Node n, int matchOption, bool keepAll, int trOption, bool smartTriggers ){
-  std::vector< Node > nodes;
-  nodes.push_back( n );
-  return mkTrigger( qe, f, nodes, matchOption, keepAll, trOption, smartTriggers );
-}
-
-bool Trigger::isUsableTrigger( std::vector< Node >& nodes, Node f ){
-  for( int i=0; i<(int)nodes.size(); i++ ){
-    if( !isUsableTrigger( nodes[i], f ) ){
-      return false;
-    }
-  }
-  return true;
-}
-
-bool Trigger::isUsable( Node n, Node f ){
-  if( n.getAttribute(InstConstantAttribute())==f ){
-    if( !isAtomicTrigger( n ) && n.getKind()!=INST_CONSTANT ){
-      std::map< Node, Node > coeffs;
-      return getPatternArithmetic( f, n, coeffs );
-    }else{
-      for( int i=0; i<(int)n.getNumChildren(); i++ ){
-        if( !isUsable( n[i], f ) ){
-          return false;
-        }
-      }
-      return true;
-    }
-  }else{
-    return true;
-  }
-}
-
-bool Trigger::isSimpleTrigger( Node n ){
-  if( isAtomicTrigger( n ) ){
-    for( int i=0; i<(int)n.getNumChildren(); i++ ){
-      if( n[i].getKind()!=INST_CONSTANT && n[i].hasAttribute(InstConstantAttribute()) ){
-        return false;
-      }
-    }
-    return true;
-  }else{
-    return false;
-  }
-}
-
-/** filter all nodes that have instances */
-void Trigger::filterInstances( std::vector< Node >& nodes ){
-  std::vector< bool > active;
-  active.resize( nodes.size(), true );
-  for( int i=0; i<(int)nodes.size(); i++ ){
-    for( int j=i+1; j<(int)nodes.size(); j++ ){
-      if( active[i] && active[j] ){
-        int result = isInstanceOf( nodes[i], nodes[j] );
-        if( result==1 ){
-          active[j] = false;
-        }else if( result==-1 ){
-          active[i] = false;
-        }
-      }
-    }
-  }
-  std::vector< Node > temp;
-  for( int i=0; i<(int)nodes.size(); i++ ){
-    if( active[i] ){
-      temp.push_back( nodes[i] );
-    }
-  }
-  nodes.clear();
-  nodes.insert( nodes.begin(), temp.begin(), temp.end() );
-}
-
-
-bool Trigger::collectPatTerms2( QuantifiersEngine* qe, Node f, Node n, std::map< Node, bool >& patMap, int tstrt ){
-  if( patMap.find( n )==patMap.end() ){
-    patMap[ n ] = false;
-    if( tstrt==TS_MIN_TRIGGER ){
-      if( n.getKind()==FORALL ){
-#ifdef NESTED_PATTERN_SELECTION
-        //return collectPatTerms2( qe, f, qe->getOrCreateCounterexampleBody( n ), patMap, tstrt );
-        return collectPatTerms2( qe, f, qe->getBoundBody( n ), patMap, tstrt );
-#else
-        return false;
-#endif
-      }else{
-        bool retVal = false;
-        for( int i=0; i<(int)n.getNumChildren(); i++ ){
-          if( collectPatTerms2( qe, f, n[i], patMap, tstrt ) ){
-            retVal = true;
-          }
-        }
-        if( retVal ){
-          return true;
-        }else if( isUsableTrigger( n, f ) ){
-          patMap[ n ] = true;
-          return true;
-        }else{
-          return false;
-        }
-      }
-    }else{
-      bool retVal = false;
-      if( isUsableTrigger( n, f ) ){
-        patMap[ n ] = true;
-        if( tstrt==TS_MAX_TRIGGER ){
-          return true;
-        }else{
-          retVal = true;
-        }
-      }
-      if( n.getKind()==FORALL ){
-#ifdef NESTED_PATTERN_SELECTION
-        //if( collectPatTerms2( qe, f, qe->getOrCreateCounterexampleBody( n ), patMap, tstrt ) ){
-        //  retVal = true;
-        //}
-        if( collectPatTerms2( qe, f, qe->getBoundBody( n ), patMap, tstrt ) ){
-          retVal = true;
-        }
-#endif
-      }else{
-        for( int i=0; i<(int)n.getNumChildren(); i++ ){
-          if( collectPatTerms2( qe, f, n[i], patMap, tstrt ) ){
-            retVal = true;
-          }
-        }
-      }
-      return retVal;
-    }
-  }else{
-    return patMap[ n ];
-  }
-}
-
-void Trigger::collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, bool filterInst ){
-  std::map< Node, bool > patMap;
-  if( filterInst ){
-    //immediately do not consider any term t for which another term is an instance of t
-    std::vector< Node > patTerms2;
-    collectPatTerms( qe, f, n, patTerms2, TS_ALL, false );
-    std::vector< Node > temp;
-    temp.insert( temp.begin(), patTerms2.begin(), patTerms2.end() );
-    filterInstances( temp );
-    if( temp.size()!=patTerms2.size() ){
-      Debug("trigger-filter-instance") << "Filtered an instance: " << std::endl;
-      Debug("trigger-filter-instance") << "Old: ";
-      for( int i=0; i<(int)patTerms2.size(); i++ ){
-        Debug("trigger-filter-instance") << patTerms2[i] << " ";
-      }
-      Debug("trigger-filter-instance") << std::endl << "New: ";
-      for( int i=0; i<(int)temp.size(); i++ ){
-        Debug("trigger-filter-instance") << temp[i] << " ";
-      }
-      Debug("trigger-filter-instance") << std::endl;
-    }
-    if( tstrt==TS_ALL ){
-      patTerms.insert( patTerms.begin(), temp.begin(), temp.end() );
-      return;
-    }else{
-      //do not consider terms that have instances
-      for( int i=0; i<(int)patTerms2.size(); i++ ){
-        if( std::find( temp.begin(), temp.end(), patTerms2[i] )==temp.end() ){
-          patMap[ patTerms2[i] ] = false;
-        }
-      }
-    }
-  }
-  collectPatTerms2( qe, f, n, patMap, tstrt );
-  for( std::map< Node, bool >::iterator it = patMap.begin(); it != patMap.end(); ++it ){
-    if( it->second ){
-      patTerms.push_back( it->first );
-    }
-  }
-}
-
-/** is n1 an instance of n2 or vice versa? */
-int Trigger::isInstanceOf( Node n1, Node n2 ){
-  if( n1==n2 ){
-    return 1;
-  }else if( n1.getKind()==n2.getKind() ){
-    if( n1.getKind()==APPLY_UF ){
-      if( n1.getOperator()==n2.getOperator() ){
-        int result = 0;
-        for( int i=0; i<(int)n1.getNumChildren(); i++ ){
-          if( n1[i]!=n2[i] ){
-            int cResult = isInstanceOf( n1[i], n2[i] );
-            if( cResult==0 ){
-              return 0;
-            }else if( cResult!=result ){
-              if( result!=0 ){
-                return 0;
-              }else{
-                result = cResult;
-              }
-            }
-          }
-        }
-        return result;
-      }
-    }
-    return 0;
-  }else if( n2.getKind()==INST_CONSTANT ){
-    computeVarContains( n1 );
-    //if( std::find( d_var_contains[ n1 ].begin(), d_var_contains[ n1 ].end(), n2 )!=d_var_contains[ n1 ].end() ){
-    //  return 1;
-    //}
-    if( d_var_contains[ n1 ].size()==1 && d_var_contains[ n1 ][ 0 ]==n2 ){
-      return 1;
-    }
-  }else if( n1.getKind()==INST_CONSTANT ){
-    computeVarContains( n2 );
-    //if( std::find( d_var_contains[ n2 ].begin(), d_var_contains[ n2 ].end(), n1 )!=d_var_contains[ n2 ].end() ){
-    //  return -1;
-    //}
-    if( d_var_contains[ n2 ].size()==1 && d_var_contains[ n2 ][ 0 ]==n1 ){
-      return 1;
-    }
-  }
-  return 0;
-}
-
-bool Trigger::isVariableSubsume( Node n1, Node n2 ){
-  if( n1==n2 ){
-    return true;
-  }else{
-    //std::cout << "is variable subsume ? " << n1 << " " << n2 << std::endl;
-    computeVarContains( n1 );
-    computeVarContains( n2 );
-    for( int i=0; i<(int)d_var_contains[n2].size(); i++ ){
-      if( std::find( d_var_contains[n1].begin(), d_var_contains[n1].end(), d_var_contains[n2][i] )==d_var_contains[n1].end() ){
-        //std::cout << "no" << std::endl;
-        return false;
-      }
-    }
-    //std::cout << "yes" << std::endl;
-    return true;
-  }
-}
-
-void Trigger::getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains ){
-  for( int i=0; i<(int)pats.size(); i++ ){
-    computeVarContains( pats[i] );
-    varContains[ pats[i] ].clear();
-    for( int j=0; j<(int)d_var_contains[pats[i]].size(); j++ ){
-      if( d_var_contains[pats[i]][j].getAttribute(InstConstantAttribute())==f ){
-        varContains[ pats[i] ].push_back( d_var_contains[pats[i]][j] );
-      }
-    }
-  }
-}
-
-void Trigger::getVarContainsNode( Node f, Node n, std::vector< Node >& varContains ){
-  computeVarContains( n );
-  for( int j=0; j<(int)d_var_contains[n].size(); j++ ){
-    if( d_var_contains[n][j].getAttribute(InstConstantAttribute())==f ){
-      varContains.push_back( d_var_contains[n][j] );
-    }
-  }
-}
-
-bool Trigger::getPatternArithmetic( Node f, Node n, std::map< Node, Node >& coeffs ){
-  if( n.getKind()==PLUS ){
-    Assert( coeffs.empty() );
-    NodeBuilder<> t(kind::PLUS);
-    for( int i=0; i<(int)n.getNumChildren(); i++ ){
-      if( n[i].hasAttribute(InstConstantAttribute()) ){
-        if( n[i].getKind()==INST_CONSTANT ){
-          if( n[i].getAttribute(InstConstantAttribute())==f ){
-            coeffs[ n[i] ] = Node::null();
-          }else{
-            coeffs.clear();
-            return false;
-          }
-        }else if( !getPatternArithmetic( f, n[i], coeffs ) ){
-          coeffs.clear();
-          return false;
-        }
-      }else{
-        t << n[i];
-      }
-    }
-    if( t.getNumChildren()==0 ){
-      coeffs[ Node::null() ] = NodeManager::currentNM()->mkConst( Rational(0) );
-    }else if( t.getNumChildren()==1 ){
-      coeffs[ Node::null() ]  = t.getChild( 0 );
-    }else{
-      coeffs[ Node::null() ]  = t;
-    }
-    return true;
-  }else if( n.getKind()==MULT ){
-    if( n[0].getKind()==INST_CONSTANT && n[0].getAttribute(InstConstantAttribute())==f ){
-      Assert( !n[1].hasAttribute(InstConstantAttribute()) );
-      coeffs[ n[0] ] = n[1];
-      return true;
-    }else if( n[1].getKind()==INST_CONSTANT && n[1].getAttribute(InstConstantAttribute())==f ){
-      Assert( !n[0].hasAttribute(InstConstantAttribute()) );
-      coeffs[ n[1] ] = n[0];
-      return true;
-    }
-  }
-  return false;
-}
diff --git a/src/theory/rr_trigger.h b/src/theory/rr_trigger.h
deleted file mode 100644 (file)
index bc12666..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*********************                                                        */
-/*! \file rr_trigger.h
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: bobot
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009-2012  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief trigger class
- **/
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__RR_TRIGGER_H
-#define __CVC4__RR_TRIGGER_H
-
-#include "theory/rr_inst_match.h"
-
-namespace CVC4 {
-namespace theory {
-namespace rrinst {
-
-//a collect of nodes representing a trigger
-class Trigger {
-public:
-  static int trCount;
-private:
-  /** computation of variable contains */
-  static std::map< Node, std::vector< Node > > d_var_contains;
-  static void computeVarContains( Node n );
-  static void computeVarContains2( Node n, Node parent );
-private:
-  /** the quantifiers engine */
-  QuantifiersEngine* d_quantEngine;
-  /** the quantifier this trigger is for */
-  Node d_f;
-  /** match generators */
-  PatsMatcher * d_mg;
-private:
-  /** a trie of triggers */
-  class TrTrie
-  {
-  private:
-    Trigger* getTrigger2( std::vector< Node >& nodes );
-    void addTrigger2( std::vector< Node >& nodes, Trigger* t );
-  public:
-    TrTrie() : d_tr( NULL ){}
-    Trigger* d_tr;
-    std::map< Node, TrTrie* > d_children;
-    Trigger* getTrigger( std::vector< Node >& nodes ){
-      std::vector< Node > temp;
-      temp.insert( temp.begin(), nodes.begin(), nodes.end() );
-      std::sort( temp.begin(), temp.end() );
-      return getTrigger2( temp );
-    }
-    void addTrigger( std::vector< Node >& nodes, Trigger* t ){
-      std::vector< Node > temp;
-      temp.insert( temp.begin(), nodes.begin(), nodes.end() );
-      std::sort( temp.begin(), temp.end() );
-      return addTrigger2( temp, t );
-    }
-  };
-  /** all triggers will be stored in this trie */
-  static TrTrie d_tr_trie;
-private:
-  /** trigger constructor */
-  Trigger( QuantifiersEngine* ie, Node f, std::vector< Node >& nodes, int matchOption = 0, bool smartTriggers = false );
-public:
-  ~Trigger(){}
-public:
-  std::vector< Node > d_nodes;
-public:
-  void debugPrint( const char* c );
-  PatsMatcher* getGenerator() { return d_mg; }
-public:
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  void resetInstantiationRound();
-  /** get next match.  must call reset( eqc ) once before this function. */
-  bool getNextMatch();
-  const InstMatch & getInstMatch(){return d_mg->getInstMatch();};
-  /** return whether this is a multi-trigger */
-  bool isMultiTrigger() { return d_nodes.size()>1; }
-public:
-  /** add all available instantiations exhaustively, in any equivalence class
-      if limitInst>0, limitInst is the max # of instantiations to try */
-  int addInstantiations( InstMatch& baseMatch);
-  /** mkTrigger method
-     ie     : quantifier engine;
-     f      : forall something ....
-     nodes  : (multi-)trigger
-     matchOption : which policy to use for creating matches (one of InstMatchGenerator::MATCH_GEN_* )
-     keepAll: don't remove unneeded patterns;
-     trOption : policy for dealing with triggers that already existed (see below)
-  */
-  enum {
-    //options for producing matches
-    MATCH_GEN_DEFAULT = 0,
-    MATCH_GEN_EFFICIENT_E_MATCH,   //generate matches via Efficient E
-  };
-  enum{
-    TR_MAKE_NEW,    //make new trigger even if it already may exist
-    TR_GET_OLD,     //return a previous trigger if it had already been created
-    TR_RETURN_NULL  //return null if a duplicate is found
-  };
-  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes,
-                             int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
-                             bool smartTriggers = false );
-  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, Node n,
-                             int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
-                             bool smartTriggers = false );
-private:
-  /** is subterm of trigger usable */
-  static bool isUsable( Node n, Node f );
-  /** collect all APPLY_UF pattern terms for f in n */
-  static bool collectPatTerms2( QuantifiersEngine* qe, Node f, Node n, std::map< Node, bool >& patMap, int tstrt );
-public:
-  //different strategies for choosing trigger terms
-  enum {
-    TS_MAX_TRIGGER = 0,
-    TS_MIN_TRIGGER,
-    TS_ALL,
-  };
-  static void collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, bool filterInst = false );
-public:
-  /** is usable trigger */
-  static inline bool isUsableTrigger( TNode n, TNode f ){
-    //return n.getAttribute(InstConstantAttribute())==f && n.getKind()==APPLY_UF;
-    return n.getAttribute(InstConstantAttribute())==f && isAtomicTrigger( n ) && isUsable( n, f );
-  }
-  static inline bool isAtomicTrigger( TNode n ){
-    return
-      n.getKind()==kind::APPLY_UF ||
-      n.getKind()==kind::SELECT ||
-      n.getKind()==kind::STORE;
-  }
-  static bool isUsableTrigger( std::vector< Node >& nodes, Node f );
-  static bool isSimpleTrigger( Node n );
-  /** filter all nodes that have instances */
-  static void filterInstances( std::vector< Node >& nodes );
-  /** -1: n1 is an instance of n2, 1: n1 is an instance of n2 */
-  static int isInstanceOf( Node n1, Node n2 );
-  /** variables subsume, return true if n1 contains all free variables in n2 */
-  static bool isVariableSubsume( Node n1, Node n2 );
-  /** get var contains */
-  static void getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains );
-  static void getVarContainsNode( Node f, Node n, std::vector< Node >& varContains );
-  /** get pattern arithmetic */
-  static bool getPatternArithmetic( Node f, Node n, std::map< Node, Node >& coeffs );
-
-  inline void toStream(std::ostream& out) const {
-    out << "TRIGGER( ";
-    for( int i=0; i<(int)d_nodes.size(); i++ ){
-      if( i>0 ){ out << ", "; }
-      out << d_nodes[i];
-    }
-    out << " )";
-  }
-};
-
-inline std::ostream& operator<<(std::ostream& out, const Trigger & tr) {
-  tr.toStream(out);
-  return out;
-}
-
-}/* CVC4::theory::rrinst namespace */
-
-}/* CVC4::theory namespace */
-
-}/* CVC4 namespace */
-
-#endif /* __CVC4__RR_TRIGGER_H */
index 1301da653166b9607e832ba6a24546f954188377..77daa5f5369e8e19b279ba0193e6ad0fab952ccf 100644 (file)
@@ -19,7 +19,7 @@
 #include "theory/theory.h"
 #include "util/Assert.h"
 #include "theory/quantifiers_engine.h"
-#include "theory/instantiator_default.h"
+#include "theory/quantifiers/instantiator_default.h"
 
 #include <vector>
 
diff --git a/src/theory/trigger.cpp b/src/theory/trigger.cpp
deleted file mode 100644 (file)
index f895f68..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-/*********************                                                        */
-/*! \file trigger.cpp
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: none
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief Implementation of trigger class
- **/
-
-#include "theory/trigger.h"
-#include "theory/theory_engine.h"
-#include "theory/quantifiers_engine.h"
-#include "theory/uf/theory_uf_instantiator.h"
-#include "theory/candidate_generator.h"
-#include "theory/uf/equality_engine.h"
-#include "theory/quantifiers/options.h"
-
-using namespace std;
-using namespace CVC4;
-using namespace CVC4::kind;
-using namespace CVC4::context;
-using namespace CVC4::theory;
-using namespace CVC4::theory::inst;
-
-//#define NESTED_PATTERN_SELECTION
-
-Trigger* Trigger::TrTrie::getTrigger2( std::vector< Node >& nodes ){
-  if( nodes.empty() ){
-    return d_tr;
-  }else{
-    Node n = nodes.back();
-    nodes.pop_back();
-    if( d_children.find( n )!=d_children.end() ){
-      return d_children[n]->getTrigger2( nodes );
-    }else{
-      return NULL;
-    }
-  }
-}
-void Trigger::TrTrie::addTrigger2( std::vector< Node >& nodes, Trigger* t ){
-  if( nodes.empty() ){
-    d_tr = t;
-  }else{
-    Node n = nodes.back();
-    nodes.pop_back();
-    if( d_children.find( n )==d_children.end() ){
-      d_children[n] = new TrTrie;
-    }
-    d_children[n]->addTrigger2( nodes, t );
-  }
-}
-
-/** trigger static members */
-std::map< TNode, std::vector< TNode > > Trigger::d_var_contains;
-Trigger::TrTrie Trigger::d_tr_trie;
-
-/** trigger class constructor */
-Trigger::Trigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool smartTriggers ) :
-d_quantEngine( qe ), d_f( f ){
-  d_nodes.insert( d_nodes.begin(), nodes.begin(), nodes.end() );
-  if( smartTriggers ){
-    if( d_nodes.size()==1 ){
-      if( isSimpleTrigger( d_nodes[0] ) ){
-        d_mg = new InstMatchGeneratorSimple( f, d_nodes[0] );
-      }else{
-        d_mg = new InstMatchGenerator( d_nodes[0], qe, matchOption );
-      }
-    }else{
-      d_mg = new InstMatchGeneratorMulti( f, d_nodes, qe, matchOption );
-    }
-  }else{
-    d_mg = new InstMatchGenerator( d_nodes, qe, matchOption );
-  }
-  Debug("trigger") << "Trigger for " << f << ": " << std::endl;
-  for( int i=0; i<(int)d_nodes.size(); i++ ){
-    Debug("trigger") << "   " << d_nodes[i] << std::endl;
-  }
-  Debug("trigger") << std::endl;
-  if( d_nodes.size()==1 ){
-    if( isSimpleTrigger( d_nodes[0] ) ){
-      ++(qe->d_statistics.d_triggers);
-    }else{
-      ++(qe->d_statistics.d_simple_triggers);
-    }
-  }else{
-    Debug("multi-trigger") << "Multi-trigger " << (*this) << std::endl;
-    //Notice() << "Multi-trigger for " << f << " : " << std::endl;
-    //Notice() << "   " << (*this) << std::endl;
-    ++(qe->d_statistics.d_multi_triggers);
-  }
-  //Notice() << "Trigger : " << (*this) << "  for " << f << std::endl;
-  if( options::eagerInstQuant() ){
-    Theory* th_uf = qe->getTheoryEngine()->getTheory( theory::THEORY_UF );
-    uf::InstantiatorTheoryUf* ith = (uf::InstantiatorTheoryUf*)th_uf->getInstantiator();
-    for( int i=0; i<(int)d_nodes.size(); i++ ){
-      ith->registerTrigger( this, d_nodes[i].getOperator() );
-    }
-  }
-}
-void Trigger::computeVarContains( Node n ) {
-  if( d_var_contains.find( n )==d_var_contains.end() ){
-    d_var_contains[n].clear();
-    computeVarContains2( n, n );
-  }
-}
-
-void Trigger::computeVarContains2( Node n, Node parent ){
-  if( n.getKind()==INST_CONSTANT ){
-    if( std::find( d_var_contains[parent].begin(), d_var_contains[parent].end(), n )==d_var_contains[parent].end() ){
-      d_var_contains[parent].push_back( n );
-    }
-  }else{
-    for( int i=0; i<(int)n.getNumChildren(); i++ ){
-      computeVarContains2( n[i], parent );
-    }
-  }
-}
-
-void Trigger::resetInstantiationRound(){
-  d_mg->resetInstantiationRound( d_quantEngine );
-}
-
-void Trigger::reset( Node eqc ){
-  d_mg->reset( eqc, d_quantEngine );
-}
-
-bool Trigger::getNextMatch( InstMatch& m ){
-  bool retVal = d_mg->getNextMatch( m, d_quantEngine );
-  //m.makeInternal( d_quantEngine->getEqualityQuery() );
-  return retVal;
-}
-
-bool Trigger::getMatch( Node t, InstMatch& m ){
-  //FIXME: this assumes d_mg is an inst match generator
-  return ((InstMatchGenerator*)d_mg)->getMatch( t, m, d_quantEngine );
-}
-
-int Trigger::addTerm( Node t ){
-  return d_mg->addTerm( d_f, t, d_quantEngine );
-}
-
-int Trigger::addInstantiations( InstMatch& baseMatch ){
-  int addedLemmas = d_mg->addInstantiations( d_f, baseMatch, d_quantEngine );
-  if( addedLemmas>0 ){
-    Debug("inst-trigger") << "Added " << addedLemmas << " lemmas, trigger was ";
-    for( int i=0; i<(int)d_nodes.size(); i++ ){
-      Debug("inst-trigger") << d_nodes[i] << " ";
-    }
-    Debug("inst-trigger") << std::endl;
-  }
-  return addedLemmas;
-}
-
-Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes, int matchOption, bool keepAll, int trOption,
-                             bool smartTriggers ){
-  std::vector< Node > trNodes;
-  if( !keepAll ){
-    //only take nodes that contribute variables to the trigger when added
-    std::vector< Node > temp;
-    temp.insert( temp.begin(), nodes.begin(), nodes.end() );
-    std::map< Node, bool > vars;
-    std::map< Node, std::vector< Node > > patterns;
-    for( int i=0; i<(int)temp.size(); i++ ){
-      bool foundVar = false;
-      computeVarContains( temp[i] );
-      for( int j=0; j<(int)d_var_contains[ temp[i] ].size(); j++ ){
-        Node v = d_var_contains[ temp[i] ][j];
-        if( v.getAttribute(InstConstantAttribute())==f ){
-          if( vars.find( v )==vars.end() ){
-            vars[ v ] = true;
-            foundVar = true;
-          }
-        }
-      }
-      if( foundVar ){
-        trNodes.push_back( temp[i] );
-        for( int j=0; j<(int)d_var_contains[ temp[i] ].size(); j++ ){
-          Node v = d_var_contains[ temp[i] ][j];
-          patterns[ v ].push_back( temp[i] );
-        }
-      }
-    }
-    //now, minimalize the trigger
-    for( int i=0; i<(int)trNodes.size(); i++ ){
-      bool keepPattern = false;
-      Node n = trNodes[i];
-      for( int j=0; j<(int)d_var_contains[ n ].size(); j++ ){
-        Node v = d_var_contains[ n ][j];
-        if( patterns[v].size()==1 ){
-          keepPattern = true;
-          break;
-        }
-      }
-      if( !keepPattern ){
-        //remove from pattern vector
-        for( int j=0; j<(int)d_var_contains[ n ].size(); j++ ){
-          Node v = d_var_contains[ n ][j];
-          for( int k=0; k<(int)patterns[v].size(); k++ ){
-            if( patterns[v][k]==n ){
-              patterns[v].erase( patterns[v].begin() + k, patterns[v].begin() + k + 1 );
-              break;
-            }
-          }
-        }
-        //remove from trigger nodes
-        trNodes.erase( trNodes.begin() + i, trNodes.begin() + i + 1 );
-        i--;
-      }
-    }
-  }else{
-    trNodes.insert( trNodes.begin(), nodes.begin(), nodes.end() );
-  }
-
-  //check for duplicate?
-  if( trOption==TR_MAKE_NEW ){
-    //static int trNew = 0;
-    //static int trOld = 0;
-    //Trigger* t = d_tr_trie.getTrigger( trNodes );
-    //if( t ){
-    //  trOld++;
-    //}else{
-    //  trNew++;
-    //}
-    //if( (trNew+trOld)%100==0 ){
-    //  Notice() << "Trigger new old = " << trNew << " " << trOld << std::endl;
-    //}
-  }else{
-    Trigger* t = d_tr_trie.getTrigger( trNodes );
-    if( t ){
-      if( trOption==TR_GET_OLD ){
-        //just return old trigger
-        return t;
-      }else{
-        return NULL;
-      }
-    }
-  }
-  Trigger* t = new Trigger( qe, f, trNodes, matchOption, smartTriggers );
-  d_tr_trie.addTrigger( trNodes, t );
-  return t;
-}
-Trigger* Trigger::mkTrigger( QuantifiersEngine* qe, Node f, Node n, int matchOption, bool keepAll, int trOption, bool smartTriggers ){
-  std::vector< Node > nodes;
-  nodes.push_back( n );
-  return mkTrigger( qe, f, nodes, matchOption, keepAll, trOption, smartTriggers );
-}
-
-bool Trigger::isUsableTrigger( std::vector< Node >& nodes, Node f ){
-  for( int i=0; i<(int)nodes.size(); i++ ){
-    if( !isUsableTrigger( nodes[i], f ) ){
-      return false;
-    }
-  }
-  return true;
-}
-
-bool Trigger::isUsable( Node n, Node f ){
-  if( n.getAttribute(InstConstantAttribute())==f ){
-    if( !isAtomicTrigger( n ) && n.getKind()!=INST_CONSTANT ){
-      std::map< Node, Node > coeffs;
-      return getPatternArithmetic( f, n, coeffs );
-    }else{
-      for( int i=0; i<(int)n.getNumChildren(); i++ ){
-        if( !isUsable( n[i], f ) ){
-          return false;
-        }
-      }
-      return true;
-    }
-  }else{
-    return true;
-  }
-}
-
-bool Trigger::isUsableTrigger( Node n, Node f ){
-  //return n.getAttribute(InstConstantAttribute())==f && n.getKind()==APPLY_UF;
-  return n.getAttribute(InstConstantAttribute())==f && isAtomicTrigger( n ) && isUsable( n, f );
-}
-
-bool Trigger::isAtomicTrigger( Node n ){
-  return n.getKind()==APPLY_UF || n.getKind()==SELECT || n.getKind()==STORE ||
-         n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR || n.getKind()==APPLY_TESTER;
-}
-bool Trigger::isSimpleTrigger( Node n ){
-  if( isAtomicTrigger( n ) ){
-    for( int i=0; i<(int)n.getNumChildren(); i++ ){
-      if( n[i].getKind()!=INST_CONSTANT && n[i].hasAttribute(InstConstantAttribute()) ){
-        return false;
-      }
-    }
-    return true;
-  }else{
-    return false;
-  }
-}
-
-/** filter all nodes that have instances */
-void Trigger::filterInstances( std::vector< Node >& nodes ){
-  std::vector< bool > active;
-  active.resize( nodes.size(), true );
-  for( int i=0; i<(int)nodes.size(); i++ ){
-    for( int j=i+1; j<(int)nodes.size(); j++ ){
-      if( active[i] && active[j] ){
-        int result = isInstanceOf( nodes[i], nodes[j] );
-        if( result==1 ){
-          active[j] = false;
-        }else if( result==-1 ){
-          active[i] = false;
-        }
-      }
-    }
-  }
-  std::vector< Node > temp;
-  for( int i=0; i<(int)nodes.size(); i++ ){
-    if( active[i] ){
-      temp.push_back( nodes[i] );
-    }
-  }
-  nodes.clear();
-  nodes.insert( nodes.begin(), temp.begin(), temp.end() );
-}
-
-
-bool Trigger::collectPatTerms2( QuantifiersEngine* qe, Node f, Node n, std::map< Node, bool >& patMap, int tstrt ){
-  if( patMap.find( n )==patMap.end() ){
-    patMap[ n ] = false;
-    if( tstrt==TS_MIN_TRIGGER ){
-      if( n.getKind()==FORALL ){
-#ifdef NESTED_PATTERN_SELECTION
-        //return collectPatTerms2( qe, f, qe->getOrCreateCounterexampleBody( n ), patMap, tstrt );
-        return collectPatTerms2( qe, f, qe->getBoundBody( n ), patMap, tstrt );
-#else
-        return false;
-#endif
-      }else{
-        bool retVal = false;
-        for( int i=0; i<(int)n.getNumChildren(); i++ ){
-          if( collectPatTerms2( qe, f, n[i], patMap, tstrt ) ){
-            retVal = true;
-          }
-        }
-        if( retVal ){
-          return true;
-        }else if( isUsableTrigger( n, f ) ){
-          patMap[ n ] = true;
-          return true;
-        }else{
-          return false;
-        }
-      }
-    }else{
-      bool retVal = false;
-      if( isUsableTrigger( n, f ) ){
-        patMap[ n ] = true;
-        if( tstrt==TS_MAX_TRIGGER ){
-          return true;
-        }else{
-          retVal = true;
-        }
-      }
-      if( n.getKind()==FORALL ){
-#ifdef NESTED_PATTERN_SELECTION
-        //if( collectPatTerms2( qe, f, qe->getOrCreateCounterexampleBody( n ), patMap, tstrt ) ){
-        //  retVal = true;
-        //}
-        if( collectPatTerms2( qe, f, qe->getBoundBody( n ), patMap, tstrt ) ){
-          retVal = true;
-        }
-#endif
-      }else{
-        for( int i=0; i<(int)n.getNumChildren(); i++ ){
-          if( collectPatTerms2( qe, f, n[i], patMap, tstrt ) ){
-            retVal = true;
-          }
-        }
-      }
-      return retVal;
-    }
-  }else{
-    return patMap[ n ];
-  }
-}
-
-void Trigger::collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, bool filterInst ){
-  std::map< Node, bool > patMap;
-  if( filterInst ){
-    //immediately do not consider any term t for which another term is an instance of t
-    std::vector< Node > patTerms2;
-    collectPatTerms( qe, f, n, patTerms2, TS_ALL, false );
-    std::vector< Node > temp;
-    temp.insert( temp.begin(), patTerms2.begin(), patTerms2.end() );
-    filterInstances( temp );
-    if( temp.size()!=patTerms2.size() ){
-      Debug("trigger-filter-instance") << "Filtered an instance: " << std::endl;
-      Debug("trigger-filter-instance") << "Old: ";
-      for( int i=0; i<(int)patTerms2.size(); i++ ){
-        Debug("trigger-filter-instance") << patTerms2[i] << " ";
-      }
-      Debug("trigger-filter-instance") << std::endl << "New: ";
-      for( int i=0; i<(int)temp.size(); i++ ){
-        Debug("trigger-filter-instance") << temp[i] << " ";
-      }
-      Debug("trigger-filter-instance") << std::endl;
-    }
-    if( tstrt==TS_ALL ){
-      patTerms.insert( patTerms.begin(), temp.begin(), temp.end() );
-      return;
-    }else{
-      //do not consider terms that have instances
-      for( int i=0; i<(int)patTerms2.size(); i++ ){
-        if( std::find( temp.begin(), temp.end(), patTerms2[i] )==temp.end() ){
-          patMap[ patTerms2[i] ] = false;
-        }
-      }
-    }
-  }
-  collectPatTerms2( qe, f, n, patMap, tstrt );
-  for( std::map< Node, bool >::iterator it = patMap.begin(); it != patMap.end(); ++it ){
-    if( it->second ){
-      patTerms.push_back( it->first );
-    }
-  }
-}
-
-/** is n1 an instance of n2 or vice versa? */
-int Trigger::isInstanceOf( Node n1, Node n2 ){
-  if( n1==n2 ){
-    return 1;
-  }else if( n1.getKind()==n2.getKind() ){
-    if( n1.getKind()==APPLY_UF ){
-      if( n1.getOperator()==n2.getOperator() ){
-        int result = 0;
-        for( int i=0; i<(int)n1.getNumChildren(); i++ ){
-          if( n1[i]!=n2[i] ){
-            int cResult = isInstanceOf( n1[i], n2[i] );
-            if( cResult==0 ){
-              return 0;
-            }else if( cResult!=result ){
-              if( result!=0 ){
-                return 0;
-              }else{
-                result = cResult;
-              }
-            }
-          }
-        }
-        return result;
-      }
-    }
-    return 0;
-  }else if( n2.getKind()==INST_CONSTANT ){
-    computeVarContains( n1 );
-    //if( std::find( d_var_contains[ n1 ].begin(), d_var_contains[ n1 ].end(), n2 )!=d_var_contains[ n1 ].end() ){
-    //  return 1;
-    //}
-    if( d_var_contains[ n1 ].size()==1 && d_var_contains[ n1 ][ 0 ]==n2 ){
-      return 1;
-    }
-  }else if( n1.getKind()==INST_CONSTANT ){
-    computeVarContains( n2 );
-    //if( std::find( d_var_contains[ n2 ].begin(), d_var_contains[ n2 ].end(), n1 )!=d_var_contains[ n2 ].end() ){
-    //  return -1;
-    //}
-    if( d_var_contains[ n2 ].size()==1 && d_var_contains[ n2 ][ 0 ]==n1 ){
-      return 1;
-    }
-  }
-  return 0;
-}
-
-bool Trigger::isVariableSubsume( Node n1, Node n2 ){
-  if( n1==n2 ){
-    return true;
-  }else{
-    //Notice() << "is variable subsume ? " << n1 << " " << n2 << std::endl;
-    computeVarContains( n1 );
-    computeVarContains( n2 );
-    for( int i=0; i<(int)d_var_contains[n2].size(); i++ ){
-      if( std::find( d_var_contains[n1].begin(), d_var_contains[n1].end(), d_var_contains[n2][i] )==d_var_contains[n1].end() ){
-        //Notice() << "no" << std::endl;
-        return false;
-      }
-    }
-    //Notice() << "yes" << std::endl;
-    return true;
-  }
-}
-
-void Trigger::getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains ){
-  for( int i=0; i<(int)pats.size(); i++ ){
-    computeVarContains( pats[i] );
-    varContains[ pats[i] ].clear();
-    for( int j=0; j<(int)d_var_contains[pats[i]].size(); j++ ){
-      if( d_var_contains[pats[i]][j].getAttribute(InstConstantAttribute())==f ){
-        varContains[ pats[i] ].push_back( d_var_contains[pats[i]][j] );
-      }
-    }
-  }
-}
-
-void Trigger::getVarContainsNode( Node f, Node n, std::vector< Node >& varContains ){
-  computeVarContains( n );
-  for( int j=0; j<(int)d_var_contains[n].size(); j++ ){
-    if( d_var_contains[n][j].getAttribute(InstConstantAttribute())==f ){
-      varContains.push_back( d_var_contains[n][j] );
-    }
-  }
-}
-
-bool Trigger::getPatternArithmetic( Node f, Node n, std::map< Node, Node >& coeffs ){
-  if( n.getKind()==PLUS ){
-    Assert( coeffs.empty() );
-    NodeBuilder<> t(kind::PLUS);
-    for( int i=0; i<(int)n.getNumChildren(); i++ ){
-      if( n[i].hasAttribute(InstConstantAttribute()) ){
-        if( n[i].getKind()==INST_CONSTANT ){
-          if( n[i].getAttribute(InstConstantAttribute())==f ){
-            coeffs[ n[i] ] = Node::null();
-          }else{
-            coeffs.clear();
-            return false;
-          }
-        }else if( !getPatternArithmetic( f, n[i], coeffs ) ){
-          coeffs.clear();
-          return false;
-        }
-      }else{
-        t << n[i];
-      }
-    }
-    if( t.getNumChildren()==0 ){
-      coeffs[ Node::null() ] = NodeManager::currentNM()->mkConst( Rational(0) );
-    }else if( t.getNumChildren()==1 ){
-      coeffs[ Node::null() ]  = t.getChild( 0 );
-    }else{
-      coeffs[ Node::null() ]  = t;
-    }
-    return true;
-  }else if( n.getKind()==MULT ){
-    if( n[0].getKind()==INST_CONSTANT && n[0].getAttribute(InstConstantAttribute())==f ){
-      Assert( !n[1].hasAttribute(InstConstantAttribute()) );
-      coeffs[ n[0] ] = n[1];
-      return true;
-    }else if( n[1].getKind()==INST_CONSTANT && n[1].getAttribute(InstConstantAttribute())==f ){
-      Assert( !n[0].hasAttribute(InstConstantAttribute()) );
-      coeffs[ n[1] ] = n[0];
-      return true;
-    }
-  }
-  return false;
-}
diff --git a/src/theory/trigger.h b/src/theory/trigger.h
deleted file mode 100644 (file)
index 84bc7ac..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*********************                                                        */
-/*! \file trigger.h
- ** \verbatim
- ** Original author: ajreynol
- ** Major contributors: none
- ** Minor contributors (to current version): none
- ** This file is part of the CVC4 prototype.
- ** Copyright (c) 2009, 2010, 2011  The Analysis of Computer Systems Group (ACSys)
- ** Courant Institute of Mathematical Sciences
- ** New York University
- ** See the file COPYING in the top-level source directory for licensing
- ** information.\endverbatim
- **
- ** \brief trigger class
- **/
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__TRIGGER_H
-#define __CVC4__TRIGGER_H
-
-#include "theory/inst_match.h"
-
-namespace CVC4 {
-namespace theory {
-namespace inst {
-
-//a collect of nodes representing a trigger
-class Trigger {
-private:
-  /** computation of variable contains */
-  static std::map< TNode, std::vector< TNode > > d_var_contains;
-  static void computeVarContains( Node n );
-  static void computeVarContains2( Node n, Node parent );
-private:
-  /** the quantifiers engine */
-  QuantifiersEngine* d_quantEngine;
-  /** the quantifier this trigger is for */
-  Node d_f;
-  /** match generators */
-  IMGenerator* d_mg;
-private:
-  /** a trie of triggers */
-  class TrTrie {
-  private:
-    Trigger* getTrigger2( std::vector< Node >& nodes );
-    void addTrigger2( std::vector< Node >& nodes, Trigger* t );
-  public:
-    TrTrie() : d_tr( NULL ){}
-    Trigger* d_tr;
-    std::map< TNode, TrTrie* > d_children;
-    Trigger* getTrigger( std::vector< Node >& nodes ){
-      std::vector< Node > temp;
-      temp.insert( temp.begin(), nodes.begin(), nodes.end() );
-      std::sort( temp.begin(), temp.end() );
-      return getTrigger2( temp );
-    }
-    void addTrigger( std::vector< Node >& nodes, Trigger* t ){
-      std::vector< Node > temp;
-      temp.insert( temp.begin(), nodes.begin(), nodes.end() );
-      std::sort( temp.begin(), temp.end() );
-      return addTrigger2( temp, t );
-    }
-  };/* class Trigger::TrTrie */
-  /** all triggers will be stored in this trie */
-  static TrTrie d_tr_trie;
-private:
-  /** trigger constructor */
-  Trigger( QuantifiersEngine* ie, Node f, std::vector< Node >& nodes, int matchOption = 0, bool smartTriggers = false );
-public:
-  ~Trigger(){}
-public:
-  std::vector< Node > d_nodes;
-public:
-  void debugPrint( const char* c );
-  IMGenerator* getGenerator() { return d_mg; }
-public:
-  /** reset instantiation round (call this whenever equivalence classes have changed) */
-  void resetInstantiationRound();
-  /** reset, eqc is the equivalence class to search in (search in any if eqc=null) */
-  void reset( Node eqc );
-  /** get next match.  must call reset( eqc ) once before this function. */
-  bool getNextMatch( InstMatch& m );
-  /** get the match against ground term or formula t.
-      the trigger and t should have the same shape.
-      Currently the trigger should not be a multi-trigger.
-  */
-  bool getMatch( Node t, InstMatch& m);
-  /** add ground term t, called when t is added to the TermDb */
-  int addTerm( Node t );
-  /** return true if whatever Node is subsituted for the variables the
-      given Node can't match the pattern */
-  bool nonunifiable( TNode t, const std::vector<Node> & vars){
-    return d_mg->nonunifiable(t,vars);
-  }
-  /** return whether this is a multi-trigger */
-  bool isMultiTrigger() { return d_nodes.size()>1; }
-public:
-  /** add all available instantiations exhaustively, in any equivalence class
-      if limitInst>0, limitInst is the max # of instantiations to try */
-  int addInstantiations( InstMatch& baseMatch );
-  /** mkTrigger method
-     ie     : quantifier engine;
-     f      : forall something ....
-     nodes  : (multi-)trigger
-     matchOption : which policy to use for creating matches (one of InstMatchGenerator::MATCH_GEN_* )
-     keepAll: don't remove unneeded patterns;
-     trOption : policy for dealing with triggers that already existed (see below)
-  */
-  enum{
-    TR_MAKE_NEW,    //make new trigger even if it already may exist
-    TR_GET_OLD,     //return a previous trigger if it had already been created
-    TR_RETURN_NULL  //return null if a duplicate is found
-  };
-  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, std::vector< Node >& nodes,
-                             int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
-                             bool smartTriggers = false );
-  static Trigger* mkTrigger( QuantifiersEngine* qe, Node f, Node n,
-                             int matchOption = 0, bool keepAll = true, int trOption = TR_MAKE_NEW,
-                             bool smartTriggers = false );
-private:
-  /** is subterm of trigger usable */
-  static bool isUsable( Node n, Node f );
-  /** collect all APPLY_UF pattern terms for f in n */
-  static bool collectPatTerms2( QuantifiersEngine* qe, Node f, Node n, std::map< Node, bool >& patMap, int tstrt );
-public:
-  //different strategies for choosing trigger terms
-  enum {
-    TS_MAX_TRIGGER = 0,
-    TS_MIN_TRIGGER,
-    TS_ALL,
-  };
-  static void collectPatTerms( QuantifiersEngine* qe, Node f, Node n, std::vector< Node >& patTerms, int tstrt, bool filterInst = false );
-public:
-  /** is usable trigger */
-  static bool isUsableTrigger( std::vector< Node >& nodes, Node f );
-  static bool isUsableTrigger( Node n, Node f );
-  static bool isAtomicTrigger( Node n );
-  static bool isSimpleTrigger( Node n );
-  /** filter all nodes that have instances */
-  static void filterInstances( std::vector< Node >& nodes );
-  /** -1: n1 is an instance of n2, 1: n1 is an instance of n2 */
-  static int isInstanceOf( Node n1, Node n2 );
-  /** variables subsume, return true if n1 contains all free variables in n2 */
-  static bool isVariableSubsume( Node n1, Node n2 );
-  /** get var contains */
-  static void getVarContains( Node f, std::vector< Node >& pats, std::map< Node, std::vector< Node > >& varContains );
-  static void getVarContainsNode( Node f, Node n, std::vector< Node >& varContains );
-  /** get pattern arithmetic */
-  static bool getPatternArithmetic( Node f, Node n, std::map< Node, Node >& coeffs );
-
-  inline void toStream(std::ostream& out) const {
-    out << "TRIGGER( ";
-    for( int i=0; i<(int)d_nodes.size(); i++ ){
-      if( i>0 ){ out << ", "; }
-      out << d_nodes[i];
-    }
-    out << " )";
-  }
-};
-
-inline std::ostream& operator<<(std::ostream& out, const Trigger & tr) {
-  tr.toStream(out);
-  return out;
-}
-
-}/* CVC4::theory::inst namespace */
-
-}/* CVC4::theory namespace */
-
-}/* CVC4 namespace */
-
-#endif /* __CVC4__TRIGGER_H */
index a0091c4b477a2d556716dffcb48670c23d8d90b5..663720326772c3c8d180df5c55aa993e6ca71411 100644 (file)
@@ -20,7 +20,7 @@
 #define __CVC4__INST_STRATEGY_H
 
 #include "theory/quantifiers_engine.h"
-#include "theory/trigger.h"
+#include "theory/quantifiers/trigger.h"
 
 #include "context/context.h"
 #include "context/context_mm.h"
index ea253cbdb095ee2efec97433c4741f2ea3558cd3..90e45775bb518e7c858edab8e2326418929901b1 100644 (file)
@@ -17,7 +17,7 @@
 #include "theory/uf/theory_uf_instantiator.h"
 #include "theory/theory_engine.h"
 #include "theory/uf/theory_uf.h"
-#include "theory/rr_candidate_generator.h"
+#include "theory/rewriterules/rr_candidate_generator.h"
 #include "theory/uf/equality_engine.h"
 #include "theory/quantifiers/options.h"
 #include "theory/rewriterules/options.h"
index d15c0103b0029cb451bf10fb1bf6afce4f907d3f..59b8f36a469efe0bd1ea97c67b354c168a51b634 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "util/stats.h"
 #include "theory/uf/theory_uf.h"
-#include "theory/trigger.h"
+#include "theory/quantifiers/trigger.h"
 #include "util/ntuple.h"
 #include "context/cdqueue.h"