diff options
Diffstat (limited to 'src/theory/theory_engine.cpp')
-rw-r--r-- | src/theory/theory_engine.cpp | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/src/theory/theory_engine.cpp b/src/theory/theory_engine.cpp index 8abc7a0e3..060d48230 100644 --- a/src/theory/theory_engine.cpp +++ b/src/theory/theory_engine.cpp @@ -394,7 +394,9 @@ void TheoryEngine::combineTheories() { Assert(!d_sharedTerms.areDisequal(carePair.a, carePair.b), "Please don't care about stuff you were notified about"); // The equality in question - Node equality = Rewriter::rewriteEquality(carePair.theory, carePair.a.eqNode(carePair.b)); + Node equality = carePair.a < carePair.b ? + carePair.a.eqNode(carePair.b) : + carePair.b.eqNode(carePair.a); // Normalize the equality Node normalizedEquality = Rewriter::rewrite(equality); @@ -862,33 +864,41 @@ void TheoryEngine::assertToTheory(TNode assertion, theory::TheoryId toTheoryId, } return; } - - // We are left with internal distribution of shared literals - Assert(atom.getKind() == kind::EQUAL); - Node normalizedAtom = Rewriter::rewriteEquality(toTheoryId, atom); - Node normalizedAssertion = polarity ? normalizedAtom : normalizedAtom.notNode(); - - // If we normalize to true or false, it's a special case - if (normalizedAtom.isConst()) { - if (polarity == normalizedAtom.getConst<bool>()) { - // Trivially true, just ignore - return; + + // See if it rewrites to true or false directly + Node normalizedLiteral = Rewriter::rewrite(assertion); + if (normalizedLiteral.isConst()) { + if (normalizedLiteral.getConst<bool>()) { + // trivially true, but theories need to share even trivially true facts + // unless of course it is the theory that normalized it + if (Theory::theoryOf(atom) == toTheoryId) { + return; + } } else { // Mark the propagation for explanations - if (markPropagation(normalizedAssertion, assertion, toTheoryId, fromTheoryId)) { + if (markPropagation(normalizedLiteral, assertion, toTheoryId, fromTheoryId)) { // Get the explanation (conflict will figure out where it came from) - conflict(normalizedAssertion, toTheoryId); + conflict(normalizedLiteral, toTheoryId); } else { Unreachable(); } return; } } - - // Try and assert + + // Normalize to lhs < rhs + Assert(atom.getKind() == kind::EQUAL); + Assert(atom[0] != atom[1]); + Node normalizedAtom = atom; + if (atom[0] > atom[1]) { + normalizedAtom = atom[1].eqNode(atom[0]); + } + Node normalizedAssertion = polarity ? normalizedAtom : normalizedAtom.notNode(); + + // Try and assert (note that we assert the non-normalized one) if (markPropagation(normalizedAssertion, assertion, toTheoryId, fromTheoryId)) { // Check if has been pre-registered with the theory - bool preregistered = d_propEngine->isSatLiteral(normalizedAssertion) && Theory::theoryOf(normalizedAtom) == toTheoryId; + bool preregistered = d_propEngine->isSatLiteral(normalizedAssertion) && Theory::theoryOf(normalizedAssertion) == toTheoryId; // Assert away theoryOf(toTheoryId)->assertFact(normalizedAssertion, preregistered); d_factsAsserted = true; @@ -1139,9 +1149,8 @@ void TheoryEngine::conflict(TNode conflict, TheoryId theoryId) { Assert(properConflict(fullConflict)); lemma(fullConflict, true, true); } else { - Debug("theory::conflict") << "TheoryEngine::conflict(" << conflict << ", " << theoryId << "):" << std::endl; - // When only one theory, the conflict should need no processing + Debug("theory::conflict") << "TheoryEngine::conflict(" << conflict << ", " << theoryId << ")" << std::endl; Assert(properConflict(conflict)); lemma(conflict, true, true); } |