* changing the bitblast-eager to bitblast on pre-register
authorDejan Jovanović <dejan@cs.nyu.edu>
Wed, 3 Apr 2013 21:55:58 +0000 (17:55 -0400)
committerDejan Jovanović <dejan@cs.nyu.edu>
Wed, 3 Apr 2013 21:55:58 +0000 (17:55 -0400)
* the newVar interface of the sat solver now changed to include (isTheoryLiteral, preRegister, canEliminate)
* when bitblast-eager all bv atoms are (theory=false, prereg = true, canelim = true)
* bitblast-eager implies decision=internal

16 files changed:
src/prop/bvminisat/bvminisat.cpp
src/prop/bvminisat/bvminisat.h
src/prop/cnf_stream.cpp
src/prop/cnf_stream.h
src/prop/minisat/core/Solver.cc
src/prop/minisat/core/Solver.h
src/prop/minisat/minisat.cpp
src/prop/minisat/minisat.h
src/prop/minisat/simp/SimpSolver.cc
src/prop/minisat/simp/SimpSolver.h
src/prop/sat_solver.h
src/smt/smt_engine.cpp
src/theory/bv/bitblaster.cpp
src/theory/bv/bv_subtheory_bitblast.cpp
src/theory/bv/bv_subtheory_bitblast.h
src/theory/bv/theory_bv.cpp

index 032788806537c270c50c0010e297b09dfbda13d9..6bbe4bb3edf895c4d07c2523ca38fb7817bd9673 100644 (file)
@@ -88,8 +88,8 @@ void BVMinisatSatSolver::popAssumption() {
   d_minisat->popAssumption();
 }
 
