Make --var-elim-quant true by default. Add rewrite engine to quantifiers module.
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Mon, 17 Jun 2013 20:31:28 +0000 (15:31 -0500)
committerAndrew Reynolds <andrew.j.reynolds@gmail.com>
Mon, 17 Jun 2013 20:31:38 +0000 (15:31 -0500)
16 files changed:
src/theory/quantifiers/Makefile.am
src/theory/quantifiers/inst_match_generator.cpp
src/theory/quantifiers/inst_match_generator.h
src/theory/quantifiers/instantiation_engine.cpp
src/theory/quantifiers/model_builder.cpp
src/theory/quantifiers/model_builder.h
src/theory/quantifiers/model_engine.cpp
src/theory/quantifiers/options
src/theory/quantifiers/quantifiers_rewriter.cpp
src/theory/quantifiers/rewrite_engine.cpp [new file with mode: 0755]
src/theory/quantifiers/rewrite_engine.h [new file with mode: 0755]
src/theory/quantifiers/term_database.h
src/theory/quantifiers/trigger.cpp
src/theory/quantifiers_engine.cpp
src/theory/quantifiers_engine.h
src/theory/rewriterules/theory_rewriterules_rules.cpp

index 60f2ee7f7c9dd3beee1da4edd1f58557fc075fd6..0339fbcd8759cb0e9ed55a1c4005ccb187134e74 100644 (file)
@@ -48,7 +48,9 @@ libquantifiers_la_SOURCES = \
        bounded_integers.h \
        bounded_integers.cpp \
        first_order_reasoning.h \
-       first_order_reasoning.cpp
+       first_order_reasoning.cpp \
+       rewrite_engine.h \
+       rewrite_engine.cpp
 
 EXTRA_DIST = \
        kinds \
index 87c39f046594de86c1e6b327fd61beb6eac9628c..50362340bd1723dc44768c142ee15d5009f4a57c 100644 (file)
@@ -38,10 +38,10 @@ InstMatchGenerator::InstMatchGenerator( Node pat, int matchPolicy ) : d_matchPol
   d_next = NULL;
 }
 
-void InstMatchGenerator::setActiveAdd(){
-  d_active_add = true;
+void InstMatchGenerator::setActiveAdd(bool val){
+  d_active_add = val;
   if( d_next!=NULL ){
-    d_next->setActiveAdd();
+    d_next->setActiveAdd(val);
   }
 }
 
@@ -310,18 +310,20 @@ bool InstMatchGenerator::getMatchArithmetic( Node t, InstMatch& m, QuantifiersEn
 
 /** 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_match_pattern.isNull() ){
+    Debug("matching-debug2") << this << " reset instantiation round." << std::endl;
+    d_needsReset = true;
     if( d_cg ){
       d_cg->resetInstantiationRound();
     }
   }
+  if( d_next ){
+    d_next->resetInstantiationRound( qe );
+  }
 }
 
 void InstMatchGenerator::reset( Node eqc, QuantifiersEngine* qe ){
+  Debug("matching-debug2") << this << " reset " << eqc << "." << std::endl;
   if( !eqc.isNull() ){
     d_eq_class = eqc;
   }
@@ -329,16 +331,22 @@ void InstMatchGenerator::reset( Node eqc, QuantifiersEngine* qe ){
   //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.getKind()==INST_CONSTANT ? Node::null() : d_eq_class );
+  d_needsReset = false;
 }
 
 bool InstMatchGenerator::getNextMatch( Node f, InstMatch& m, QuantifiersEngine* qe ){
+  if( d_needsReset ){
+    Debug("matching") << "Reset not done yet, must do the reset..." << std::endl;
+    reset( d_eq_class.getKind()==INST_CONSTANT ? Node::null() : d_eq_class, qe );
+  }
   m.d_matched = Node::null();
-  //Debug("matching") << this << " " << d_pattern << " get next match 2 " << m << " in eq class " << d_eq_class << std::endl;
+  Debug("matching") << this << " " << d_match_pattern << " get next match " << m << " in eq class " << d_eq_class << std::endl;
   bool success = false;
   Node t;
   do{
     //get the next candidate term t
     t = d_cg->getNextCandidate();
+    Debug("matching-debug2") << "Matching candidate : " << t << std::endl;
     //if t not null, try to fit it into match m
     if( !t.isNull() && t.getType()==d_match_pattern.getType() ){
       success = getMatch( f, t, m, qe );
@@ -346,7 +354,7 @@ bool InstMatchGenerator::getNextMatch( Node f, InstMatch& m, QuantifiersEngine*
   }while( !success && !t.isNull() );
   m.d_matched = t;
   if( !success ){
-    //Debug("matching") << this << " failed, reset " << d_eq_class << std::endl;
+    Debug("matching") << this << " failed, reset " << d_eq_class << std::endl;
     //we failed, must reset
     reset( d_eq_class.getKind()==INST_CONSTANT ? Node::null() : d_eq_class, qe );
   }
index 4c954fa8149b498ea36bdbc687a3e8144aa8d9b7..9f856a56bdbb77bc296a83c668d1072c77714e24 100644 (file)
@@ -44,13 +44,14 @@ public:
   /** add ground term t, called when t is added to term db */
   virtual int addTerm( Node f, Node t, QuantifiersEngine* qe ) = 0;
   /** set active add */
-  virtual void setActiveAdd() {}
+  virtual void setActiveAdd( bool val ) {}
 };/* class IMGenerator */
 
 class CandidateGenerator;
 
 class InstMatchGenerator : public IMGenerator {
 private:
+  bool d_needsReset;
   /** candidate generator */
   CandidateGenerator* d_cg;
   /** policy to use for matching */
@@ -108,7 +109,7 @@ public:
   int addTerm( Node f, Node t, QuantifiersEngine* qe );
 
   bool d_active_add;
-  void setActiveAdd();
+  void setActiveAdd( bool val );
 
   static InstMatchGenerator* mkInstMatchGenerator( Node pat, QuantifiersEngine* qe );
   static InstMatchGenerator* mkInstMatchGenerator( std::vector< Node >& pats, QuantifiersEngine* qe );
index 77df69456ca4bc984e2a3a45562a8ab32e23f281..38ee4a57f2c3dde424500f6b90c0d49adde12011 100644 (file)
@@ -197,6 +197,7 @@ void InstantiationEngine::check( Theory::Effort e ){
                          << d_quantEngine->getModel()->getNumAssertedQuantifiers() << std::endl;
     for( int i=0; i<(int)d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
       Node n = d_quantEngine->getModel()->getAssertedQuantifier( i );
+      //it is not active if we have found the skolemized negation is unsat
       if( options::cbqi() && hasAddedCbqiLemma( n ) ){
         Node cel = d_quantEngine->getTermDatabase()->getCounterexampleLiteral( n );
         bool active, value;
@@ -226,6 +227,9 @@ void InstantiationEngine::check( Theory::Effort e ){
           Debug("quantifiers") << ", ce is asserted";
         }
         Debug("quantifiers") << std::endl;
+      //it is not active if it corresponds to a rewrite rule: we will process in rewrite engine
+      }else if( n.hasAttribute(QRewriteRuleAttribute()) ){
+        d_quant_active[n] = false;
       }else{
         d_quant_active[n] = true;
         quantActive = true;
index 88fb7cd8fa81f0ef73647ee2322fdad0224407da..fbf3ce59c3b7166bf9a509868d8a3c7aeefe1fa6 100644 (file)
@@ -39,6 +39,10 @@ TheoryEngineModelBuilder( qe->getTheoryEngine() ), d_curr_model( c, NULL ), d_qe
   d_addedLemmas = 0;
 }
 
+bool QModelBuilder::isQuantifierActive( Node f ) {
+  return !f.hasAttribute(QRewriteRuleAttribute());
+}
+
 
 bool QModelBuilder::optUseModel() {
   return options::fmfModelBasedInst();
@@ -355,7 +359,8 @@ QModelBuilderIG::Statistics::~Statistics(){
 }
 
 bool QModelBuilderIG::isQuantifierActive( Node f ){
-  return ( d_considerAxioms || !f.getAttribute(AxiomAttribute()) ) && d_quant_sat.find( f )==d_quant_sat.end();
+  return !f.hasAttribute(QRewriteRuleAttribute()) &&
+         ( d_considerAxioms || !f.getAttribute(AxiomAttribute()) ) && d_quant_sat.find( f )==d_quant_sat.end();
 }
 
 bool QModelBuilderIG::isTermActive( Node n ){
index 7156129754a9ecbc4ca8a54445de7b0ab9ee6ff0..708688c6042f5202f109624ff70f90f20cf40d55 100644 (file)
@@ -37,7 +37,7 @@ public:
   QModelBuilder( context::Context* c, QuantifiersEngine* qe );
   virtual ~QModelBuilder(){}
   // is quantifier active?
-  virtual bool isQuantifierActive( Node f ) { return true; }
+  virtual bool isQuantifierActive( Node f );
   //do exhaustive instantiation
   virtual bool doExhaustiveInstantiation( FirstOrderModel * fm, Node f, int effort, int & lemmas ) { return false; }
   //whether to construct model
index 32deb9e4780f7daf61e2ba50da5318f0637de06d..0f756dcc0667e6d9f332dd0b8d79e9411cce3f70 100644 (file)
@@ -168,14 +168,6 @@ int ModelEngine::checkModel(){
       }
     }
   }
-  //full model checking: construct models for all functions
-  /*
-  if( d_fmc.isActive() ){
-    for (std::map< Node, uf::UfModelTreeGenerator >::iterator it = fm->d_uf_model_gen.begin(); it != fm->d_uf_model_gen.end(); ++it) {
-      d_fmc.getModel(fm, it->first);
-    }
-  }
-  */
   //compute the relevant domain if necessary
   //if( optUseRelevantDomain() ){
   //}
@@ -227,6 +219,7 @@ int ModelEngine::checkModel(){
 
 int ModelEngine::exhaustiveInstantiate( Node f, int effort ){
   int addedLemmas = 0;
+  //first check if the builder can do the exhaustive instantiation
   if( !d_builder->doExhaustiveInstantiation( d_quantEngine->getModel(), f, effort, addedLemmas ) ){
     Trace("inst-fmf-ei") << "Exhaustive instantiate " << f << ", effort = " << effort << "..." << std::endl;
     Debug("inst-fmf-ei") << "   Instantiation Constants: ";
index e830147892770863369947c6020e8dca982d950e..a0e42c425854b1197f19c357d368d781bbb9cac4 100644 (file)
@@ -24,8 +24,8 @@ option prenexQuant /--disable-prenex-quant bool :default true
 # Whether to variable-eliminate quantifiers.
 # For example, forall x y. ( P( x, y ) V x != c ) will be rewritten to
 #   forall y. P( c, y )
-option varElimQuant --var-elim-quant bool :default false
enable variable elimination of quantified formulas
+option varElimQuant /--disable-var-elim-quant bool :default true
disable simple variable elimination for quantified formulas
 
 # Whether to CNF quantifier bodies
 option cnfQuant --cnf-quant bool :default false
index 9f156b656957874f9030e3edef3be7b033e209e9..b08752169febc1b124a93a61600808f33a26c042 100644 (file)
@@ -307,7 +307,7 @@ Node QuantifiersRewriter::computeSimpleIteLift( Node body ) {
 }
 
 Node QuantifiersRewriter::computeVarElimination( Node body, std::vector< Node >& args, Node& ipl ){
-  Trace("var-elim-quant") << "Compute var elimination for " << body << std::endl;
+  Trace("var-elim-quant-debug") << "Compute var elimination for " << body << std::endl;
   QuantPhaseReq qpr( body );
   std::vector< Node > vars;
   std::vector< Node > subs;
diff --git a/src/theory/quantifiers/rewrite_engine.cpp b/src/theory/quantifiers/rewrite_engine.cpp
new file mode 100755 (executable)
index 0000000..5a35e38
--- /dev/null
@@ -0,0 +1,115 @@
+/*********************                                                        */\r
+/*! \file bounded_integers.cpp\r
+ ** \verbatim\r
+ ** Original author: Andrew Reynolds\r
+ ** This file is part of the CVC4 project.\r
+ ** Copyright (c) 2009-2013  New York University and The University of Iowa\r
+ ** See the file COPYING in the top-level source directory for licensing\r
+ ** information.\endverbatim\r
+ **\r
+ ** \brief Rewrite engine module\r
+ **\r
+ ** This class manages rewrite rules for quantifiers\r
+ **/\r
+\r
+#include "theory/quantifiers/rewrite_engine.h"\r
+#include "theory/quantifiers/quant_util.h"\r
+#include "theory/quantifiers/first_order_model.h"\r
+#include "theory/quantifiers/model_engine.h"\r
+#include "theory/quantifiers/options.h"\r
+#include "theory/quantifiers/inst_match_generator.h"\r
+\r
+using namespace CVC4;\r
+using namespace std;\r
+using namespace CVC4::theory;\r
+using namespace CVC4::theory::quantifiers;\r
+using namespace CVC4::kind;\r
+\r
+RewriteEngine::RewriteEngine( context::Context* c, QuantifiersEngine* qe ) : QuantifiersModule(qe) {\r
+\r
+}\r
+\r
+void RewriteEngine::check( Theory::Effort e ) {\r
+  if( e==Theory::EFFORT_FULL ){\r
+    //apply rewrite rules\r
+    int addedLemmas = 0;\r
+    for( unsigned i=0; i<d_rr_quant.size(); i++ ) {\r
+      addedLemmas += checkRewriteRule( d_rr_quant[i] );\r
+    }\r
+    Trace("rewrite-engine") << "Rewrite engine generated " << addedLemmas << " lemmas." << std::endl;\r
+    if (addedLemmas==0) {\r
+    }else{\r
+      //otherwise, the search will continue\r
+      d_quantEngine->flushLemmas( &d_quantEngine->getOutputChannel() );\r
+    }\r
+  }\r
+}\r
+\r
+int RewriteEngine::checkRewriteRule( Node f ) {\r
+  Trace("rewrite-engine-inst") << "Check " << f << "..." << std::endl;\r
+  int addedLemmas = 0;\r
+  //reset triggers\r
+  Node rr = f.getAttribute(QRewriteRuleAttribute());\r
+  if( d_rr_triggers.find(f)==d_rr_triggers.end() ){\r
+    std::vector< inst::Trigger * > triggers;\r
+    if( f.getNumChildren()==3 ){\r
+      for(unsigned i=0; i<f[2].getNumChildren(); i++ ){\r
+        Node pat = f[2][i];\r
+        std::vector< Node > nodes;\r
+        Trace("rewrite-engine-trigger") << "Trigger is : ";\r
+        for( int j=0; j<(int)pat.getNumChildren(); j++ ){\r
+          Node p = d_quantEngine->getTermDatabase()->getInstConstantNode( pat[j], f );\r
+          nodes.push_back( p );\r
+          Trace("rewrite-engine-trigger") << p << " " << p.getKind() << " ";\r
+        }\r
+        Trace("rewrite-engine-trigger") << std::endl;\r
+        Assert( inst::Trigger::isUsableTrigger( nodes, f ) );\r
+        inst::Trigger * tr = inst::Trigger::mkTrigger( d_quantEngine, f, nodes, 0, true, inst::Trigger::TR_MAKE_NEW, false );\r
+        tr->getGenerator()->setActiveAdd(false);\r
+        triggers.push_back( tr );\r
+      }\r
+    }\r
+    d_rr_triggers[f].insert( d_rr_triggers[f].end(), triggers.begin(), triggers.end() );\r
+  }\r
+  for( unsigned i=0; i<d_rr_triggers[f].size(); i++ ){\r
+    Trace("rewrite-engine-inst") << "Try trigger " << *d_rr_triggers[f][i] << std::endl;\r
+    d_rr_triggers[f][i]->resetInstantiationRound();\r
+    d_rr_triggers[f][i]->reset( Node::null() );\r
+    bool success;\r
+    do\r
+    {\r
+      InstMatch m;\r
+      success = d_rr_triggers[f][i]->getNextMatch( f, m );\r
+      if( success ){\r
+        //see if instantiation is true in the model\r
+        bool trueInModel = false;\r
+\r
+        if( !trueInModel ){\r
+          Trace("rewrite-engine-inst") << "Add instantiation : " << m << std::endl;\r
+          if( d_quantEngine->addInstantiation( f, m ) ){\r
+            addedLemmas++;\r
+            Trace("rewrite-engine-inst-debug") << "success" << std::endl;\r
+          }else{\r
+            Trace("rewrite-engine-inst-debug") << "failure." << std::endl;\r
+          }\r
+        }\r
+      }\r
+    }while(success);\r
+  }\r
+  Trace("rewrite-engine-inst") << "Rule " << f << " generated " << addedLemmas << " lemmas." << std::endl;\r
+  return addedLemmas;\r
+}\r
+\r
+void RewriteEngine::registerQuantifier( Node f ) {\r
+  if( f.hasAttribute(QRewriteRuleAttribute()) ){\r
+    Trace("rewrite-engine") << "Register quantifier " << f << std::endl;\r
+    Node rr = f.getAttribute(QRewriteRuleAttribute());\r
+    Trace("rewrite-engine") << "  rewrite rule is : " << rr << std::endl;\r
+    d_rr_quant.push_back( f );\r
+  }\r
+}\r
+\r
+void RewriteEngine::assertNode( Node n ) {\r
+\r
+}\r
+\r
diff --git a/src/theory/quantifiers/rewrite_engine.h b/src/theory/quantifiers/rewrite_engine.h
new file mode 100755 (executable)
index 0000000..5160af6
--- /dev/null
@@ -0,0 +1,51 @@
+/*********************                                                        */\r
+/*! \file bounded_integers.h\r
+** \verbatim\r
+** Original author: Andrew Reynolds\r
+** This file is part of the CVC4 project.\r
+** Copyright (c) 2009-2013  New York University and The University of Iowa\r
+** See the file COPYING in the top-level source directory for licensing\r
+** information.\endverbatim\r
+**\r
+** \brief This class manages integer bounds for quantifiers\r
+**/\r
+\r
+#include "cvc4_private.h"\r
+\r
+#ifndef __CVC4__REWRITE_ENGINE_H\r
+#define __CVC4__REWRITE_ENGINE_H\r
+\r
+#include "theory/quantifiers_engine.h"\r
+#include "theory/quantifiers/trigger.h"\r
+\r
+#include "context/context.h"\r
+#include "context/context_mm.h"\r
+#include "context/cdchunk_list.h"\r
+\r
+namespace CVC4 {\r
+namespace theory {\r
+namespace quantifiers {\r
+\r
+class RewriteEngine : public QuantifiersModule\r
+{\r
+  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;\r
+  typedef context::CDHashMap<Node, int, NodeHashFunction> NodeIntMap;\r
+  typedef context::CDHashMap<Node, Node, NodeHashFunction> NodeNodeMap;\r
+  std::vector< Node > d_rr_quant;\r
+  /** explicitly provided patterns */\r
+  std::map< Node, std::vector< inst::Trigger* > > d_rr_triggers;\r
+private:\r
+  int checkRewriteRule( Node f );\r
+public:\r
+  RewriteEngine( context::Context* c, QuantifiersEngine* qe );\r
+\r
+  void check( Theory::Effort e );\r
+  void registerQuantifier( Node f );\r
+  void assertNode( Node n );\r
+};\r
+\r
+}\r
+}\r
+}\r
+\r
+#endif
\ No newline at end of file
index 7b5df2ab84af695bc8bdafbec19d4a2ddfe07f5c..fb596455415d40dee764691e4a5b6492411eb669 100644 (file)
@@ -64,6 +64,11 @@ typedef expr::Attribute<HasBoundVarAttributeId, bool> HasBoundVarAttribute;
 struct HasBoundVarComputedAttributeId {};
 typedef expr::Attribute<HasBoundVarComputedAttributeId, bool> HasBoundVarComputedAttribute;
 
+//for rewrite rules
+struct QRewriteRuleAttributeId {};
+typedef expr::Attribute<QRewriteRuleAttributeId, Node> QRewriteRuleAttribute;
+
+
 class QuantifiersEngine;
 
 namespace inst{
index fea8ab6d5c8ec3d1806c037e901c05d3dc9f4acd..b71a1486caec1b21d65e990d4a4440c53a95973c 100644 (file)
@@ -44,7 +44,7 @@ d_quantEngine( qe ), d_f( f ){
         d_mg = new InstMatchGeneratorSimple( f, d_nodes[0] );
       }else{
         d_mg = InstMatchGenerator::mkInstMatchGenerator( d_nodes[0], qe );
-        d_mg->setActiveAdd();
+        d_mg->setActiveAdd(true);
       }
     }else{
       d_mg = new InstMatchGeneratorMulti( f, d_nodes, qe, matchOption );
@@ -53,7 +53,7 @@ d_quantEngine( qe ), d_f( f ){
     }
   }else{
     d_mg = InstMatchGenerator::mkInstMatchGenerator( d_nodes, qe );
-    d_mg->setActiveAdd();
+    d_mg->setActiveAdd(true);
   }
   if( d_nodes.size()==1 ){
     if( isSimpleTrigger( d_nodes[0] ) ){
@@ -301,7 +301,7 @@ Node Trigger::getIsUsableTrigger( Node n, Node f, bool pol, bool hasPol ) {
     }
   }
   bool usable = quantifiers::TermDb::getInstConstAttr(n)==f && isAtomicTrigger( n ) && isUsable( n, f );
-  Trace("usable") << n << " usable : " << usable << std::endl;
+  Trace("usable") << n << " usable : " << (quantifiers::TermDb::getInstConstAttr(n)==f) << " " << isAtomicTrigger( n ) << " " << isUsable( n, f ) << std::endl;
   if( usable ){
     return n;
   }else{
index c663e1aa2caeea4f71c25aa9d1282a2158c2d83e..94bc475d0afaac5d48b1a2af6a35a467f7028209 100644 (file)
@@ -28,6 +28,7 @@
 #include "theory/rewriterules/efficient_e_matching.h"
 #include "theory/rewriterules/rr_trigger.h"
 #include "theory/quantifiers/bounded_integers.h"
+#include "theory/quantifiers/rewrite_engine.h"
 
 using namespace std;
 using namespace CVC4;
@@ -62,9 +63,15 @@ d_lemmas_produced_c(u){
   }else{
     d_inst_engine = NULL;
   }
-  if( options::finiteModelFind() ){
+  bool reqModel = options::finiteModelFind() || options::rewriteRulesAsAxioms();
+  if( reqModel ){
     d_model_engine = new quantifiers::ModelEngine( c, this );
     d_modules.push_back( d_model_engine );
+  }else{
+    d_model_engine = NULL;
+  }
+
+  if( options::finiteModelFind() ){
     if( options::fmfBoundInt() ){
       d_bint = new quantifiers::BoundedIntegers( c, this );
       d_modules.push_back( d_bint );
@@ -72,9 +79,14 @@ d_lemmas_produced_c(u){
       d_bint = NULL;
     }
   }else{
-    d_model_engine = NULL;
     d_bint = NULL;
   }
+  if( options::rewriteRulesAsAxioms() ){
+    d_rr_engine = new quantifiers::RewriteEngine( c, this );
+    d_modules.push_back(d_rr_engine);
+  }else{
+    d_rr_engine = NULL;
+  }
 
   //options
   d_optInstCheckDuplicate = true;
index 2ff2100b2ed70f59d9d69734a7a020d0a4eaf217..40b043752a9c07baae5916815f5a4e46aa5fea8b 100644 (file)
@@ -60,11 +60,13 @@ public:
 };/* class QuantifiersModule */
 
 namespace quantifiers {
-  class InstantiationEngine;
-  class ModelEngine;
   class TermDb;
   class FirstOrderModel;
+  //modules
+  class InstantiationEngine;
+  class ModelEngine;
   class BoundedIntegers;
+  class RewriteEngine;
 }/* CVC4::theory::quantifiers */
 
 namespace inst {
@@ -88,10 +90,6 @@ private:
   TheoryEngine* d_te;
   /** vector of modules for quantifiers */
   std::vector< QuantifiersModule* > d_modules;
-  /** instantiation engine */
-  quantifiers::InstantiationEngine* d_inst_engine;
-  /** model engine */
-  quantifiers::ModelEngine* d_model_engine;
   /** equality query class */
   EqualityQueryQuantifiersEngine* d_eq_query;
   /** for computing relevance of quantifiers */
@@ -100,8 +98,14 @@ private:
   std::map< Node, QuantPhaseReq* > d_phase_reqs;
   /** efficient e-matcher */
   EfficientEMatcher* d_eem;
+  /** instantiation engine */
+  quantifiers::InstantiationEngine* d_inst_engine;
+  /** model engine */
+  quantifiers::ModelEngine* d_model_engine;
   /** bounded integers utility */
   quantifiers::BoundedIntegers * d_bint;
+  /** rewrite rules utility */
+  quantifiers::RewriteEngine * d_rr_engine;
 private:
   /** list of all quantifiers seen */
   std::vector< Node > d_quants;
index 446d30d21460f0f551656406347c76f58ed0a450..7e1d42bb28b96571326d6bedc76089341fdd2bd8 100644 (file)
@@ -232,7 +232,11 @@ void TheoryRewriteRules::addRewriteRule(const Node r)
     NodeBuilder<> patternListB(kind::INST_PATTERN_LIST);
     patternListB << static_cast<Node>(patternB);
     forallB << static_cast<Node>(patternListB);
-    getOutputChannel().lemma((Node) forallB);
+    Node lem = (Node) forallB;
+    lem = Rewriter::rewrite(lem);
+    QRewriteRuleAttribute qra;
+    lem.setAttribute(qra,r);
+    getOutputChannel().lemma(lem);
     return;
   }