void SPFWAgg::getExplanation(litlist& lits, const AggReason& ar) { auto agg = ar.getAgg(); auto head = agg.getHead(); bool requiredaggvalue = false; if (ar.isHeadReason()) { requiredaggvalue = head != ar.getPropLit(); // NOTE: check the REQUESTED head value, not its real value if(agg.getSem()==AggSem::OR){ requiredaggvalue = not requiredaggvalue; } } else { requiredaggvalue = value(head) == l_True; if(agg.getSem()==AggSem::OR){ requiredaggvalue = value(head) == l_False; } } auto caseone = requiredaggvalue; Weight min, max; min = getSet().getType().getMinPossible(getSet()); max = getSet().getType().getMaxPossible(getSet()); if (!ar.isHeadReason()) { addValue(getSet().getType(), ar.getPropWeight(), !ar.isInSet(), min, max); lits.push_back(value(head) == l_True ? not head : head); } bool stop = false; vector<PropagationInfo> reasons; if (caseone) { stop = isFalsified(agg, min, max); } else { stop = isSatisfied(agg, min, max); } // FIXME cleanup and add to other explanations PCSolver& pcsolver = getSet().getPCSolver(); const int declevel = pcsolver.getCurrentDecisionLevel(); bool foundpropagatedlit = false; if (pcsolver.modes().currentlevelfirstinexplanation && getTrail().back()->level == declevel) { for (auto i = getTrail().back()->props.cbegin(); not stop && not foundpropagatedlit && i < getTrail().back()->props.cend(); ++i) { auto lit = i->getLit(); MAssert(pcsolver.getLevel(var(lit))==declevel); if (lit == ar.getPropLit()) { //NOTE: We only see a subset of the possibly relevant literals, so we are not guaranteed to find the full explanation before seeing the propagated literal, so we have to redo the loop later on. foundpropagatedlit = true; break; } if (i->getType() == HEAD) { continue; } checkAddToExplan(stop, min, max, *i, agg, caseone, reasons); } } //IMPORTANT: first go over all literals and check which are already in the currently generated partial nogood (only if generating explanation on conflict) if (getSet().modes().aggclausesaving == 2 && pcsolver.modes().innogoodfirstinexplanation) { bool foundpropagatedlit = false; for (auto a = getTrail().cbegin(); !stop && !foundpropagatedlit && a < getTrail().cend(); ++a) { for (auto i = (*a)->props.cbegin(); !stop && !foundpropagatedlit && i < (*a)->props.cend(); ++i) { const Lit& lit = i->getLit(); if (lit == ar.getPropLit()) { //NOTE: We only see a subset of the possibly relevant literals, so we are not guaranteed to find the full explanation before seeing the propagated literal, so we have to redo the loop later on. foundpropagatedlit = true; break; } if (i->getType() == HEAD) { continue; } bool add = true; if (pcsolver.modes().currentlevelfirstinexplanation && pcsolver.getLevel(var(lit)) == declevel) { add = false; } if (!pcsolver.isAlreadyUsedInAnalyze(lit)) { add = false; } if (add) { checkAddToExplan(stop, min, max, *i, agg, caseone, reasons); } } } } //Then go over the trail earliest to latest to add more to the explanation foundpropagatedlit = false; for (auto a = getTrail().cbegin(); !stop && !foundpropagatedlit && a < getTrail().cend(); ++a) { for (auto i = (*a)->props.cbegin(); !stop && !foundpropagatedlit && i < (*a)->props.cend(); ++i) { const Lit& lit = i->getLit(); if (lit == ar.getPropLit()) { //NOTE: We only see a subset of the possibly relevant literals, so we are not guaranteed to find the full explanation before seeing the propagated literal, so we have to redo the loop later on. foundpropagatedlit = true; break; } if (i->getType() == HEAD) { continue; } bool add = true; if (pcsolver.modes().currentlevelfirstinexplanation && pcsolver.getLevel(var(lit)) == declevel) { add = false; } if (getSet().modes().aggclausesaving == 2 && pcsolver.modes().innogoodfirstinexplanation && pcsolver.isAlreadyUsedInAnalyze(lit)) { add = false; } if (add) { checkAddToExplan(stop, min, max, *i, agg, caseone, reasons); } } } MAssert(stop); //Subsetminimization if (getSet().modes().subsetminimizeexplanation) { sort(reasons.begin(), reasons.end(), compareByWeights<PropagationInfo>); for (auto i = reasons.begin(); i < reasons.end(); ++i) { bool inset = i->getType() == POS; removeValue(getSet().getType(), i->getWeight(), inset, min, max); if ((caseone && isFalsified(agg, min, max)) || (!caseone && isSatisfied(agg, min, max))) { i = reasons.erase(i); i--; } else { break; } } } for (auto i = reasons.cbegin(); i < reasons.cend(); ++i) { lits.push_back(not i->getLit()); } }
void MaxFWAgg::getExplanation(litlist& lits, const AggReason& ar) { auto agg = ar.getAgg(); auto head = agg.getHead(); bool search = true, one, inset = false; auto bound = agg.getBound(); if (not ar.isHeadReason()) { lits.push_back(value(head) == l_True ? ~head : head); auto explainheadtrue = value(head)==l_True; if(agg.getSem()==AggSem::OR){ explainheadtrue = not explainheadtrue; } if (explainheadtrue) { if (agg.hasLB()) { //all OTHERS larger or eq to bound one = false; } else { //UB search = false; } } else { //head false if (agg.hasLB()) { search = false; } else { //UB //all OTHERS larger than bound one = false; bound += 1; } } } else { auto explainheadtrue = ar.getPropLit()==head; if(agg.getSem()==AggSem::OR){ explainheadtrue = not explainheadtrue; } if (explainheadtrue) { // NOTE: check the REQUESTED head value, not the real value! if (agg.hasLB()) { //find one larger or eq and inset one = true; inset = true; } else { //UB //all larger than bound one = false; bound += 1; } } else { //head false if (agg.hasLB()) { //all larger or eq than bound one = false; } else { //UB //find one larger and inset inset = true; one = true; bound += 1; } } } if (search) { bool found = false; for (auto a = getTrail().cbegin(); not found && a < getTrail().cend(); ++a) { for (auto i = (*a)->props.cbegin(); not found && i < (*a)->props.cend(); ++i) { if (i->getType() == HEAD || var(i->getLit()) == var(ar.getPropLit())) { continue; } if (i->getWeight() < bound) { continue; } if (inset && i->getType() == NEG) { continue; } lits.push_back(~i->getLit()); if (one) { found = true; } } } if(one && not found){ throw idpexception("Invalid code path"); } } }
void GenPWAgg::getExplanation(litlist& lits, const AggReason& ar) { const auto& pcsol = getSet().getPCSolver(); auto agg = ar.getAgg(); auto head = agg.getHead(); auto caseone = false; if (ar.isHeadReason()) { caseone = head != ar.getPropLit(); } else { caseone = value(head) == l_True; } auto proplit = ar.getPropLit(); auto conflictclause = value(ar.getPropLit()) == l_False; lbool headval = value(head); //if head known and not propagated and generating conflict clause or asserted before if (headval != l_Undef && var(ar.getPropLit()) != var(head) && (conflictclause || pcsol.assertedBefore(var(head), var(proplit)))) { lits.push_back(headval == l_True ? not head : head); } std::vector<wlt> wlis; for (auto i = getWS().cbegin(); i < getWS().cend(); ++i) { if (var((*i)->getWatchLit()) != var(proplit)) { auto lit = (*i)->getWL().getLit(); if (value((*i)->getWatchLit()) == l_True) { wlt wli((*i)->getWL(), getSet().getPCSolver().getTime(var(lit)), (*i)->getWatchLit() == lit); wlis.push_back(wli); } } } for (auto i = getNWS().cbegin(); i < getNWS().cend(); ++i) { if (var((*i)->getWatchLit()) != var(proplit)) { auto lit = (*i)->getWL().getLit(); if (value((*i)->getWatchLit()) == l_True) { wlt wli((*i)->getWL(), getSet().getPCSolver().getTime(var(lit)), (*i)->getWatchLit() == lit); wlis.push_back(wli); } } } //Follow propagation order sort(wlis.begin(), wlis.end(), compareEarlier<wlt>); auto pessbounds = getBoundsOnEmptyInterpr(); if (!ar.isHeadReason()) { //Change value according to propagating negation of proplit addValue(getType(), ar.getPropWeight(), !ar.isInSet(), pessbounds); } vector<wlt> reasons; for (auto i = wlis.cbegin(); !isFalsified(ar.getAgg(), pessbounds) && i < wlis.cend(); ++i) { if (var(i->getLit()) == var(proplit)) { continue; } if (conflictclause || pcsol.assertedBefore(var(i->getLit()), var(proplit))) { addValue(getType(), i->getWeight(), i->inset, pessbounds); reasons.push_back(*i); } } //Subsetminimization if (getSet().modes().subsetminimizeexplanation) { sort(reasons.begin(), reasons.end(), compareByWeights<wlt>); for (auto i = reasons.begin(); i < reasons.end(); ++i) { removeValue(getSet().getType(), i->getWeight(), i->inset, pessbounds); if ((caseone && isFalsified(agg, pessbounds)) || (!caseone && isSatisfied(agg, pessbounds))) { i = reasons.erase(i); i--; } else { break; } } } for (auto i = reasons.cbegin(); i < reasons.cend(); ++i) { lits.push_back(value(i->getLit()) == l_True ? not i->getLit() : i->getLit()); } MAssert(isFalsified(ar.getAgg(), pessbounds)); }