-SatVariable BVMinisatSatSolver::newVar(bool freeze){
-  return d_minisat->newVar(true, true, freeze);
+SatVariable BVMinisatSatSolver::newVar(bool isTheoryAtom, bool preRegister, bool canErase){
+  return d_minisat->newVar(true, true, !canErase);
 }
 
 void BVMinisatSatSolver::markUnremovable(SatLiteral lit){
index 0dd208088b0b3df5b313fc592587e45e4424bafd..ebf4a44b48f8f0477df042a828751ec81e5e46de 100644 (file)
@@ -80,7 +80,7 @@ public:
 
   SatValue propagate();
 
-  SatVariable newVar(bool theoryAtom = false);
+  SatVariable newVar(bool isTheoryAtom = false, bool preRegister = false, bool canErase = true);
 
   SatVariable trueVar() { return d_minisat->trueVar(); }
   SatVariable falseVar() { return d_minisat->falseVar(); }
index 983669da39bc73468e2080786e7b0cde1346eaa5..4be58bdefd70eac92aa067681ebba0879f365a84 100644 (file)
@@ -26,6 +26,7 @@
 #include "expr/command.h"
 #include "expr/expr.h"
 #include "prop/theory_proxy.h"
+#include "theory/bv/options.h"
 
 #include <queue>
 
@@ -151,8 +152,8 @@ void TseitinCnfStream::ensureLiteral(TNode n) {
   Debug("ensureLiteral") << "CnfStream::ensureLiteral(): out lit is " << lit << std::endl;
 }
 
-SatLiteral CnfStream::newLiteral(TNode node, bool theoryLiteral) {
-  Debug("cnf") << "newLiteral(" << node << ", " << theoryLiteral << ")" << endl;
+SatLiteral CnfStream::newLiteral(TNode node, bool isTheoryAtom, bool preRegister, bool canEliminate) {
+  Debug("cnf") << "newLiteral(" << node << ", " << isTheoryAtom << ")" << endl;
   Assert(node.getKind() != kind::NOT);
 
   // Get the literal for this node
@@ -166,7 +167,7 @@ SatLiteral CnfStream::newLiteral(TNode node, bool theoryLiteral) {
         lit = SatLiteral(d_satSolver->falseVar());
       }
     } else {
-      lit = SatLiteral(d_satSolver->newVar(theoryLiteral));
+      lit = SatLiteral(d_satSolver->newVar(isTheoryAtom, preRegister, canEliminate));
     }
     d_nodeToLiteralMap.insert(node, lit);
     d_nodeToLiteralMap.insert(node.notNode(), ~lit);
@@ -175,7 +176,7 @@ SatLiteral CnfStream::newLiteral(TNode node, bool theoryLiteral) {
   }
 
   // If it's a theory literal, need to store it for back queries
-  if ( theoryLiteral || d_fullLitToNodeMap ||
+  if ( isTheoryAtom || d_fullLitToNodeMap ||
        ( CVC4_USE_REPLAY && options::replayLog() != NULL ) ||
        (Dump.isOn("clauses")) ) {
 
@@ -184,7 +185,7 @@ SatLiteral CnfStream::newLiteral(TNode node, bool theoryLiteral) {
   }
 
   // If a theory literal, we pre-register it
-  if (theoryLiteral) {
+  if (preRegister) {
     bool backup = d_removable;
     d_registrar->preRegister(node);
     d_removable = backup;
@@ -214,13 +215,27 @@ SatLiteral CnfStream::convertAtom(TNode node) {
 
   Assert(!hasLiteral(node), "atom already mapped!");
 
+  bool theoryLiteral = false;
+  bool canEliminate = true;
+  bool preRegister = false;
+
   // Is this a variable add it to the list
   if (node.isVar()) {
     d_booleanVariables.push_back(node);
+  } else {
+    theoryLiteral = true;
+    canEliminate = false;
+    preRegister = true;
+
+    if (options::bitvectorEagerBitblast() && theory::Theory::theoryOf(node) == theory::THEORY_BV) {
+      // All BV atoms are treated as boolean except for equality
+      theoryLiteral = false;
+      canEliminate = true;
+    }
   }
 
   // Make a new literal (variables are not considered theory literals)
-  SatLiteral lit = newLiteral(node, !node.isVar());
+  SatLiteral lit = newLiteral(node, theoryLiteral, preRegister, canEliminate);
 
   // Return the resulting literal
   return lit;
index cbcca5e851e9151c5502ce0d819567514741631c..1c66be91185a8c2ac033266d84d6e66ea2bb93c7 100644 (file)
@@ -146,11 +146,12 @@ protected:
    * Acquires a new variable from the SAT solver to represent the node
    * and inserts the necessary data it into the mapping tables.
    * @param node a formula
-   * @param theoryLiteral whether this literal a theory literal (and
-   * therefore the theory is to be informed when set to true/false)
+   * @param isTheoryAtom is this a theory atom that needs to be asserted to theory
+   * @param preRegister whether to preregister the atom with the theory
+   * @param canEliminate whether the sat solver can safely eliminate this variable
    * @return the literal corresponding to the formula
    */
-  SatLiteral newLiteral(TNode node, bool theoryLiteral = false);
+  SatLiteral newLiteral(TNode node, bool isTheoryAtom = false, bool preRegister = false, bool canEliminate = true);
 
   /**
    * Constructs a new literal for an atom and returns it.  Calls
index f7d67d445ed6f5db1bc22d826fbbef771793de2e..c7f1780b65814c008138d368e0a99a61e9873464 100644 (file)
@@ -150,7 +150,7 @@ Solver::~Solver()
 // Creates a new SAT variable in the solver. If 'decision_var' is cleared, variable will not be
 // used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
 //
-Var Solver::newVar(bool sign, bool dvar, bool theoryAtom)
+Var Solver::newVar(bool sign, bool dvar, bool isTheoryAtom, bool preRegister, bool canErase)
 {
     int v = nVars();
 
@@ -163,12 +163,12 @@ Var Solver::newVar(bool sign, bool dvar, bool theoryAtom)
     polarity .push(sign);
     decision .push();
     trail    .capacity(v+1);
-    theory   .push(theoryAtom);
+    theory   .push(isTheoryAtom);
 
     setDecisionVar(v, dvar);
 
     // If the variable is introduced at non-zero level, we need to reintroduce it on backtracks
-    if (theoryAtom) {
+    if (preRegister) {
       variables_to_register.push(VarIntroInfo(v, decisionLevel()));
     }
 
index 0dad68a0891afc860b08e28da1d13d08b30562d1..9338f9b557ad4af9ea09766c30df84dcbe6eccd2 100644 (file)
@@ -117,7 +117,7 @@ public:
 
     // Problem specification:
     //
-    Var     newVar    (bool polarity = true, bool dvar = true, bool theoryAtom = false); // Add a new variable with parameters specifying variable mode.
+    Var     newVar    (bool polarity = true, bool dvar = true, bool isTheoryAtom = false, bool preRegister = false, bool canErase = true); // Add a new variable with parameters specifying variable mode.
     Var     trueVar() const { return varTrue; }
     Var     falseVar() const { return varFalse; }
 
index 886dc0f721674c257d8b4d9ae8045d3ff0c9573c..960f2ad620c6c782445fa2e82054ca9726f148e4 100644 (file)
@@ -140,8 +140,8 @@ void MinisatSatSolver::addClause(SatClause& clause, bool removable) {
   d_minisat->addClause(minisat_clause, removable);
 }
 
-SatVariable MinisatSatSolver::newVar(bool theoryAtom) {
-  return d_minisat->newVar(true, true, theoryAtom);
+SatVariable MinisatSatSolver::newVar(bool isTheoryAtom, bool preRegister, bool canErase) {
+  return d_minisat->newVar(true, true, isTheoryAtom, preRegister, canErase);
 }
 
 SatValue MinisatSatSolver::solve(unsigned long& resource) {
index 723f257f7f8c51afe7a98758473bbcceaf36e773..37e471846f9835d4745509786619e2a94886db2b 100644 (file)
@@ -57,7 +57,7 @@ public:
 
   void addClause(SatClause& clause, bool removable);
 
-  SatVariable newVar(bool theoryAtom = false);
+  SatVariable newVar(bool isTheoryAtom, bool preRegister, bool canErase);
   SatVariable trueVar() { return d_minisat->trueVar(); }
   SatVariable falseVar() { return d_minisat->falseVar(); }
 
index ed2dc04b9b9bfd3bc406f61c3a945c15b7795740..9c3e59954e38ea9148e6167d10afbefd606c75c5 100644 (file)
@@ -95,11 +95,11 @@ SimpSolver::~SimpSolver()
 }
 
 
-Var SimpSolver::newVar(bool sign, bool dvar, bool theoryAtom) {
-    Var v = Solver::newVar(sign, dvar,theoryAtom);
+Var SimpSolver::newVar(bool sign, bool dvar, bool isTheoryAtom, bool preRegister, bool canErase) {
+    Var v = Solver::newVar(sign, dvar, isTheoryAtom, preRegister, canErase);
 
     if (use_simplification){
-        frozen    .push((char)theoryAtom);
+        frozen    .push((char)(!canErase));
         eliminated.push((char)false);
         n_occ     .push(0);
         n_occ     .push(0);
index e9116001f69d3aacf371ddab3d35adf4cc6f9f91..878d799a5b72af33e1c9050d03b379b15d59bd80 100644 (file)
@@ -46,7 +46,7 @@ class SimpSolver : public Solver {
 
     // Problem specification:
     //
-    Var     newVar    (bool polarity = true, bool dvar = true, bool theoryAtom = false);
+    Var     newVar    (bool polarity = true, bool dvar = true, bool isTheoryAtom = false, bool preRegister = false, bool canErase = true);
     bool    addClause (const vec<Lit>& ps, bool removable);
     bool    addEmptyClause(bool removable);                  // Add the empty clause to the solver.
     bool    addClause (Lit p, bool removable);               // Add a unit clause to the solver.
index d55788298ebbf5ac6294472f968f9f7fd8b7bd5b..18a1dcf68583705da0b6beff338b943afdcee462 100644 (file)
@@ -40,8 +40,14 @@ public:
   /** Assert a clause in the solver. */
   virtual void addClause(SatClause& clause, bool removable) = 0;
 
-  /** Create a new boolean variable in the solver. */
-  virtual SatVariable newVar(bool theoryAtom = false) = 0;
+  /**
+   * Create a new boolean variable in the solver.
+   * @param isTheoryAtom is this a theory atom that needs to be asserted to theory
+   * @param preRegister whether to preregister the atom with the theory
+   * @param canErase whether the sat solver can safely eliminate this variable
+   *
+   */
+  virtual SatVariable newVar(bool isTheoryAtom, bool preRegister, bool canErase) = 0;
 
   /** Create a new (or return an existing) boolean variable representing the constant true */
   virtual SatVariable trueVar() = 0;
index 18636a486ec28ab6da989dbb2af40a43922787f7..55000c94d3919885dee55e0d0070aaf93d791e91 100644 (file)
@@ -59,6 +59,7 @@
 #include "theory/substitutions.h"
 #include "theory/uf/options.h"
 #include "theory/arith/options.h"
+#include "theory/bv/options.h"
 #include "theory/theory_traits.h"
 #include "theory/logic_info.h"
 #include "theory/options.h"
@@ -674,6 +675,11 @@ void SmtEngine::finalOptionsAreSet() {
     return;
   }
 
+  if (options::bitvectorEagerBitblast()) {
+    // Eager solver should use the internal decision strategy
+    options::decisionMode.set(DECISION_STRATEGY_INTERNAL);
+  }
+
   if(options::checkModels()) {
     if(! options::produceModels()) {
       Notice() << "SmtEngine: turning on produce-models to support check-model" << endl;
index cf841bb5656132f41cdc2b0f8779fbddf7d61eda..ad62ade3859cbe4a5e90b90228ebd46562b56fff 100644 (file)
@@ -104,6 +104,7 @@ void Bitblaster::bbAtom(TNode node) {
     d_bitblastedAtoms.insert(node);
   } else {
     d_bvOutput->lemma(atom_definition, false);
+    d_bitblastedAtoms.insert(node);
   }
 }
 
index 237b04172b9b39cfb71202d3f46c1b2fa03a96e1..d8a7845445dff5563f537094effed44579865b28 100644 (file)
@@ -54,7 +54,11 @@ void BitblastSolver::preRegister(TNode node) {
        node.getKind() == kind::BITVECTOR_SLT ||
        node.getKind() == kind::BITVECTOR_SLE) &&
       !d_bitblaster->hasBBAtom(node)) {
-    d_bitblastQueue.push_back(node);
+    if (options::bitvectorEagerBitblast()) {
+      d_bitblaster->bbAtom(node);
+    } else {
+      d_bitblastQueue.push_back(node);
+    }
   }
 }
 
@@ -62,29 +66,23 @@ void BitblastSolver::explain(TNode literal, std::vector<TNode>& assumptions) {
   d_bitblaster->explain(literal, assumptions);
 }
 
+void BitblastSolver::bitblastQueue() {
+  while (!d_bitblastQueue.empty()) {
+    TNode atom = d_bitblastQueue.front();
+    d_bitblaster->bbAtom(atom);
+    d_bitblastQueue.pop();
+  }
+}
 
 bool BitblastSolver::check(Theory::Effort e) {
   Debug("bv-bitblast") << "BitblastSolver::check (" << e << ")\n"; 
+  Assert(!options::bitvectorEagerBitblast());
+
   ++(d_statistics.d_numCallstoCheck); 
-  //// Eager bit-blasting
-  if (options::bitvectorEagerBitblast()) {
-    while (!done()) {
-      TNode assertion = get(); 
-      TNode atom = assertion.getKind() == kind::NOT ? assertion[0] : assertion;
-      if (atom.getKind() != kind::BITVECTOR_BITOF) {
-        d_bitblaster->bbAtom(atom);
-      }
-      return true;
-    }
-  }
 
   //// Lazy bit-blasting
   // bit-blast enqueued nodes
-  while (!d_bitblastQueue.empty()) {
-    TNode atom = d_bitblastQueue.front();
-    d_bitblaster->bbAtom(atom);
-    d_bitblastQueue.pop();
-  }
+  bitblastQueue();
 
   // Processing assertions  
   while (!done()) {
index 1eef61daf2d01431793b2cd1f1d99917dbc39c83..1fab621cded1d592c7a4f3b501569f10dc042aba 100644 (file)
@@ -52,6 +52,7 @@ public:
   void collectModelInfo(TheoryModel* m); 
   Node getModelValue(TNode node);
   bool isComplete() { return true; }
+  void bitblastQueue();
 };
 
 }
index 228a4d8a37e0151978c9bbf017497d45eb67a05f..433223308b08d217fb91d6f6e945dafdce82b19d 100644 (file)
@@ -102,6 +102,7 @@ void TheoryBV::preRegisterTerm(TNode node) {
 
   if (options::bitvectorEagerBitblast()) {
     // don't use the equality engine in the eager bit-blasting
+    d_subtheoryMap[SUB_BITBLAST]->preRegister(node);
     return;
   }
   for (unsigned i = 0; i < d_subtheories.size(); ++i) {
@@ -124,6 +125,10 @@ void TheoryBV::sendConflict() {
 void TheoryBV::check(Effort e)
 {
   Debug("bitvector") << "TheoryBV::check(" << e << ")" << std::endl;
+  if (options::bitvectorEagerBitblast()) {
+    return;
+  }
+
   if (Theory::fullEffort(e)) {
     ++(d_statistics.d_numCallsToCheckFullEffort); 
   } else {
@@ -186,6 +191,10 @@ Node TheoryBV::getModelValue(TNode var) {
 void TheoryBV::propagate(Effort e) {
   Debug("bitvector") << indent() << "TheoryBV::propagate()" << std::endl;
 
+  if (options::bitvectorEagerBitblast()) {
+    return;
+  }
+
   if (inConflict()) {
     return;
   }