summaryrefslogtreecommitdiff
path: root/src/theory/bv/bv_solver_bitblast.cpp
diff options
context:
space:
mode:
authorMathias Preiner <mathias.preiner@gmail.com>2021-05-19 10:21:42 -0700
committerGitHub <noreply@github.com>2021-05-19 17:21:42 +0000
commitff5ecff78ade286f2836c6fa76b6c502fa8f3c3b (patch)
treef9ec4b4b461945d4ba32c3294c52f52088fe24bd /src/theory/bv/bv_solver_bitblast.cpp
parentbcb536ef60cb24c19001c0efbde55ff3a37e114f (diff)
bv: Add support for --bitblast=eager. (#6516)
This PR adds support for handling --bitblast=eager in the new bitblast solver.
Diffstat (limited to 'src/theory/bv/bv_solver_bitblast.cpp')
-rw-r--r--src/theory/bv/bv_solver_bitblast.cpp102
1 files changed, 93 insertions, 9 deletions
diff --git a/src/theory/bv/bv_solver_bitblast.cpp b/src/theory/bv/bv_solver_bitblast.cpp
index b01ba2580..463a937fd 100644
--- a/src/theory/bv/bv_solver_bitblast.cpp
+++ b/src/theory/bv/bv_solver_bitblast.cpp
@@ -26,12 +26,54 @@ namespace cvc5 {
namespace theory {
namespace bv {
+/**
+ * Bit-blasting registrar.
+ *
+ * The CnfStream calls preRegister() if it encounters a theory atom.
+ * This registrar bit-blasts given atom and remembers which bit-vector atoms
+ * were bit-blasted.
+ *
+ * This registrar is needed when --bitblast=eager is enabled.
+ */
+class BBRegistrar : public prop::Registrar
+{
+ public:
+ BBRegistrar(BBSimple* bb) : d_bitblaster(bb) {}
+
+ void preRegister(Node n) override
+ {
+ if (d_registeredAtoms.find(n) != d_registeredAtoms.end())
+ {
+ return;
+ }
+ /* We are only interested in bit-vector atoms. */
+ if ((n.getKind() == kind::EQUAL && n[0].getType().isBitVector())
+ || n.getKind() == kind::BITVECTOR_ULT
+ || n.getKind() == kind::BITVECTOR_ULE
+ || n.getKind() == kind::BITVECTOR_SLT
+ || n.getKind() == kind::BITVECTOR_SLE)
+ {
+ d_registeredAtoms.insert(n);
+ d_bitblaster->bbAtom(n);
+ }
+ }
+
+ std::unordered_set<TNode>& getRegisteredAtoms() { return d_registeredAtoms; }
+
+ private:
+ /** The bitblaster used. */
+ BBSimple* d_bitblaster;
+
+ /** Stores bit-vector atoms encounterd on preRegister(). */
+ std::unordered_set<TNode> d_registeredAtoms;
+};
+
BVSolverBitblast::BVSolverBitblast(TheoryState* s,
TheoryInferenceManager& inferMgr,
ProofNodeManager* pnm)
: BVSolver(*s, inferMgr),
d_bitblaster(new BBSimple(s)),
- d_nullRegistrar(new prop::NullRegistrar()),
+ d_bbRegistrar(new BBRegistrar(d_bitblaster.get())),
d_nullContext(new context::Context()),
d_bbFacts(s->getSatContext()),
d_bbInputFacts(s->getSatContext()),
@@ -61,7 +103,7 @@ BVSolverBitblast::BVSolverBitblast(TheoryState* s,
smtStatisticsRegistry(), "theory::bv::BVSolverBitblast"));
}
d_cnfStream.reset(new prop::CnfStream(d_satSolver.get(),
- d_nullRegistrar.get(),
+ d_bbRegistrar.get(),
d_nullContext.get(),
nullptr,
smt::currentResourceManager()));
@@ -88,9 +130,16 @@ void BVSolverBitblast::postCheck(Theory::Effort level)
/* Bit-blast fact and cache literal. */
if (d_factLiteralCache.find(fact) == d_factLiteralCache.end())
{
- d_bitblaster->bbAtom(fact);
- Node bb_fact = d_bitblaster->getStoredBBAtom(fact);
- d_cnfStream->convertAndAssert(bb_fact, false, false);
+ if (fact.getKind() == kind::BITVECTOR_EAGER_ATOM)
+ {
+ handleEagerAtom(fact, true);
+ }
+ else
+ {
+ d_bitblaster->bbAtom(fact);
+ Node bb_fact = d_bitblaster->getStoredBBAtom(fact);
+ d_cnfStream->convertAndAssert(bb_fact, false, false);
+ }
}
d_assertions.push_back(fact);
}
@@ -103,10 +152,19 @@ void BVSolverBitblast::postCheck(Theory::Effort level)
/* Bit-blast fact and cache literal. */
if (d_factLiteralCache.find(fact) == d_factLiteralCache.end())
{
- d_bitblaster->bbAtom(fact);
- Node bb_fact = d_bitblaster->getStoredBBAtom(fact);
- d_cnfStream->ensureLiteral(bb_fact);
- prop::SatLiteral lit = d_cnfStream->getLiteral(bb_fact);
+ prop::SatLiteral lit;
+ if (fact.getKind() == kind::BITVECTOR_EAGER_ATOM)
+ {
+ handleEagerAtom(fact, false);
+ lit = d_cnfStream->getLiteral(fact[0]);
+ }
+ else
+ {
+ d_bitblaster->bbAtom(fact);
+ Node bb_fact = d_bitblaster->getStoredBBAtom(fact);
+ d_cnfStream->ensureLiteral(bb_fact);
+ lit = d_cnfStream->getLiteral(bb_fact);
+ }
d_factLiteralCache[fact] = lit;
d_literalFactCache[lit] = fact;
}
@@ -322,6 +380,32 @@ Node BVSolverBitblast::getValue(TNode node)
return it->second;
}
+void BVSolverBitblast::handleEagerAtom(TNode fact, bool assertFact)
+{
+ Assert(fact.getKind() == kind::BITVECTOR_EAGER_ATOM);
+
+ if (assertFact)
+ {
+ d_cnfStream->convertAndAssert(fact[0], false, false);
+ }
+ else
+ {
+ d_cnfStream->ensureLiteral(fact[0]);
+ }
+
+ /* convertAndAssert() does not make the connection between the bit-vector
+ * atom and it's bit-blasted form (it only calls preRegister() from the
+ * registrar). Thus, we add the equalities now. */
+ auto& registeredAtoms = d_bbRegistrar->getRegisteredAtoms();
+ for (auto atom : registeredAtoms)
+ {
+ Node bb_atom = d_bitblaster->getStoredBBAtom(atom);
+ d_cnfStream->convertAndAssert(atom.eqNode(bb_atom), false, false);
+ }
+ // Clear cache since we only need to do this once per bit-blasted atom.
+ registeredAtoms.clear();
+}
+
} // namespace bv
} // namespace theory
} // namespace cvc5
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback