d_out(t.getOutputChannel()),
d_ee(nullptr),
d_decManager(nullptr),
+ d_pfee(nullptr),
d_pnm(pnm),
d_cacheLemmas(cacheLemmas),
d_keep(t.getSatContext()),
{
d_ee = ee;
// if proofs are enabled, also make a proof equality engine to wrap ee
- // if it is non-null
+ // if it is non-null. If its proof equality engine has already been assigned,
+ // use it. This is to ensure that all theories use the same proof equality
+ // engine when in ee-mode=central.
if (d_pnm != nullptr && d_ee != nullptr)
{
- d_pfee.reset(new eq::ProofEqEngine(d_theoryState.getSatContext(),
- d_theoryState.getUserContext(),
- *d_ee,
- d_pnm));
+ d_pfee = d_ee->getProofEqualityEngine();
+ if (d_pfee == nullptr)
+ {
+ d_pfeeAlloc.reset(new eq::ProofEqEngine(d_theoryState.getSatContext(),
+ d_theoryState.getUserContext(),
+ *d_ee,
+ d_pnm));
+ d_pfee = d_pfeeAlloc.get();
+ d_ee->setProofEqualityEngine(d_pfee);
+ }
}
}
|| d_numCurrentFacts > 0;
}
-eq::ProofEqEngine* TheoryInferenceManager::getProofEqEngine()
-{
- return d_pfee.get();
-}
+eq::ProofEqEngine* TheoryInferenceManager::getProofEqEngine() { return d_pfee; }
void TheoryInferenceManager::conflictEqConstantMerge(TNode a, TNode b)
{
Trace("infer-manager") << "TheoryInferenceManager::assertInternalFact: "
<< (pol ? Node(atom) : atom.notNode()) << " from "
<< expn << std::endl;
+ if (Configuration::isAssertionBuild())
+ {
+ // check that all facts hold in the equality engine, to ensure that we
+ // aren't processing a stale fact
+ std::vector<Node> expc = exp;
+ for (size_t i = 0; i < expc.size(); i++)
+ {
+ Node e = expc[i];
+ bool epol = e.getKind() != NOT;
+ Node eatom = epol ? e : e[0];
+ Trace("infer-manager")
+ << "...check " << eatom << " " << epol << std::endl;
+ if (eatom.getKind() == AND)
+ {
+ Assert(epol);
+ for (const Node& ea : eatom)
+ {
+ expc.push_back(ea);
+ }
+ continue;
+ }
+ else if (eatom.getKind() == EQUAL)
+ {
+ Assert(d_ee->hasTerm(eatom[0]));
+ Assert(d_ee->hasTerm(eatom[1]));
+ Assert(!epol || d_ee->areEqual(eatom[0], eatom[1]));
+ Assert(epol || d_ee->areDisequal(eatom[0], eatom[1], false));
+ }
+ else
+ {
+ Assert(d_ee->hasTerm(eatom));
+ Assert(d_ee->areEqual(eatom, NodeManager::currentNM()->mkConst(epol)));
+ }
+ }
+ }
d_numCurrentFacts++;
// Now, assert the fact. How to do so depends on whether proofs are enabled.
// If no proof production, or no proof rule was given
bool constantsAreTriggers,
bool anyTermTriggers)
: ContextNotifyObj(context),
- d_masterEqualityEngine(0),
+ d_masterEqualityEngine(nullptr),
+ d_proofEqualityEngine(nullptr),
d_context(context),
d_done(context, false),
d_notify(&s_notifyNone),
}
void EqualityEngine::setMasterEqualityEngine(EqualityEngine* master) {
- Assert(d_masterEqualityEngine == 0);
+ Assert(d_masterEqualityEngine == nullptr);
d_masterEqualityEngine = master;
}
+void EqualityEngine::setProofEqualityEngine(ProofEqEngine* pfee)
+{
+ Assert(d_proofEqualityEngine == nullptr);
+ d_proofEqualityEngine = pfee;
+}
+ProofEqEngine* EqualityEngine::getProofEqualityEngine()
+{
+ return d_proofEqualityEngine;
+}
+
void EqualityEngine::enqueue(const MergeCandidate& candidate, bool back) {
Debug("equality") << d_name << "::eq::enqueue({" << candidate.d_t1Id << "} "
<< d_nodes[candidate.d_t1Id] << ", {" << candidate.d_t2Id
class EqClassesIterator;
class EqClassIterator;
class EqProof;
+class ProofEqEngine;
/**
* Class for keeping an incremental congruence closure over a set of terms. It provides
*/
EqualityEngine* d_masterEqualityEngine;
+ /** Proof equality engine */
+ ProofEqEngine* d_proofEqualityEngine;
+
public:
/**
* Initialize the equality engine, given the notification class.
* of all the terms and equalities from this engine.
*/
void setMasterEqualityEngine(EqualityEngine* master);
+ /** Set the proof equality engine for this one. */
+ void setProofEqualityEngine(ProofEqEngine* pfee);
+ /** Get the proof equality engine */
+ ProofEqEngine* getProofEqualityEngine();
/** Print the equivalence classes for debugging */
std::string debugPrintEqc() const;