Node concAtom = concPol ? conc : conc[0];
concEq = concAtom.eqNode(nm->mkConst(concPol));
}
- Assert(concEq.getKind() == EQUAL
- && concEq[0].getKind() == APPLY_SELECTOR_TOTAL);
- Assert(exp[0].getType().isDatatype());
- Node sop = concEq[0].getOperator();
- Node sl = nm->mkNode(APPLY_SELECTOR_TOTAL, sop, exp[0]);
- Node sr = nm->mkNode(APPLY_SELECTOR_TOTAL, sop, exp[1]);
- // exp[0] = exp[1]
- // --------------------- CONG ----------------- DT_COLLAPSE
- // s(exp[0]) = s(exp[1]) s(exp[1]) = r
- // --------------------------------------------------- TRANS
- // s(exp[0]) = r
- Node asn = ProofRuleChecker::mkKindNode(APPLY_SELECTOR_TOTAL);
- Node seq = sl.eqNode(sr);
- cdp->addStep(seq, PfRule::CONG, {exp}, {asn, sop});
- Node sceq = sr.eqNode(concEq[1]);
- cdp->addStep(sceq, PfRule::DT_COLLAPSE, {}, {sr});
- cdp->addStep(sl.eqNode(concEq[1]), PfRule::TRANS, {seq, sceq}, {});
- if (conc.getKind() != EQUAL)
+ if (concEq[0].getKind() != APPLY_SELECTOR_TOTAL)
{
- PfRule eid =
- conc.getKind() == NOT ? PfRule::FALSE_ELIM : PfRule::TRUE_ELIM;
- cdp->addStep(conc, eid, {concEq}, {});
+ // can happen for Boolean term variables, which are not currently
+ // supported.
+ success = false;
+ }
+ else
+ {
+ Assert(exp[0].getType().isDatatype());
+ Node sop = concEq[0].getOperator();
+ Node sl = nm->mkNode(APPLY_SELECTOR_TOTAL, sop, exp[0]);
+ Node sr = nm->mkNode(APPLY_SELECTOR_TOTAL, sop, exp[1]);
+ // exp[0] = exp[1]
+ // --------------------- CONG ----------------- DT_COLLAPSE
+ // s(exp[0]) = s(exp[1]) s(exp[1]) = r
+ // --------------------------------------------------- TRANS
+ // s(exp[0]) = r
+ Node asn = ProofRuleChecker::mkKindNode(APPLY_SELECTOR_TOTAL);
+ Node seq = sl.eqNode(sr);
+ cdp->addStep(seq, PfRule::CONG, {exp}, {asn, sop});
+ Node sceq = sr.eqNode(concEq[1]);
+ cdp->addStep(sceq, PfRule::DT_COLLAPSE, {}, {sr});
+ cdp->addStep(sl.eqNode(concEq[1]), PfRule::TRANS, {seq, sceq}, {});
+ if (conc.getKind() != EQUAL)
+ {
+ PfRule eid =
+ conc.getKind() == NOT ? PfRule::FALSE_ELIM : PfRule::TRUE_ELIM;
+ cdp->addStep(conc, eid, {concEq}, {});
+ }
+ success = true;
}
- success = true;
}
break;
case InferenceId::DATATYPES_CLASH_CONFLICT:
Trace("strings-ipc-core") << "...success!" << std::endl;
}
}
+ else if (infer == InferenceId::STRINGS_F_NCTN
+ || infer == InferenceId::STRINGS_N_NCTN)
+ {
+ // May require extended equality rewrite, applied after the rewrite
+ // above. Notice we need both in sequence since ext equality rewriting
+ // is not recursive.
+ std::vector<Node> argsERew;
+ addMethodIds(argsERew,
+ MethodId::SB_DEFAULT,
+ MethodId::SBA_SEQUENTIAL,
+ MethodId::RW_REWRITE_EQ_EXT);
+ Node mainEqERew =
+ psb.tryStep(PfRule::MACRO_SR_PRED_ELIM, {mainEqCeq}, argsERew);
+ if (mainEqERew == conc)
+ {
+ useBuffer = true;
+ Trace("strings-ipc-core") << "...success!" << std::endl;
+ }
+ }
else
{
std::vector<Node> tvec;
Trace("strings-ipc-prefix")
<< "- Possible conflicting equality : " << curr << std::endl;
std::vector<Node> emp;
- Node concE = psb.applyPredElim(curr, emp);
+ Node concE = psb.applyPredElim(curr,
+ emp,
+ MethodId::SB_DEFAULT,
+ MethodId::SBA_SEQUENTIAL,
+ MethodId::RW_REWRITE_EQ_EXT);
Trace("strings-ipc-prefix")
<< "- After pred elim: " << concE << std::endl;
if (concE == conc)