outputPropagate(toProp);
}else if(constraint->negationHasProof()){
- Node exp = d_congruenceManager.explain(toProp).getNode();
- Node notNormalized = normalized.getKind() == NOT ?
- normalized[0] : normalized.notNode();
- Node lp = flattenAnd(exp.andNode(notNormalized));
+ // The congruence manager can prove: antecedents => toProp,
+ // ergo. antecedents ^ ~toProp is a conflict.
+ TrustNode exp = d_congruenceManager.explain(toProp);
+ Node notNormalized = normalized.negate();
+ std::vector<Node> ants(exp.getNode().begin(), exp.getNode().end());
+ ants.push_back(notNormalized);
+ Node lp = safeConstructNary(kind::AND, ants);
Debug("arith::prop") << "propagate conflict" << lp << endl;
- raiseBlackBoxConflict(lp);
+ if (proofsEnabled())
+ {
+ // Assume all of antecedents and ~toProp (rewritten)
+ std::vector<Pf> pfAntList;
+ for (size_t i = 0; i < ants.size(); ++i)
+ {
+ pfAntList.push_back(d_pnm->mkAssume(ants[i]));
+ }
+ Pf pfAnt = pfAntList.size() > 1
+ ? d_pnm->mkNode(PfRule::AND_INTRO, pfAntList, {})
+ : pfAntList[0];
+ // Use modus ponens to get toProp (un rewritten)
+ Pf pfConc = d_pnm->mkNode(
+ PfRule::MODUS_PONENS,
+ {pfAnt, exp.getGenerator()->getProofFor(exp.getProven())},
+ {});
+ // prove toProp (rewritten)
+ Pf pfConcRewritten = d_pnm->mkNode(
+ PfRule::MACRO_SR_PRED_TRANSFORM, {pfConc}, {normalized});
+ Pf pfNotNormalized = d_pnm->mkAssume(notNormalized);
+ // prove bottom from toProp and ~toProp
+ Pf pfBot;
+ if (normalized.getKind() == kind::NOT)
+ {
+ pfBot = d_pnm->mkNode(
+ PfRule::CONTRA, {pfNotNormalized, pfConcRewritten}, {});
+ }
+ else
+ {
+ pfBot = d_pnm->mkNode(
+ PfRule::CONTRA, {pfConcRewritten, pfNotNormalized}, {});
+ }
+ // close scope
+ Pf pfNotAnd = d_pnm->mkScope(pfBot, ants);
+ raiseBlackBoxConflict(lp, pfNotAnd);
+ }
+ else
+ {
+ raiseBlackBoxConflict(lp);
+ }
outputConflicts();
return;
}else{