Lit Solver::pickBranchLit()
{
+ Lit nextLit;
+
#ifdef CVC4_REPLAY
- Lit nextLit = proxy->getNextReplayDecision();
+ nextLit = proxy->getNextReplayDecision();
if (nextLit != lit_Undef) {
return nextLit;
}
#endif /* CVC4_REPLAY */
+ // Theory requests
+ nextLit = proxy->getNextDecisionRequest();
+ while (nextLit != lit_Undef) {
+ if(value(var(nextLit)) == l_Undef) {
+ Debug("propagateAsDecision") << "propagateAsDecision(): now deciding on " << nextLit << std::endl;
+ return nextLit;
+ } else {
+ Debug("propagateAsDecision") << "propagateAsDecision(): would decide on " << nextLit << " but it already has an assignment" << std::endl;
+ }
+ nextLit = proxy->getNextDecisionRequest();
+ }
+
Var next = var_Undef;
// Random decision:
std::vector<Lit> propagatedLiterals;
proxy->theoryPropagate(propagatedLiterals);
int oldTrailSize = trail.size();
+ Debug("minisat") << "old trail size is " << oldTrailSize << ", propagating " << propagatedLiterals.size() << " lits..." << std::endl;
for (unsigned i = 0, i_end = propagatedLiterals.size(); i < i_end; ++ i) {
Debug("minisat") << "Theory propagated: " << propagatedLiterals[i] << std::endl;
// multiple theories can propagate the same literal
uncheckedEnqueue(p, CRef_Lazy);
} else {
// but we check that this is the case and that they agree
+ Debug("minisat") << "trail_index(var(p)) == " << trail_index(var(p)) << std::endl;
Assert(trail_index(var(p)) >= oldTrailSize);
Assert(value(p) == lbool(!sign(p)));
}
d_logic(""),
d_propagatedLiterals(context),
d_propagatedLiteralsIndex(context, 0),
+ d_decisionRequests(context),
+ d_decisionRequestsIndex(context, 0),
d_preRegistrationVisitor(this, context),
d_sharedTermsVisitor(d_sharedTerms)
{
}
}
+void TheoryEngine::propagateAsDecision(TNode literal, theory::TheoryId theory) {
+ Debug("theory") << "EngineOutputChannel::propagateAsDecision(" << literal << ", " << theory << ")" << std::endl;
+
+ d_propEngine->checkTime();
+
+ Assert(d_propEngine->isSatLiteral(literal.getKind() == kind::NOT ? literal[0] : literal), "OutputChannel::propagateAsDecision() requires a SAT literal (or negation of one)");
+
+ d_decisionRequests.push_back(literal);
+}
+
theory::EqualityStatus TheoryEngine::getEqualityStatus(TNode a, TNode b) {
Assert(a.getType() == b.getType());
return theoryOf(Theory::theoryOf(a.getType()))->getEqualityStatus(a, b);
}
-Node TheoryEngine::getExplanation(TNode node)
-{
+Node TheoryEngine::getExplanation(TNode node) {
Debug("theory") << "TheoryEngine::getExplanation(" << node << ")" << std::endl;
TNode atom = node.getKind() == kind::NOT ? node[0] : node;
bool operator == (const NodeTheoryPair& pair) const {
return node == pair.node && theory == pair.theory;
}
-};
+};/* struct NodeTheoryPair */
struct NodeTheoryPairHashFunction {
NodeHashFunction hashFunction;
size_t operator()(const NodeTheoryPair& pair) const {
return hashFunction(pair.node)*0x9e3779b9 + pair.theory;
}
-};
+};/* struct NodeTheoryPairHashFunction */
/**
* This is essentially an abstraction for a collection of theories. A
*/
class Statistics {
- static std::string mkName(std::string prefix, theory::TheoryId theory, std::string suffix) {
+ static std::string mkName(std::string prefix,
+ theory::TheoryId theory,
+ std::string suffix) {
std::stringstream ss;
ss << prefix << theory << suffix;
return ss.str();
public:
- IntStat conflicts, propagations, lemmas;
+ IntStat conflicts, propagations, lemmas, propagationsAsDecisions;
Statistics(theory::TheoryId theory):
conflicts(mkName("theory<", theory, ">::conflicts"), 0),
propagations(mkName("theory<", theory, ">::propagations"), 0),
- lemmas(mkName("theory<", theory, ">::lemmas"), 0)
+ lemmas(mkName("theory<", theory, ">::lemmas"), 0),
+ propagationsAsDecisions(mkName("theory<", theory, ">::propagationsAsDecisions"), 0)
{
StatisticsRegistry::registerStat(&conflicts);
StatisticsRegistry::registerStat(&propagations);
StatisticsRegistry::registerStat(&lemmas);
+ StatisticsRegistry::registerStat(&propagationsAsDecisions);
}
~Statistics() {
StatisticsRegistry::unregisterStat(&conflicts);
StatisticsRegistry::unregisterStat(&propagations);
StatisticsRegistry::unregisterStat(&lemmas);
+ StatisticsRegistry::unregisterStat(&propagationsAsDecisions);
}
};/* class TheoryEngine::Statistics */
d_engine->propagate(literal, d_theory);
}
+ void propagateAsDecision(TNode literal) throw(AssertionException) {
+ Trace("theory") << "EngineOutputChannel<" << d_theory << ">::propagateAsDecision(" << literal << ")" << std::endl;
+ ++ d_statistics.propagationsAsDecisions;
+ d_engine->d_outputChannelUsed = true;
+ d_engine->propagateAsDecision(literal, d_theory);
+ }
+
theory::LemmaStatus lemma(TNode lemma, bool removable = false) throw(TypeCheckingExceptionPrivate, AssertionException) {
Trace("theory") << "EngineOutputChannel<" << d_theory << ">::lemma(" << lemma << ")" << std::endl;
++ d_statistics.lemmas;
d_engine->spendResource();
}
- };/* class EngineOutputChannel */
+ };/* class TheoryEngine::EngineOutputChannel */
/**
* Output channels for individual theories.
context::CDO<bool> d_sharedTermsExist;
/**
- * Explain the equality literals and push all the explaining literals into the builder. All
- * the non-equality literals are pushed to the builder.
+ * Explain the equality literals and push all the explaining literals
+ * into the builder. All the non-equality literals are pushed to the
+ * builder.
*/
void explainEqualities(theory::TheoryId theoryId, TNode literals, NodeBuilder<>& builder);
NodeTheoryPair toAssert;
/** This is the node/theory pair that we will use to explain it */
NodeTheoryPair toExplain;
-
+
SharedEquality(TNode assertion, TNode original, theory::TheoryId sendingTheory, theory::TheoryId receivingTheory)
: toAssert(assertion, receivingTheory),
toExplain(original, sendingTheory)
{ }
- };
-
+ };/* struct SharedEquality */
+
/**
- * Map from equalities asserted to a theory, to the theory that can explain them.
+ * Map from equalities asserted to a theory, to the theory that can explain them.
*/
typedef context::CDMap<NodeTheoryPair, NodeTheoryPair, NodeTheoryPairHashFunction> SharedAssertionsMap;
-
+
/**
* A map from asserted facts to where they came from (for explanations).
*/
/**
* Literals that are propagated by the theory. Note that these are TNodes.
* The theory can only propagate nodes that have an assigned literal in the
- * sat solver and are hence referenced in the SAT solver.
+ * SAT solver and are hence referenced in the SAT solver.
*/
context::CDList<TNode> d_propagatedLiterals;
*/
std::vector<SharedEquality> d_propagatedEqualities;
+ /**
+ * Decisions that are requested via propagateAsDecision(). The theory
+ * can only request decisions on nodes that have an assigned litearl in
+ * the SAT solver and are hence referenced in the SAT solver (making the
+ * use of TNode safe).
+ */
+ context::CDList<TNode> d_decisionRequests;
+
+ /**
+ * The index of the next decision requested by a theory.
+ */
+ context::CDO<unsigned> d_decisionRequestsIndex;
+
/**
* Called by the output channel to propagate literals and facts
*/
*/
void propagate(theory::Theory::Effort effort);
+ /**
+ * Called by the output channel to request decisions "as soon as
+ * possible."
+ */
+ void propagateAsDecision(TNode literal, theory::TheoryId theory);
+
/**
* A variable to mark if we added any lemmas.
*/
}
}
+ TNode getNextDecisionRequest() {
+ if(d_decisionRequestsIndex < d_decisionRequests.size()) {
+ TNode req = d_decisionRequests[d_decisionRequestsIndex];
+ Debug("propagateAsDecision") << "TheoryEngine requesting decision["
+ << d_decisionRequestsIndex << "]: "
+ << req << std::endl;
+ d_decisionRequestsIndex = d_decisionRequestsIndex + 1;
+ return req;
+ } else {
+ return TNode::null();
+ }
+ }
+
bool properConflict(TNode conflict) const;
bool properPropagation(TNode lit) const;
bool properExplanation(TNode node, TNode expl) const;
}
/**
- * Returns the equality status of the two terms, from the theory that owns the domain type.
- * The types of a and b must be the same.
+ * Returns the equality status of the two terms, from the theory
+ * that owns the domain type. The types of a and b must be the same.
*/
theory::EqualityStatus getEqualityStatus(TNode a, TNode b);
PreRegisterVisitor d_preRegistrationVisitor;
/** Visitor for collecting shared terms */
- SharedTermsVisitor d_sharedTermsVisitor;
+ SharedTermsVisitor d_sharedTermsVisitor;
};/* class TheoryEngine */