// make sure it is marked as an atom
addAtom(node);
- BVDebug("bitvector-bitblast") << "Bitblasting node " << node <<"\n";
+ Debug("bitvector-bitblast") << "Bitblasting node " << node <<"\n";
++d_statistics.d_numAtoms;
// the bitblasted definition of the atom
Node atom_bb = Rewriter::rewrite(d_atomBBStrategies[node.getKind()](node, this));
return;
}
- BVDebug("bitvector-bitblast") << "Bitblasting node " << node <<"\n";
+ Debug("bitvector-bitblast") << "Bitblasting node " << node <<"\n";
++d_statistics.d_numTerms;
d_termBBStrategies[node.getKind()] (node, bits,this);
markerLit = ~markerLit;
}
- BVDebug("bitvector-bb") << "TheoryBV::Bitblaster::assertToSat asserting node: " << atom <<"\n";
- BVDebug("bitvector-bb") << "TheoryBV::Bitblaster::assertToSat with literal: " << markerLit << "\n";
+ Debug("bitvector-bb") << "TheoryBV::Bitblaster::assertToSat asserting node: " << atom <<"\n";
+ Debug("bitvector-bb") << "TheoryBV::Bitblaster::assertToSat with literal: " << markerLit << "\n";
SatValue ret = d_satSolver->assertAssumption(markerLit, propagate);
Trace("bitvector") << " " << d_cnfStream->getNode(*it) << "\n";
}
}
- BVDebug("bitvector") << "Bitblaster::solve() asserted atoms " << d_assertedAtoms.size() <<"\n";
+ Debug("bitvector") << "Bitblaster::solve() asserted atoms " << d_assertedAtoms.size() <<"\n";
return SAT_VALUE_TRUE == d_satSolver->solve();
}
return d_bv->d_sharedTermsSet.find(node) != d_bv->d_sharedTermsSet.end();
}
+bool Bitblaster::hasValue(TNode a) {
+ Assert (d_termCache.find(a) != d_termCache.end());
+ Bits bits = d_termCache[a];
+ for (int i = bits.size() -1; i >= 0; --i) {
+ SatValue bit_value;
+ if (d_cnfStream->hasLiteral(bits[i])) {
+ SatLiteral bit = d_cnfStream->getLiteral(bits[i]);
+ bit_value = d_satSolver->value(bit);
+ if (bit_value == SAT_VALUE_UNKNOWN)
+ return false;
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
Node Bitblaster::getVarValue(TNode a) {
Assert (d_termCache.find(a) != d_termCache.end());
Bits bits = d_termCache[a];
__gnu_cxx::hash_set<TNode, TNodeHashFunction>::iterator it = d_variables.begin();
for (; it!= d_variables.end(); ++it) {
TNode var = *it;
- if (Theory::theoryOf(var) == theory::THEORY_BV || isSharedTerm(var)) {
+ if ((Theory::theoryOf(var) == theory::THEORY_BV || isSharedTerm(var)) && hasValue(var)) {
Node const_value = getVarValue(var);
Debug("bitvector-model") << "Bitblaster::collectModelInfo (assert (= "
<< var << " "
// division is bitblasted in terms of constraints
// so it needs to use private bitblaster interface
void bbUdiv(TNode node, Bits& bits);
- void bbUrem(TNode node, Bits& bits);
+ void bbUrem(TNode node, Bits& bits);
+ bool hasValue(TNode a);
public:
void cacheTermDef(TNode node, Bits def); // public so we can cache remainder for division
void bbTerm(TNode node, Bits& bits);
}
bool BitblastSolver::addAssertions(const std::vector<TNode>& assertions, Theory::Effort e) {
- BVDebug("bitvector::bitblaster") << "BitblastSolver::addAssertions (" << e << ")" << std::endl;
-
- //// Eager bit-blasting
- if (options::bitvectorEagerBitblast()) {
- for (unsigned i = 0; i < assertions.size(); ++i) {
- TNode atom = assertions[i].getKind() == kind::NOT ? assertions[i][0] : assertions[i];
- if (atom.getKind() != kind::BITVECTOR_BITOF) {
- d_bitblaster->bbAtom(atom);
- }
- }
- return true;
- }
+ Debug("bitvector::bitblaster") << "BitblastSolver::addAssertions (" << e << ")" << std::endl;
+ Debug("bitvector::bitblaster") << "number of assertions: " << assertions.size() << std::endl;
//// Lazy bit-blasting
// solving
if (e == Theory::EFFORT_FULL || options::bitvectorEagerFullcheck()) {
Assert(!d_bv->inConflict());
- BVDebug("bitvector::bitblaster") << "BitblastSolver::addAssertions solving. \n";
+ Debug("bitvector::bitblaster") << "BitblastSolver::addAssertions solving. \n";
bool ok = d_bitblaster->solve();
if (!ok) {
std::vector<TNode> conflictAtoms;
if (d_isCoreTheory && !d_slicer->isCoreTerm(fact)) {
d_isCoreTheory = false;
}
- ok = decomposeFact(fact);
+
+ // only reason about equalities
+ // FIXME: should we slice when we have the terms in inequalities?
+ if (fact.getKind() == kind::EQUAL || (fact.getKind() == kind::NOT && fact[0].getKind() == kind::EQUAL)) {
+ ok = decomposeFact(fact);
+ } else {
+ ok = assertFact(fact, fact);
+ }
if (!ok)
return false;
}
current_low += current_size;
decomp.push_back(current);
}
+ // cache the result
Debug("bv-slicer") << "as [";
for (unsigned i = 0; i < decomp.size(); ++i) {
class Slicer {
__gnu_cxx::hash_map<TermId, TNode> d_idToNode;
__gnu_cxx::hash_map<TNode, TermId, TNodeHashFunction> d_nodeToId;
- __gnu_cxx::hash_map<TNode, bool, TNodeHashFunction> d_coreTermCache;
+ __gnu_cxx::hash_map<TNode, bool, TNodeHashFunction> d_coreTermCache;
+ __gnu_cxx::hash_map<TNode, std::vector<Node>, TNodeHashFunction> d_decompositionCache;
UnionFind d_unionFind;
ExtractTerm registerTerm(TNode node);
public:
d_alreadyPropagatedSet(c),
d_sharedTermsSet(c),
d_slicer(),
+ d_bitblastAssertionsQueue(c),
d_bitblastSolver(c, this),
d_coreSolver(c, this, &d_slicer),
d_statistics(),
Assertion assertion = get();
TNode fact = assertion.assertion;
new_assertions.push_back(fact);
+ d_bitblastAssertionsQueue.push_back(fact);
Debug("bitvector-assertions") << "TheoryBV::check assertion " << fact << "\n";
}
if (!inConflict() && !d_coreSolver.isCoreTheory()) {
// sending assertions to the bitblast solver if it's not just core theory
d_bitblastSolver.addAssertions(new_assertions, e);
+ } else {
+ // sending assertions to the bitblast solver if it's not just core theory
+ d_bitblastSolver.addAssertions(new_assertions, EFFORT_STANDARD);
}
if (inConflict()) {
// Assert (fullModel); // can only query full model
d_coreSolver.collectModelInfo(m);
d_bitblastSolver.collectModelInfo(m);
-
}
void TheoryBV::propagate(Effort e) {
Slicer d_slicer;
+ context::CDQueue<TNode> d_bitblastAssertionsQueue;
+
BitblastSolver d_bitblastSolver;
CoreSolver d_coreSolver;
-
+
public:
TheoryBV(context::Context* c, context::UserContext* u, OutputChannel& out, Valuation valuation, const LogicInfo& logicInfo, QuantifiersEngine* qe);