// must correct the orientation on this leaf
std::vector<std::shared_ptr<ProofNode>> children;
children.push_back(pfaa);
- std::vector<Node> args;
- args.push_back(a);
for (std::shared_ptr<ProofNode> pfs : fa.second)
{
Assert(pfs->getResult() == a);
- updateNode(pfs.get(), PfRule::MACRO_SR_PRED_TRANSFORM, children, args);
+ // use SYMM if possible
+ if (aMatch == aeqSym)
+ {
+ updateNode(pfs.get(), PfRule::SYMM, children, {});
+ }
+ else
+ {
+ updateNode(pfs.get(), PfRule::MACRO_SR_PRED_TRANSFORM, children, {a});
+ }
}
Trace("pnm-scope") << "...finished" << std::endl;
acu.insert(aMatch);
Node minExpected;
NodeManager* nm = NodeManager::currentNM();
Node exp;
- Node conc = pf->getResult();
if (assumps.empty())
{
- Assert(!conc.isConst());
- minExpected = conc;
+ // SCOPE with no arguments is a no-op, just return original
+ return pf;
+ }
+ Node conc = pf->getResult();
+ exp = assumps.size() == 1 ? assumps[0] : nm->mkNode(AND, assumps);
+ if (conc.isConst() && !conc.getConst<bool>())
+ {
+ minExpected = exp.notNode();
}
else
{
- exp = assumps.size() == 1 ? assumps[0] : nm->mkNode(AND, assumps);
- if (conc.isConst() && !conc.getConst<bool>())
- {
- minExpected = exp.notNode();
- }
- else
- {
- minExpected = nm->mkNode(IMPLIES, exp, conc);
- }
+ minExpected = nm->mkNode(IMPLIES, exp, conc);
}
return mkNode(PfRule::SCOPE, {pf}, assumps, minExpected);
}
*
* Additionally, if both ensureClosed and doMinimize are true, assumps is
* updated to contain exactly the free asumptions of pf. This also includes
- * having no duplicates.
+ * having no duplicates. Furthermore, if assumps is empty after minimization,
+ * this method is a no-op.
*
* In each case, the update vector assumps is passed as arguments to SCOPE.
*
scopeAssumps.push_back(a);
}
}
- // scope the proof constructed above, and connect the formula with the proof
- // minimize the assumptions
+ // Scope the proof constructed above, and connect the formula with the proof
+ // minimize the assumptions.
pf = d_pnm->mkScope(pfBody, scopeAssumps, true, true);
+ // If we have no assumptions, and are proving an explanation for propagation
+ if (scopeAssumps.empty() && tnk == TrustNodeKind::PROP_EXP)
+ {
+ // Must add "true" as an explicit argument. This is to ensure that the
+ // propagation F from true proves (=> true F) instead of F, since this is
+ // the form required by TrustNodeKind::PROP_EXP. We do not ensure closed or
+ // minimize here, since we already ensured the proof was closed above, and
+ // we do not want to minimize, or else "true" would be omitted.
+ scopeAssumps.push_back(nm->mkConst(true));
+ pf = d_pnm->mkScope(pf, scopeAssumps, false);
+ }
exp = nm->mkAnd(scopeAssumps);
// Make the lemma or conflict node. This must exactly match the conclusion
// of SCOPE below.