d_abstractionMap(u),
d_rewriter(u),
d_state(c, u, valuation),
- d_im(*this, d_state, pnm, "theory::fp::", false)
+ d_im(*this, d_state, pnm, "theory::fp::", false),
+ d_wbFactsCache(u)
{
// indicate we are using the default theory state and inference manager
d_theoryState = &d_state;
d_inferManager = &d_im;
-} /* TheoryFp::TheoryFp() */
+}
TheoryRewriter* TheoryFp::getTheoryRewriter() { return &d_rewriter; }
Node floatValue = m->getValue(concrete[0]);
Node undefValue = m->getValue(concrete[1]);
+ Assert(!abstractValue.isNull());
+ Assert(!floatValue.isNull());
+ Assert(!undefValue.isNull());
Assert(abstractValue.isConst());
Assert(floatValue.isConst());
Assert(undefValue.isConst());
Node rmValue = m->getValue(concrete[0]);
Node realValue = m->getValue(concrete[1]);
+ Assert(!abstractValue.isNull());
+ Assert(!rmValue.isNull());
+ Assert(!realValue.isNull());
Assert(abstractValue.isConst());
Assert(rmValue.isConst());
Assert(realValue.isConst());
return false;
}
-void TheoryFp::convertAndEquateTerm(TNode node) {
+void TheoryFp::convertAndEquateTerm(TNode node)
+{
Trace("fp-convertTerm") << "TheoryFp::convertTerm(): " << node << std::endl;
- size_t oldAdditionalAssertions = d_conv->d_additionalAssertions.size();
+
+ size_t oldSize = d_conv->d_additionalAssertions.size();
Node converted(d_conv->convert(node));
+ size_t newSize = d_conv->d_additionalAssertions.size();
+
if (converted != node) {
Debug("fp-convertTerm")
<< "TheoryFp::convertTerm(): before " << node << std::endl;
<< "TheoryFp::convertTerm(): after " << converted << std::endl;
}
- size_t newAdditionalAssertions = d_conv->d_additionalAssertions.size();
- Assert(oldAdditionalAssertions <= newAdditionalAssertions);
+ Assert(oldSize <= newSize);
- while (oldAdditionalAssertions < newAdditionalAssertions)
+ while (oldSize < newSize)
{
- Node addA = d_conv->d_additionalAssertions[oldAdditionalAssertions];
+ Node addA = d_conv->d_additionalAssertions[oldSize];
Debug("fp-convertTerm") << "TheoryFp::convertTerm(): additional assertion "
<< addA << std::endl;
nm->mkNode(kind::EQUAL, addA, nm->mkConst(::cvc5::BitVector(1U, 1U))),
InferenceId::FP_EQUATE_TERM);
- ++oldAdditionalAssertions;
+ ++oldSize;
}
// Equate the floating-point atom and the converted one.
return;
}
-void TheoryFp::registerTerm(TNode node) {
+void TheoryFp::registerTerm(TNode node)
+{
Trace("fp-registerTerm") << "TheoryFp::registerTerm(): " << node << std::endl;
- if (!isRegistered(node)) {
+ if (!isRegistered(node))
+ {
Kind k = node.getKind();
Assert(k != kind::FLOATINGPOINT_TO_FP_GENERIC
&& k != kind::FLOATINGPOINT_SUB && k != kind::FLOATINGPOINT_EQ
InferenceId::FP_REGISTER_TERM);
}
- // Use symfpu to produce an equivalent bit-vector statement
- convertAndEquateTerm(node);
+ /* When not word-blasting lazier, we word-blast every term on
+ * registration. */
+ if (!options::fpLazyWb())
+ {
+ convertAndEquateTerm(node);
+ }
}
return;
}
-bool TheoryFp::isRegistered(TNode node) {
- return !(d_registeredTerms.find(node) == d_registeredTerms.end());
+bool TheoryFp::isRegistered(TNode node)
+{
+ return d_registeredTerms.find(node) != d_registeredTerms.end();
}
void TheoryFp::preRegisterTerm(TNode node)
void TheoryFp::postCheck(Effort level)
{
- // Resolve the abstractions for the conversion lemmas
+ /* Resolve the abstractions for the conversion lemmas */
if (level == EFFORT_LAST_CALL)
{
Trace("fp") << "TheoryFp::check(): checking abstractions" << std::endl;
bool TheoryFp::preNotifyFact(
TNode atom, bool pol, TNode fact, bool isPrereg, bool isInternal)
{
+ /* Word-blast lazier if configured. */
+ if (options::fpLazyWb() && d_wbFactsCache.find(atom) == d_wbFactsCache.end())
+ {
+ d_wbFactsCache.insert(atom);
+ convertAndEquateTerm(atom);
+ }
+
if (atom.getKind() == kind::EQUAL)
{
Assert(!(atom[0].getType().isFloatingPoint()
return false;
}
+void TheoryFp::notifySharedTerm(TNode n)
+{
+ /* Word-blast lazier if configured. */
+ if (options::fpLazyWb() && d_wbFactsCache.find(n) == d_wbFactsCache.end())
+ {
+ d_wbFactsCache.insert(n);
+ convertAndEquateTerm(n);
+ }
+}
+
TrustNode TheoryFp::explain(TNode n)
{
Trace("fp") << "TheoryFp::explain(): explain " << n << std::endl;
<< "TheoryFp::collectModelInfo(): relevantVariable " << node
<< std::endl;
- if (!m->assertEquality(node, d_conv->getValue(d_valuation, node), true))
+ Node converted = d_conv->getValue(d_valuation, node);
+ // We only assign the value if the FpConverter actually has one, that is,
+ // if FpConverter::getValue() does not return a null node.
+ if (!converted.isNull() && !m->assertEquality(node, converted, true))
{
return false;
}