* 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
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){
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(); }
#include "expr/command.h"
#include "expr/expr.h"
#include "prop/theory_proxy.h"
+#include "theory/bv/options.h"
#include <queue>
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
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);
}
// 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")) ) {
}
// If a theory literal, we pre-register it
- if (theoryLiteral) {
+ if (preRegister) {
bool backup = d_removable;
d_registrar->preRegister(node);
d_removable = backup;
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;
* 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
// 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();
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()));
}
// 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; }
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) {
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(); }
}
-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);
// 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.
/** 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;
#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"
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;
d_bitblastedAtoms.insert(node);
} else {
d_bvOutput->lemma(atom_definition, false);
+ d_bitblastedAtoms.insert(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);
+ }
}
}
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()) {
void collectModelInfo(TheoryModel* m);
Node getModelValue(TNode node);
bool isComplete() { return true; }
+ void bitblastQueue();
};
}
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) {
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 {
void TheoryBV::propagate(Effort e) {
Debug("bitvector") << indent() << "TheoryBV::propagate()" << std::endl;
+ if (options::bitvectorEagerBitblast()) {
+ return;
+ }
+
if (inConflict()) {
return;
}