This makes it so that EqSolver is the main entry point for all equality engine explanations in arithmetic; it still defers to the CongruenceManager to compute these explanations.
To do this, when the core linear solver depends on an explanation from the equality engine, it instead provides a placeholder. Since explanations are computed recursively in TheoryEngine, this will trigger another call to TheoryArith::explain, which will then be handled by the EqSolver. Thus, there should be no net effect on the overall explanations in this commit.
This is work towards eliminating the dependency of the linear solver on the equality engine.
TrustNode EqualitySolver::explain(TNode lit)
{
Trace("arith-eq-solver-debug") << "explain " << lit << "?" << std::endl;
+ if (d_acm != nullptr)
+ {
+ // if we are using the congruence manager, consult whether it can explain
+ if (d_acm->canExplain(lit))
+ {
+ return d_acm->explain(lit);
+ }
+ // otherwise, don't explain
+ return TrustNode::null();
+ }
// check if we propagated it?
if (d_propLits.find(lit) == d_propLits.end())
{
return true;
}
-void ArithCongruenceManager::enqueueIntoNB(const std::set<TNode> s,
- NodeBuilder& nb)
-{
- std::set<TNode>::const_iterator it = s.begin();
- std::set<TNode>::const_iterator it_end = s.end();
- for(; it != it_end; ++it) {
- nb << *it;
- }
-}
-
TrustNode ArithCongruenceManager::explainInternal(TNode internal)
{
if (isProofEnabled())
void enableSharedTerms();
void dequeueLiterals();
- void enqueueIntoNB(const std::set<TNode> all, NodeBuilder& nb);
-
/**
* Determine an explaination for `internal`. That is a conjunction of theory
* literals which imply `internal`.
}
else if (hasEqualityEngineProof())
{
- Trace("pf::arith::explain") << " going to ee:" << std::endl;
- TrustNode exp = d_database->eeExplain(this);
+ // just assume, it will be explained again
+ Node lit = getLiteral();
if (d_database->isProofEnabled())
{
- Assert(exp.getProven().getKind() == Kind::IMPLIES);
- std::vector<std::shared_ptr<ProofNode>> hypotheses;
- hypotheses.push_back(exp.getGenerator()->getProofFor(exp.getProven()));
- if (exp.getNode().getKind() == Kind::AND)
- {
- for (const auto& h : exp.getNode())
- {
- hypotheses.push_back(
- pnm->mkNode(PfRule::TRUE_INTRO, {pnm->mkAssume(h)}, {}));
- }
- }
- else
- {
- hypotheses.push_back(pnm->mkNode(
- PfRule::TRUE_INTRO, {pnm->mkAssume(exp.getNode())}, {}));
- }
+ std::shared_ptr<ProofNode> a = pnm->mkAssume(getLiteral());
pf = pnm->mkNode(
- PfRule::MACRO_SR_PRED_TRANSFORM, {hypotheses}, {getProofLiteral()});
- }
- Trace("pf::arith::explain")
- << " explanation: " << exp.getNode() << std::endl;
- if (exp.getNode().getKind() == Kind::AND)
- {
- nb.append(exp.getNode().begin(), exp.getNode().end());
- }
- else
- {
- nb << exp.getNode();
+ PfRule::MACRO_SR_PRED_TRANSFORM, {a}, {getProofLiteral()});
}
+ Assert(lit.getKind() != kind::AND);
+ nb << lit;
}
else
{
}
}
}
-TrustNode ConstraintDatabase::eeExplain(const Constraint* const c) const
-{
- Assert(c->hasLiteral());
- return d_congruenceManager.explain(c->getLiteral());
-}
bool ConstraintDatabase::variableDatabaseIsSetup(ArithVar v) const {
return v < d_varDatabases.size();
bool variableDatabaseIsSetup(ArithVar v) const;
void removeVariable(ArithVar v);
- /** Get an explanation and proof for this constraint from the equality engine
- */
- TrustNode eeExplain(ConstraintCP c) const;
-
/**
* Returns a constraint with the variable v, the constraint type t, and a value
* dominated by r (explained below) if such a constraint exists in the database.
ConstraintP c = d_constraintDatabase.lookup(n);
TrustNode exp;
- if(c != NullConstraint){
+ // explanations that involve the congruence manager are handled in the
+ // main theory class.
+ Assert(!d_congruenceManager.canExplain(n));
+ if (c != NullConstraint)
+ {
Assert(!c->isAssumption());
exp = c->externalExplainForPropagation(n);
Trace("arith::explain") << "constraint explanation" << n << ":" << exp << endl;
- }else if(d_assertionsThatDoNotMatchTheirLiterals.find(n) != d_assertionsThatDoNotMatchTheirLiterals.end()){
+ }
+ else if (d_assertionsThatDoNotMatchTheirLiterals.find(n)
+ != d_assertionsThatDoNotMatchTheirLiterals.end())
+ {
c = d_assertionsThatDoNotMatchTheirLiterals[n];
if(!c->isAssumption()){
exp = c->externalExplainForPropagation(n);
Trace("arith::explain") << "assertions explanation" << n << ":" << exp << endl;
- }else{
- Trace("arith::explain") << "this is a strange mismatch" << n << endl;
- Assert(d_congruenceManager.canExplain(n));
- exp = d_congruenceManager.explain(n);
}
- }else{
- Assert(d_congruenceManager.canExplain(n));
- Trace("arith::explain") << "dm explanation" << n << endl;
- exp = d_congruenceManager.explain(n);
}
return exp;
}
TrustNode TheoryArith::explain(TNode n)
{
- if (options().arith.arithEqSolver)
+ // if the equality solver has an explanation for it, use it
+ TrustNode texp = d_eqSolver->explain(n);
+ if (!texp.isNull())
{
- // if the equality solver has an explanation for it, use it
- TrustNode texp = d_eqSolver->explain(n);
- if (!texp.isNull())
- {
- return texp;
- }
+ return texp;
}
return d_internal->explain(n);
}