1 /******************************************************************************
2 * Top contributors (to current version):
3 * Mathias Preiner, Gereon Kremer, Haniel Barbosa
5 * This file is part of the cvc5 project.
7 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8 * in the top-level source directory and their institutional affiliations.
9 * All rights reserved. See the file COPYING in the top-level source
10 * directory for licensing information.
11 * ****************************************************************************
13 * Bit-blast solver that sends bit-blast lemmas directly to the internal
17 #include "theory/bv/bv_solver_bitblast_internal.h"
19 #include "proof/conv_proof_generator.h"
20 #include "theory/bv/theory_bv.h"
21 #include "theory/bv/theory_bv_utils.h"
22 #include "theory/theory_model.h"
28 /* -------------------------------------------------------------------------- */
32 bool isBVAtom(TNode n
)
34 return (n
.getKind() == kind::EQUAL
&& n
[0].getType().isBitVector())
35 || n
.getKind() == kind::BITVECTOR_ULT
36 || n
.getKind() == kind::BITVECTOR_ULE
37 || n
.getKind() == kind::BITVECTOR_SLT
38 || n
.getKind() == kind::BITVECTOR_SLE
;
41 /* Traverse Boolean nodes and collect BV atoms. */
42 void collectBVAtoms(TNode n
, std::unordered_set
<Node
>& atoms
)
44 std::vector
<TNode
> visit
;
45 std::unordered_set
<TNode
> visited
;
51 TNode cur
= visit
.back();
54 if (visited
.find(cur
) != visited
.end() || !cur
.getType().isBoolean())
64 visit
.insert(visit
.end(), cur
.begin(), cur
.end());
65 } while (!visit
.empty());
70 BVSolverBitblastInternal::BVSolverBitblastInternal(
71 TheoryState
* s
, TheoryInferenceManager
& inferMgr
, ProofNodeManager
* pnm
)
72 : BVSolver(*s
, inferMgr
),
74 d_bitblaster(new BBProof(s
, pnm
, false))
78 void BVSolverBitblastInternal::addBBLemma(TNode fact
)
80 if (!d_bitblaster
->hasBBAtom(fact
))
82 d_bitblaster
->bbAtom(fact
);
84 NodeManager
* nm
= NodeManager::currentNM();
86 Node atom_bb
= d_bitblaster
->getStoredBBAtom(fact
);
87 Node lemma
= nm
->mkNode(kind::EQUAL
, fact
, atom_bb
);
91 d_im
.lemma(lemma
, InferenceId::BV_BITBLAST_INTERNAL_BITBLAST_LEMMA
);
96 TrustNode::mkTrustLemma(lemma
, d_bitblaster
->getProofGenerator());
97 d_im
.trustedLemma(tlem
, InferenceId::BV_BITBLAST_INTERNAL_BITBLAST_LEMMA
);
101 bool BVSolverBitblastInternal::preNotifyFact(
102 TNode atom
, bool pol
, TNode fact
, bool isPrereg
, bool isInternal
)
104 if (fact
.getKind() == kind::NOT
)
113 else if (fact
.getKind() == kind::BITVECTOR_EAGER_ATOM
)
117 NodeManager
* nm
= NodeManager::currentNM();
118 Node lemma
= nm
->mkNode(kind::EQUAL
, fact
, n
);
120 if (d_pnm
== nullptr)
122 d_im
.lemma(lemma
, InferenceId::BV_BITBLAST_INTERNAL_EAGER_LEMMA
);
126 d_bitblaster
->getProofGenerator()->addRewriteStep(
127 fact
, n
, PfRule::BV_EAGER_ATOM
, {}, {fact
});
129 TrustNode::mkTrustLemma(lemma
, d_bitblaster
->getProofGenerator());
130 d_im
.trustedLemma(tlem
, InferenceId::BV_BITBLAST_INTERNAL_EAGER_LEMMA
);
133 std::unordered_set
<Node
> bv_atoms
;
134 collectBVAtoms(n
, bv_atoms
);
135 for (const Node
& nn
: bv_atoms
)
144 bool BVSolverBitblastInternal::collectModelValues(TheoryModel
* m
,
145 const std::set
<Node
>& termSet
)
147 return d_bitblaster
->collectModelValues(m
, termSet
);
150 Node
BVSolverBitblastInternal::getValue(TNode node
, bool initialize
)
157 if (!d_bitblaster
->hasBBTerm(node
))
159 return initialize
? utils::mkConst(utils::getSize(node
), 0u) : Node();
162 Valuation
& val
= d_state
.getValuation();
164 std::vector
<Node
> bits
;
165 d_bitblaster
->getBBTerm(node
, bits
);
166 Integer
value(0), one(1), zero(0), bit
;
167 for (size_t i
= 0, size
= bits
.size(), j
= size
- 1; i
< size
; ++i
, --j
)
170 if (val
.hasSatValue(bits
[j
], satValue
))
172 bit
= satValue
? one
: zero
;
176 if (!initialize
) return Node();
179 value
= value
* 2 + bit
;
181 return utils::mkConst(bits
.size(), value
);
184 BVProofRuleChecker
* BVSolverBitblastInternal::getProofChecker()
190 } // namespace theory