Don't theory-preprocess under quantifiers; but DO theory-preprocess lemmas (resolves...
authorMorgan Deters <mdeters@cs.nyu.edu>
Mon, 17 Feb 2014 23:59:39 +0000 (18:59 -0500)
committerMorgan Deters <mdeters@cs.nyu.edu>
Tue, 4 Mar 2014 12:56:20 +0000 (07:56 -0500)
17 files changed:
src/prop/prop_engine.cpp
src/theory/arith/theory_arith.cpp
src/theory/output_channel.h
src/theory/quantifiers/bounded_integers.cpp
src/theory/quantifiers/instantiation_engine.cpp
src/theory/quantifiers/options
src/theory/quantifiers/symmetry_breaking.cpp
src/theory/quantifiers/theory_quantifiers.cpp
src/theory/quantifiers/theory_quantifiers.h
src/theory/quantifiers_engine.cpp
src/theory/rewriterules/theory_rewriterules.h
src/theory/theory_engine.cpp
src/theory/theory_engine.h
src/theory/theory_test_utils.h
src/util/statistics_registry.h
test/unit/theory/theory_engine_white.h
test/unit/theory/theory_white.h

index 036877b6a06b87ae1fcee63cfd3a117fc3014a45..2a2a60391f0e7f16f9f72ea7c1f52b32ae6339b0 100644 (file)
@@ -111,10 +111,6 @@ void PropEngine::assertLemma(TNode node, bool negated, bool removable) {
   //Assert(d_inCheckSat, "Sat solver should be in solve()!");
   Debug("prop::lemmas") << "assertLemma(" << node << ")" << endl;
 
-  if(Dump.isOn("lemmas")) {
-    Dump("lemmas") << AssertCommand(node.toExpr());
-  }
-
   // Assert as removable
   d_cnfStream->convertAndAssert(node, removable, negated);
 }
index 239385bfc35f208fa7b6813943945abf5445d997..85d9d1f9b46612829e2cd0f91519bc922df38846 100644 (file)
@@ -52,7 +52,7 @@ void TheoryArith::addSharedTerm(TNode n){
 }
 
 Node TheoryArith::ppRewrite(TNode atom) {
-  CodeTimer timer(d_ppRewriteTimer);
+  CodeTimer timer(d_ppRewriteTimer, /* allow_reentrant = */ true);
   return d_internal->ppRewrite(atom);
 }
 
index 44b89e8cbc3e896b3fa8ad17a49346cb95863a75..51187b7dd3a33b6583968e9c887188a08e679b50 100644 (file)
@@ -113,10 +113,12 @@ public:
    *
    * @param n - a theory lemma valid at decision level 0
    * @param removable - whether the lemma can be removed at any point
+   * @param preprocess - whether to apply more aggressive preprocessing
    * @return the "status" of the lemma, including user level at which
    * the lemma resides; the lemma will be removed when this user level pops
    */
-  virtual LemmaStatus lemma(TNode n, bool removable = false)
+  virtual LemmaStatus lemma(TNode n, bool removable = false,
+                            bool preprocess = false)
     throw(TypeCheckingExceptionPrivate, AssertionException) = 0;
 
   /**
index 5ad4cef92a91af1a76aa0fe8df1e93726e1d4c86..78f98980712520dd040a938f77bb8e692352c3f8 100644 (file)
@@ -363,7 +363,7 @@ void BoundedIntegers::getBounds( Node f, Node v, RepSetIterator * rsi, Node & l,
       nn = nn.substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );
       Node lem = NodeManager::currentNM()->mkNode( LEQ, nn, d_range[f][v] );
       Trace("bound-int-lemma") << "*** Add lemma to minimize instantiated non-ground term " << lem << std::endl;
-      d_quantEngine->getOutputChannel().lemma(lem);
+      d_quantEngine->getOutputChannel().lemma(lem, false, true);
       l = Node::null();
       u = Node::null();
       return;
index 9a3c07c5ee12c23a1c993cbab3c14a163499649a..99dc29bf8f16d6768fb61b1bb84f2b56434c8bdd 100644 (file)
@@ -92,7 +92,7 @@ bool InstantiationEngine::doInstantiationRound( Theory::Effort effort ){
           nb << f << ceLit;
           Node lem = nb;
           Trace("cbqi") << "Counterexample lemma : " << lem << std::endl;
-          d_quantEngine->getOutputChannel().lemma( lem );
+          d_quantEngine->getOutputChannel().lemma( lem, false, true );
           addedLemma = true;
         }
       }
index 06d11f70f42bcfddb348c70d4c49e0dcad678ee7..6d333521b76c3772b1f5bcfca98496b72a9a5bf3 100644 (file)
@@ -94,7 +94,7 @@ option flipDecision --flip-decision/ bool :default false
 option internalReps /--disable-quant-internal-reps bool :default true
  disables instantiating with representatives chosen by quantifiers engine
 
-option finiteModelFind --finite-model-find bool :default false :read-write
+option finiteModelFind finite-model-find --finite-model-find bool :default false :read-write
  use finite model finding heuristic for quantifier instantiation
 
 option mbqiMode --mbqi=MODE CVC4::theory::quantifiers::MbqiMode :read-write :default CVC4::theory::quantifiers::MBQI_DEFAULT :include "theory/quantifiers/modes.h" :handler CVC4::theory::quantifiers::stringToMbqiMode :handler-include "theory/quantifiers/options_handlers.h" :predicate CVC4::theory::quantifiers::checkMbqiMode :predicate-include "theory/quantifiers/options_handlers.h"
index 66a3ac79fcb9be099706ab379dadad55fe254cec..0023b05bc8bcdee8bd9f88f06b82b8a2a42b6699 100644 (file)
@@ -298,7 +298,7 @@ bool SubsortSymmetryBreaker::check( Theory::Effort level ) {
   //flush pending lemmas
   if( !d_pending_lemmas.empty() ){
     for( unsigned i=0; i<d_pending_lemmas.size(); i++ ){
-      getStrongSolver()->getOutputChannel().lemma( d_pending_lemmas[i] );
+      getStrongSolver()->getOutputChannel().lemma( d_pending_lemmas[i], false, true );
       ++( getStrongSolver()->d_statistics.d_sym_break_lemmas );
     }
     d_pending_lemmas.clear();
index 6a3a6fca1d2ea175769c5598e82b9c5ea58b589b..19a915ae9a61be5c2656717460056886eb6d9cd2 100644 (file)
@@ -164,7 +164,7 @@ void TheoryQuantifiers::assertExistential( Node n ){
       nb << n[0] << body.notNode();
       Node lem = nb;
       Trace("quantifiers-sk") << "Skolemize lemma : " << lem << std::endl;
-      d_out->lemma( lem );
+      d_out->lemma( lem, false, true );
       d_skolemized[n] = true;
     }
   }
index 8ace5f181b15e1b30936aef0a39f37b69bce4092..84b65cacd9774e5328d61d67ca3fd0661fa24b4b 100644 (file)
@@ -73,6 +73,7 @@ public:
   bool flipDecision();
   void setUserAttribute( const std::string& attr, Node n );
   eq::EqualityEngine* getMasterEqualityEngine() { return d_masterEqualityEngine; }
+  bool ppDontRewriteSubterm(TNode atom) { return atom.getKind() == kind::FORALL || atom.getKind() == kind::EXISTS; }
 private:
   void assertUniversal( Node n );
   void assertExistential( Node n );
index 36410bd5080e80afa4d48a3474fd124b3f270bd6..41f53740a968d67357b8f75e298032153f0c6284 100644 (file)
@@ -458,7 +458,7 @@ bool QuantifiersEngine::addLemma( Node lem, bool doCache ){
     Debug("inst-engine-debug") << "Adding lemma : " << lem << std::endl;
     lem = Rewriter::rewrite(lem);
     if( d_lemmas_produced_c.find( lem )==d_lemmas_produced_c.end() ){
-      //d_curr_out->lemma( lem );
+      //d_curr_out->lemma( lem, false, true );
       d_lemmas_produced_c[ lem ] = true;
       d_lemmas_waiting.push_back( lem );
       Debug("inst-engine-debug") << "Added lemma : " << lem << std::endl;
@@ -567,7 +567,7 @@ void QuantifiersEngine::flushLemmas( OutputChannel* out ){
     //take default output channel if none is provided
     d_hasAddedLemma = true;
     for( int i=0; i<(int)d_lemmas_waiting.size(); i++ ){
-      out->lemma( d_lemmas_waiting[i] );
+      out->lemma( d_lemmas_waiting[i], false, true );
     }
     d_lemmas_waiting.clear();
   }
index 30e6f97098f695486c1054438eb2a5265a31d9db..2cefe7f076583e6f5beae1231fd1cd3a528257de 100644 (file)
@@ -211,7 +211,7 @@ private:
 
   Theory::PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions);
 
-  bool ppDontRewriteSubterm(TNode atom){ return true; }
+  bool ppDontRewriteSubterm(TNode atom) { return true; }
 
 
  private:
index 63024e5d505417a8a07d6aed33ac448a60489076..c29177b49a228459e9b3e95ffee744b5db731f58 100644 (file)
@@ -475,7 +475,7 @@ void TheoryEngine::combineTheories() {
 
     // We need to split on it
     Debug("sharing") << "TheoryEngine::combineTheories(): requesting a split " << endl;
-    lemma(equality.orNode(equality.notNode()), false, false, carePair.theory);
+    lemma(equality.orNode(equality.notNode()), false, false, false, carePair.theory);
   }
 }
 
@@ -779,7 +779,7 @@ Node TheoryEngine::ppTheoryRewrite(TNode term) {
 
   Node newTerm;
   if (theoryOf(term)->ppDontRewriteSubterm(term)) {
-    newTerm = term;
+    newTerm = Rewriter::rewrite(term);
   } else {
     NodeBuilder<> newNode(term.getKind());
     if (term.getMetaKind() == kind::metakind::PARAMETERIZED) {
@@ -1320,7 +1320,7 @@ void TheoryEngine::ensureLemmaAtoms(const std::vector<TNode>& atoms, theory::The
   }
 }
 
-theory::LemmaStatus TheoryEngine::lemma(TNode node, bool negated, bool removable, theory::TheoryId atomsTo) {
+theory::LemmaStatus TheoryEngine::lemma(TNode node, bool negated, bool removable, bool preprocess, theory::TheoryId atomsTo) {
 
   // Do we need to check atoms
   if (atomsTo != theory::THEORY_LAST) {
@@ -1344,15 +1344,18 @@ theory::LemmaStatus TheoryEngine::lemma(TNode node, bool negated, bool removable
     options::lemmaOutputChannel()->notifyNewLemma(node.toExpr());
   }
 
+  // Run theory preprocessing, maybe
+  Node ppNode = preprocess ? this->preprocess(node) : Node(node);
+
   // Remove the ITEs
   std::vector<Node> additionalLemmas;
   IteSkolemMap iteSkolemMap;
-  additionalLemmas.push_back(node);
+  additionalLemmas.push_back(ppNode);
   d_iteRemover.run(additionalLemmas, iteSkolemMap);
   additionalLemmas[0] = theory::Rewriter::rewrite(additionalLemmas[0]);
 
   if(Debug.isOn("lemma-ites")) {
-    Debug("lemma-ites") << "removed ITEs from lemma: " << node << endl;
+    Debug("lemma-ites") << "removed ITEs from lemma: " << ppNode << endl;
     Debug("lemma-ites") << " + now have the following "
                         << additionalLemmas.size() << " lemma(s):" << endl;
     for(std::vector<Node>::const_iterator i = additionalLemmas.begin();
@@ -1417,11 +1420,11 @@ void TheoryEngine::conflict(TNode conflict, TheoryId theoryId) {
     Node fullConflict = mkExplanation(explanationVector);
     Debug("theory::conflict") << "TheoryEngine::conflict(" << conflict << ", " << theoryId << "): full = " << fullConflict << endl;
     Assert(properConflict(fullConflict));
-    lemma(fullConflict, true, true, THEORY_LAST);
+    lemma(fullConflict, true, true, false, THEORY_LAST);
   } else {
     // When only one theory, the conflict should need no processing
     Assert(properConflict(conflict));
-    lemma(conflict, true, true, THEORY_LAST);
+    lemma(conflict, true, true, false, THEORY_LAST);
   }
 }
 
index d5de8e3b2f96ba70b32c504c79d41149ca7c57b4..db31ef9b77e2c437771f0b3a17d7bdd2d8e31cda 100644 (file)
@@ -292,18 +292,18 @@ class TheoryEngine {
       return d_engine->propagate(literal, d_theory);
     }
 
-    theory::LemmaStatus lemma(TNode lemma, bool removable = false) throw(TypeCheckingExceptionPrivate, AssertionException) {
+    theory::LemmaStatus lemma(TNode lemma, bool removable = false, bool preprocess = false) throw(TypeCheckingExceptionPrivate, AssertionException) {
       Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
       ++ d_statistics.lemmas;
       d_engine->d_outputChannelUsed = true;
-      return d_engine->lemma(lemma, false, removable, theory::THEORY_LAST);
+      return d_engine->lemma(lemma, false, removable, preprocess, theory::THEORY_LAST);
     }
 
     theory::LemmaStatus splitLemma(TNode lemma, bool removable = false) throw(TypeCheckingExceptionPrivate, AssertionException) {
       Trace("theory::lemma") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
       ++ d_statistics.lemmas;
       d_engine->d_outputChannelUsed = true;
-      return d_engine->lemma(lemma, false, removable, d_theory);
+      return d_engine->lemma(lemma, false, removable, false, d_theory);
     }
 
     void demandRestart() throw(TypeCheckingExceptionPrivate, AssertionException) {
@@ -451,7 +451,7 @@ class TheoryEngine {
    * @param removable can the lemma be remove (restrictions apply)
    * @param needAtoms if not THEORY_LAST, then
    */
-  theory::LemmaStatus lemma(TNode node, bool negated, bool removable, theory::TheoryId atomsTo);
+  theory::LemmaStatus lemma(TNode node, bool negated, bool removable, bool preprocess, theory::TheoryId atomsTo);
 
   /** Enusre that the given atoms are send to the given theory */
   void ensureLemmaAtoms(const std::vector<TNode>& atoms, theory::TheoryId theory);
index e4921b163d3abe2cf6533311ca913cc5e243781d..28a749a4182ebc125574411bfbcdcecf5ed95878 100644 (file)
@@ -87,7 +87,7 @@ public:
     push(PROPAGATE_AS_DECISION, n);
   }
 
-  LemmaStatus lemma(TNode n, bool removable) throw(AssertionException) {
+  LemmaStatus lemma(TNode n, bool removable, bool preprocess) throw(AssertionException) {
     push(LEMMA, n);
     return LemmaStatus(Node::null(), 0);
   }
index bd33557d9d9e74b42ab1b78452320530b34a5d8e..8246bfdd23c0aafdcf957e2e04f8dfee0353b7ef 100644 (file)
@@ -824,6 +824,7 @@ public:
  */
 class CodeTimer {
   TimerStat& d_timer;
+  bool d_reentrant;
 
   /** Private copy constructor undefined (no copy permitted). */
   CodeTimer(const CodeTimer& timer) CVC4_UNDEFINED;
@@ -831,11 +832,15 @@ class CodeTimer {
   CodeTimer& operator=(const CodeTimer& timer) CVC4_UNDEFINED;
 
 public:
-  CodeTimer(TimerStat& timer) : d_timer(timer) {
-    d_timer.start();
+  CodeTimer(TimerStat& timer, bool allow_reentrant = false) : d_timer(timer), d_reentrant(false) {
+    if(!allow_reentrant || !(d_reentrant = d_timer.running())) {
+      d_timer.start();
+    }
   }
   ~CodeTimer() {
-    d_timer.stop();
+    if(!d_reentrant) {
+      d_timer.stop();
+    }
   }
 };/* class CodeTimer */
 
index 803b245274786218d0c823063d836a3b2fa0e2ee..e32e498010864ad7e0078b9c9db155a2723dc5f4 100644 (file)
@@ -58,7 +58,7 @@ class FakeOutputChannel : public OutputChannel {
   void propagateAsDecision(TNode n) throw(AssertionException) {
     Unimplemented();
   }
-  LemmaStatus lemma(TNode n, bool removable) throw(AssertionException) {
+  LemmaStatus lemma(TNode n, bool removable, bool preprocess) throw(AssertionException) {
     Unimplemented();
   }
   void requirePhase(TNode, bool) throw(AssertionException) {
index e2dfcc46467042e5599f3cb9054f9b0973620df6..3259381ad7061b872a4661df154525232fd2044e 100644 (file)
@@ -70,7 +70,7 @@ public:
     // ignore
   }
 
-  LemmaStatus lemma(TNode n, bool removable)
+  LemmaStatus lemma(TNode n, bool removable = false, bool preprocess = false)
     throw(AssertionException) {
     push(LEMMA, n);
     return LemmaStatus(Node::null(), 0);
@@ -301,7 +301,7 @@ public:
 
   void testOutputChannel() {
     Node n = atom0.orNode(atom1);
-    d_outputChannel.lemma(n, false);
+    d_outputChannel.lemma(n);
     d_outputChannel.split(atom0);
     Node s = atom0.orNode(atom0.notNode());
     TS_ASSERT_EQUALS(d_outputChannel.d_callHistory.size(), 2u);