summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Preiner <mathias.preiner@gmail.com>2021-06-21 12:11:10 -0700
committerGitHub <noreply@github.com>2021-06-21 19:11:10 +0000
commit331187d557b2c54b079de6348ff1f597a72f50a2 (patch)
treee0651d38c6ae1597b91ee6a2b6b7d419a27718bc
parent62cf9381eac3609e4af0509ffce3abf58ba71238 (diff)
Fix model issues with --bitblast=eager. (#6753)
For model construction we only compute model values for relevant terms. The set of relevant terms is computed in https://github.com/cvc5/cvc5/blob/master/src/theory/model_manager_distributed.cpp#L58, which skips equalities by default because equalities are usually handled by the equality engine. When --bitblast=eager is enabled all assertions are wrapped into BITVECTOR_EAGER_ATOM nodes and passed to the BV solver, which results in equalities below BITVECTOR_EAGER_ATOM nodes not being handled by the equality engine but by the BV solver directly. These equalities, however, are skipped when computing the relevant terms and therefore the BV solver is not asked to compute model values for variables below these equalities. If --bitblast=eager is enabled the BV solver now additionally adds the variables encountered during bit-blasting to the relevant terms via computeRelevantTerms. Co-authored-by: Andres Noetzli <andres.noetzli@gmail.com>
-rw-r--r--src/theory/bv/bitblast/simple_bitblaster.cpp10
-rw-r--r--src/theory/bv/bitblast/simple_bitblaster.h2
-rw-r--r--src/theory/bv/bv_solver.h13
-rw-r--r--src/theory/bv/bv_solver_bitblast.cpp15
-rw-r--r--src/theory/bv/bv_solver_bitblast.h2
-rw-r--r--src/theory/bv/theory_bv.cpp5
-rw-r--r--src/theory/bv/theory_bv.h2
-rw-r--r--test/regress/CMakeLists.txt1
-rw-r--r--test/regress/regress0/issue6741.smt28
9 files changed, 53 insertions, 5 deletions
diff --git a/src/theory/bv/bitblast/simple_bitblaster.cpp b/src/theory/bv/bitblast/simple_bitblaster.cpp
index a38dfdfe5..357a54b1a 100644
--- a/src/theory/bv/bitblast/simple_bitblaster.cpp
+++ b/src/theory/bv/bitblast/simple_bitblaster.cpp
@@ -17,6 +17,7 @@
#include "theory/theory_model.h"
#include "theory/theory_state.h"
+#include "options/bv_options.h"
namespace cvc5 {
namespace theory {
@@ -129,6 +130,15 @@ Node BBSimple::getModelFromSatSolver(TNode a, bool fullModel)
return utils::mkConst(bits.size(), value);
}
+void BBSimple::computeRelevantTerms(std::set<Node>& termSet)
+{
+ Assert(options::bitblastMode() == options::BitblastMode::EAGER);
+ for (const auto& var : d_variables)
+ {
+ termSet.insert(var);
+ }
+}
+
bool BBSimple::collectModelValues(TheoryModel* m,
const std::set<Node>& relevantTerms)
{
diff --git a/src/theory/bv/bitblast/simple_bitblaster.h b/src/theory/bv/bitblast/simple_bitblaster.h
index ebbb2891f..ec0899145 100644
--- a/src/theory/bv/bitblast/simple_bitblaster.h
+++ b/src/theory/bv/bitblast/simple_bitblaster.h
@@ -53,6 +53,8 @@ class BBSimple : public TBitblaster<Node>
/** Create 'bits' for variable 'var'. */
void makeVariable(TNode var, Bits& bits) override;
+ /** Add d_variables to termSet. */
+ void computeRelevantTerms(std::set<Node>& termSet);
/** Collect model values for all relevant terms given in 'relevantTerms'. */
bool collectModelValues(TheoryModel* m, const std::set<Node>& relevantTerms);
diff --git a/src/theory/bv/bv_solver.h b/src/theory/bv/bv_solver.h
index 8ff4318c0..6ccc6c7c1 100644
--- a/src/theory/bv/bv_solver.h
+++ b/src/theory/bv/bv_solver.h
@@ -32,7 +32,7 @@ class BVSolver
BVSolver(TheoryState& state, TheoryInferenceManager& inferMgr)
: d_state(state), d_im(inferMgr){};
- virtual ~BVSolver(){};
+ virtual ~BVSolver() {}
/**
* Returns true if we need an equality engine. If so, we initialize the
@@ -71,7 +71,7 @@ class BVSolver
virtual bool needsCheckLastEffort() { return false; }
- virtual void propagate(Theory::Effort e){};
+ virtual void propagate(Theory::Effort e) {}
virtual TrustNode explain(TNode n)
{
@@ -80,17 +80,20 @@ class BVSolver
return TrustNode::null();
}
+ /** Additionally collect terms relevant for collecting model values. */
+ virtual void computeRelevantTerms(std::set<Node>& termSet) {}
+
/** Collect model values in m based on the relevant terms given by termSet */
virtual bool collectModelValues(TheoryModel* m,
const std::set<Node>& termSet) = 0;
virtual std::string identify() const = 0;
- virtual TrustNode ppRewrite(TNode t) { return TrustNode::null(); };
+ virtual TrustNode ppRewrite(TNode t) { return TrustNode::null(); }
- virtual void ppStaticLearn(TNode in, NodeBuilder& learned){};
+ virtual void ppStaticLearn(TNode in, NodeBuilder& learned) {}
- virtual void presolve(){};
+ virtual void presolve() {}
virtual void notifySharedTerm(TNode t) {}
diff --git a/src/theory/bv/bv_solver_bitblast.cpp b/src/theory/bv/bv_solver_bitblast.cpp
index 414e57e19..3ae4a7f0a 100644
--- a/src/theory/bv/bv_solver_bitblast.cpp
+++ b/src/theory/bv/bv_solver_bitblast.cpp
@@ -238,6 +238,21 @@ TrustNode BVSolverBitblast::explain(TNode n)
return d_im.explainLit(n);
}
+void BVSolverBitblast::computeRelevantTerms(std::set<Node>& termSet)
+{
+ /* BITVECTOR_EAGER_ATOM wraps input assertions that may also contain
+ * equalities. As a result, these equalities are not handled by the equality
+ * engine and terms below these equalities do not appear in `termSet`.
+ * We need to make sure that we compute model values for all relevant terms
+ * in BitblastMode::EAGER and therefore add all variables from the
+ * bit-blaster to `termSet`.
+ */
+ if (options::bitblastMode() == options::BitblastMode::EAGER)
+ {
+ d_bitblaster->computeRelevantTerms(termSet);
+ }
+}
+
bool BVSolverBitblast::collectModelValues(TheoryModel* m,
const std::set<Node>& termSet)
{
diff --git a/src/theory/bv/bv_solver_bitblast.h b/src/theory/bv/bv_solver_bitblast.h
index 31d9443c8..c5134c6fc 100644
--- a/src/theory/bv/bv_solver_bitblast.h
+++ b/src/theory/bv/bv_solver_bitblast.h
@@ -64,6 +64,8 @@ class BVSolverBitblast : public BVSolver
EqualityStatus getEqualityStatus(TNode a, TNode b) override;
+ void computeRelevantTerms(std::set<Node>& termSet) override;
+
bool collectModelValues(TheoryModel* m,
const std::set<Node>& termSet) override;
diff --git a/src/theory/bv/theory_bv.cpp b/src/theory/bv/theory_bv.cpp
index 22b05b026..3d7f11f6d 100644
--- a/src/theory/bv/theory_bv.cpp
+++ b/src/theory/bv/theory_bv.cpp
@@ -175,6 +175,11 @@ bool TheoryBV::needsCheckLastEffort()
return d_internal->needsCheckLastEffort();
}
+void TheoryBV::computeRelevantTerms(std::set<Node>& termSet)
+{
+ return d_internal->computeRelevantTerms(termSet);
+}
+
bool TheoryBV::collectModelValues(TheoryModel* m, const std::set<Node>& termSet)
{
return d_internal->collectModelValues(m, termSet);
diff --git a/src/theory/bv/theory_bv.h b/src/theory/bv/theory_bv.h
index 4b3a1f3b2..e884f621c 100644
--- a/src/theory/bv/theory_bv.h
+++ b/src/theory/bv/theory_bv.h
@@ -83,6 +83,8 @@ class TheoryBV : public Theory
TrustNode explain(TNode n) override;
+ void computeRelevantTerms(std::set<Node>& termSet) override;
+
/** Collect model values in m based on the relevant terms given by termSet */
bool collectModelValues(TheoryModel* m,
const std::set<Node>& termSet) override;
diff --git a/test/regress/CMakeLists.txt b/test/regress/CMakeLists.txt
index 9ad4f7e8a..444e4c7f6 100644
--- a/test/regress/CMakeLists.txt
+++ b/test/regress/CMakeLists.txt
@@ -670,6 +670,7 @@ set(regress_0_tests
regress0/issue5743.smt2
regress0/issue5947.smt2
regress0/issue6605-2-abd-triv.smt2
+ regress0/issue6741.smt2
regress0/ite_arith.smt2
regress0/ite_real_int_type.smtv1.smt2
regress0/ite_real_valid.smtv1.smt2
diff --git a/test/regress/regress0/issue6741.smt2 b/test/regress/regress0/issue6741.smt2
new file mode 100644
index 000000000..0fbf4edeb
--- /dev/null
+++ b/test/regress/regress0/issue6741.smt2
@@ -0,0 +1,8 @@
+; COMMAND-LINE: --bv-solver=bitblast --bitblast=eager --check-models
+(set-logic QF_BV)
+(set-info :status sat)
+(declare-fun x () (_ BitVec 1))
+(declare-fun y () (_ BitVec 1))
+(assert (= y (ite (= x (_ bv1 1)) (_ bv1 1) (_ bv0 1))))
+(assert (= y (_ bv1 1)))
+(check-sat)
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback