SatValue BVMinisatSatSolver::solve(long unsigned int& resource){
Trace("limit") << "MinisatSatSolver::solve(): have limit of " << resource << " conflicts" << std::endl;
+ ++d_statistics.d_statCallsToSolve;
if(resource == 0) {
d_minisat->budgetOff();
} else {
void BvToBoolVisitor::storeBvToBool(TNode bv_term, TNode bool_term) {
Assert (bv_term.getType().isBitVector() &&
- bv_term.getType().getBitVectorSize() == 1);
- Assert (bool_term.getType().isBoolean() && d_bvToBoolMap.find(bv_term) == d_bvToBoolMap.end());
+ bv_term.getType().getBitVectorSize() == 1 &&
+ bool_term.getType().isBoolean() && bv_term != Node() && bool_term != Node());
+ if (d_bvToBoolMap.find(bv_term) != d_bvToBoolMap.end()) {
+ Assert (d_bvToBoolMap[bv_term] == bool_term);
+ }
d_bvToBoolMap[bv_term] = bool_term;
}
return true;
}
- Kind kind = node.getKind();
if (!node.getType().isBitVector() || node.getType().getBitVectorSize() != 1)
return false;
+
+ Kind kind = node.getKind();
if (kind == kind::CONST_BITVECTOR) {
return true;
}
return true;
}
+ if (kind == kind::VARIABLE) {
+ storeBvToBool(node, utils::mkNode(kind::EQUAL, node, utils::mkConst(BitVector(1, 1u))));
+ return true;
+ }
return false;
}
check(current, parent);
if (isConvertibleBvAtom(current)) {
- result = convertBvAtom(current);
+ result = convertBvAtom(current);
+ addToCache(current, result);
} else if (isConvertibleBvTerm(current)) {
result = convertBvTerm(current);
} else {
}
result = builder;
}
+ addToCache(current, result);
}
Assert (result != Node());
Debug("bv-to-bool") << " =>" << result <<"\n";
- addToCache(current, result);
}
d_subtheories(),
d_subtheoryMap(),
d_statistics(),
+ d_lemmasAdded(c, false),
d_conflict(c, false),
d_literalsToPropagate(c),
d_literalsToPropagateIndex(c, 0),
}
}
+void TheoryBV::checkForLemma(TNode fact) {
+ if (fact.getKind() == kind::EQUAL) {
+ if (fact[0].getKind() == kind::BITVECTOR_UREM_TOTAL) {
+ TNode urem = fact[0];
+ TNode result = fact[1];
+ TNode divisor = urem[1];
+ Node result_ult_div = utils::mkNode(kind::BITVECTOR_ULT, result, divisor);
+ Node split = utils::mkNode(kind::OR, utils::mkNode(kind::NOT, fact), result_ult_div);
+ lemma(split);
+ }
+ if (fact[1].getKind() == kind::BITVECTOR_UREM_TOTAL) {
+ TNode urem = fact[1];
+ TNode result = fact[0];
+ TNode divisor = urem[1];
+ Node result_ult_div = utils::mkNode(kind::BITVECTOR_ULT, result, divisor);
+ Node split = utils::mkNode(kind::OR, utils::mkNode(kind::NOT, fact), result_ult_div);
+ lemma(split);
+ }
+ }
+}
+
+
void TheoryBV::check(Effort e)
{
Trace("bitvector") <<"TheoryBV::check (" << e << ")\n";
return;
}
+ if (Theory::fullEffort(e)) {
+ Trace("bitvector-fulleffort") << "TheoryBV::fullEffort \n";
+ printFacts( Trace("bitvector-fulleffort") );
+ }
+
while (!done()) {
TNode fact = get().assertion;
+ checkForLemma(fact);
for (unsigned i = 0; i < d_subtheories.size(); ++i) {
d_subtheories[i]->assertFact(fact);
}
Statistics d_statistics;
+ context::CDO<bool> d_lemmasAdded;
+
// Are we in conflict?
context::CDO<bool> d_conflict;
/** Index of the next literal to propagate */
context::CDO<unsigned> d_literalsToPropagateIndex;
+
+
/**
* Keeps a map from nodes to the subtheory that propagated it so that we can explain it
* properly.
void sendConflict();
- void lemma(TNode node) { d_out->lemma(node); }
+ void lemma(TNode node) { d_out->lemma(node); d_lemmasAdded = true; }
+
+ void checkForLemma(TNode node);
friend class Bitblaster;
friend class BitblastSolver;
AndSimplify,
OrSimplify,
XorSimplify,
-
+ UleEliminate,
// rules to simplify bitblasting
BBPlusNeg
};
case BBPlusNeg : out << "BBPlusNeg"; return out;
case UltOne : out << "UltOne"; return out;
case SltZero : out << "SltZero"; return out;
- case ZeroUlt : out << "ZeroUlt"; return out;
+ case ZeroUlt : out << "ZeroUlt"; return out;
+ case UleEliminate : out << "UleEliminate"; return out;
default:
Unreachable();
}
return result;
}
+
template <>
bool RewriteRule<SltEliminate>::applies(TNode node) {
return (node.getKind() == kind::BITVECTOR_SLT);
return utils::mkNode(kind::NOT, b_slt_a);
}
+template <>
+bool RewriteRule<UleEliminate>::applies(TNode node) {
+ return (node.getKind() == kind::BITVECTOR_ULE);
+}
+
+template <>
+Node RewriteRule<UleEliminate>::apply(TNode node) {
+ Debug("bv-rewrite") << "RewriteRule<UleEliminate>(" << node << ")" << std::endl;
+
+ TNode a = node[0];
+ TNode b = node[1];
+ Node b_ult_a = utils::mkNode(kind::BITVECTOR_ULT, b, a);
+ return utils::mkNode(kind::NOT, b_ult_a);
+}
+
template <>
bool RewriteRule<CompEliminate>::applies(TNode node) {
Node resultNode = LinearRewriteStrategy
< RewriteRule<EvalUlt>,
// if both arguments are constants evaluates
- RewriteRule<UltZero>,
+ RewriteRule<UltZero>
// a < 0 rewrites to false
- RewriteRule<UltOne>,
- RewriteRule<ZeroUlt>
+ // RewriteRule<UltOne>,
+ // RewriteRule<ZeroUlt>
>::apply(node);
return RewriteResponse(REWRITE_DONE, resultNode);
RewriteResponse TheoryBVRewriter::RewriteSlt(TNode node, bool preregister){
Node resultNode = LinearRewriteStrategy
- < RewriteRule < EvalSlt >,
- RewriteRule < SltZero >
+ < RewriteRule < EvalSlt >
+ // RewriteRule < SltZero >
>::apply(node);
return RewriteResponse(REWRITE_DONE, resultNode);
RewriteRule<UleMax>,
RewriteRule<ZeroUle>,
RewriteRule<UleZero>,
- RewriteRule<UleSelf>
+ RewriteRule<UleSelf>,
+ RewriteRule<UleEliminate>
>::apply(node);
return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN, resultNode);
}
RewriteResponse TheoryBVRewriter::RewriteSle(TNode node, bool preregister){
Node resultNode = LinearRewriteStrategy
- < RewriteRule <EvalSle>,
+ < RewriteRule <EvalSle>,
RewriteRule <SleEliminate>
>::apply(node);
-
- return RewriteResponse(REWRITE_DONE, resultNode);
+ return RewriteResponse(resultNode == node? REWRITE_DONE : REWRITE_AGAIN, resultNode);
}
RewriteResponse TheoryBVRewriter::RewriteUgt(TNode node, bool preregister){