void conflict(TNode conflictNode) throw(AssertionException) {
Trace("theory") << "EngineOutputChannel<" << d_theory << ">::conflict(" << conflictNode << ")" << std::endl;
++ d_statistics.conflicts;
+ d_engine->d_outputChannelUsed = true;
d_engine->conflict(conflictNode, d_theory);
}
void propagate(TNode literal) throw(AssertionException) {
Trace("theory") << "EngineOutputChannel<" << d_theory << ">::propagate(" << literal << ")" << std::endl;
++ d_statistics.propagations;
+ d_engine->d_outputChannelUsed = true;
d_engine->propagate(literal, d_theory);
}
unsigned lemma(TNode lemma, bool removable = false) throw(TypeCheckingExceptionPrivate, AssertionException) {
Trace("theory") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
++ d_statistics.lemmas;
+ d_engine->d_outputChannelUsed = true;
return d_engine->lemma(lemma, false, removable);
}
*/
bool d_lemmasAdded;
+ /**
+ * A variable to mark if the OutputChannel was "used" by any theory
+ * since the start of the last check. If it has been, we require
+ * a FULL_EFFORT check before exiting and reporting SAT.
+ *
+ * See the documentation for the needCheck() function, below.
+ */
+ bool d_outputChannelUsed;
+
/**
* Adds a new lemma
*/
}
/**
- * Runs theory specific preprocesssing on the non-Boolean parts of the formula.
- * This is only called on input assertions, after ITEs have been removed.
+ * Runs theory specific preprocesssing on the non-Boolean parts of
+ * the formula. This is only called on input assertions, after ITEs
+ * have been removed.
*/
Node preprocess(TNode node);
/**
* Return whether or not we are incomplete (in the current context).
*/
- inline bool isIncomplete() {
+ inline bool isIncomplete() const {
return d_incomplete;
}
+ /**
+ * Returns true if we need another round of checking. If this
+ * returns true, check(FULL_EFFORT) _must_ be called by the
+ * propositional layer before reporting SAT.
+ *
+ * This is especially necessary for incomplete theories that lazily
+ * output some lemmas on FULL_EFFORT check (e.g. quantifier reasoning
+ * outputing quantifier instantiations). In such a case, a lemma can
+ * be asserted that is simplified away (perhaps it's already true).
+ * However, we must maintain the invariant that, if a theory uses the
+ * OutputChannel, it implicitly requests that another check(FULL_EFFORT)
+ * be performed before exit, even if no new facts are on its fact queue,
+ * as it might decide to further instantiate some lemmas, precluding
+ * a SAT response.
+ */
+ inline bool needCheck() const {
+ return d_outputChannelUsed || d_lemmasAdded;
+ }
+
/**
* This is called at shutdown time by the SmtEngine, just before
* destruction. It is important because there are destruction