/** * Return the value the head should take if some propagation is possible. */ lbool MinisatID::canPropagateHead(const Agg& agg, const Weight& CC, const Weight& CP) { //if (nomoreprops[agg.getIndex()] || headproptime[agg.getIndex()]!=-1) { // return headvalue[agg.getIndex()]; //} auto result = l_Undef; //add if derived: headproptime[agg.getIndex()] = getStack().size(); auto b = agg.getBound(); if (agg.hasUB()) { if (CC > b) { result = l_False; } else if (CP <= b) { result = l_True; } } else { if (CC >= b) { result = l_True; } else if (CP < b) { result = l_False; } } if(agg.getSem()==AggSem::OR){ if(result==l_True){ result = l_Undef; }else if(result==l_False){ result = l_True; } } return result; }
/** * Returns non-owning pointer */ rClause MaxFWAgg::propagateAll(const Agg& agg, bool headtrue) { rClause confl = nullPtrClause; // if(nomoreprops[agg.getIndex()] || headproptime[agg.getIndex()]!=-1){ return confl; } if ((!agg.hasLB() && headtrue) || (!agg.hasUB() && !headtrue)) { return confl; } Lit l = mkPosLit(0); Weight w(0); int found = 0; for (vwl::const_iterator i = getSet().getWL().cbegin(); found < 2 && i < getSet().getWL().cend(); ++i) { const WL& wl = (*i); if (headtrue) { if (agg.hasLB() && wl.getWeight() < agg.getBound()) { continue; } if (agg.hasUB() && wl.getWeight() > agg.getBound()) { continue; } } else { //headfalse if ((!agg.hasLB() || wl.getWeight() >= agg.getBound()) && (!agg.hasUB() || wl.getWeight() <= agg.getBound())) { continue; } } if (value(wl.getLit()) == l_Undef) { ++found; l = wl.getLit(); w = wl.getWeight(); } else if (value(wl.getLit()) == l_True) { found = 2; //hack to stop immediately, because no propagation necessary } } if (found == 1) { confl = getSet().notifySolver(new SetLitReason(agg, l, w, true)); } return confl; }
rClause GenPWAgg::checkHeadPropagationForAgg(bool& propagations, const Agg& agg, const minmaxBounds& bound) { auto confl = nullPtrClause; auto propagatehead = false; if (agg.hasLB() && bound.max < agg.getBound()) { propagatehead = true; } else if (agg.hasUB() && agg.getBound() < bound.min) { propagatehead = true; } if (propagatehead) { propagations = true; confl = getSet().notifySolver(new HeadReason(agg, agg.getHead())); notifyFirstPropagation(agg.getHead()); } return confl; }
/** * Returns non-owning pointer */ rClause MaxFWAgg::propagateSpecificAtEnd(const Agg& agg, bool headtrue) { //if(nomoreprops[agg.getIndex()] || headproptime[agg.getIndex()]!=-1){ return nullPtrClause; } auto confl = nullPtrClause; if (headtrue && agg.hasUB()) { for (auto i = getSet().getWL().rbegin(); confl == nullPtrClause && i < getSet().getWL().rend() && agg.getBound() < i->getWeight(); ++i) { confl = getSet().notifySolver(new SetLitReason(agg, i->getLit(), i->getWeight(), false)); } } else if (!headtrue && agg.hasLB()) { for (auto i = getSet().getWL().rbegin(); confl == nullPtrClause && i < getSet().getWL().rend() && agg.getBound() <= i->getWeight(); ++i) { confl = getSet().notifySolver(new SetLitReason(agg, i->getLit(), i->getWeight(), false)); } } if (confl == nullPtrClause) { confl = propagateAll(agg, headtrue); } return confl; }
// Can return NULL, if no heads are false (or unknown if includeunknown) Agg* GenPWAgg::getAggWithMostStringentBound(bool includeunknown) const { Agg* strongestagg = NULL; for (auto i = getAgg().cbegin(); i < getAgg().cend(); ++i) { bool relevantagg = false; // NOTE: recall HEAD OR AGG if (includeunknown) { relevantagg |= value((*i)->getHead()) != l_True; } else { relevantagg |= value((*i)->getHead()) == l_False; } if (relevantagg) { if (strongestagg == NULL) { strongestagg = *i; } else if (strongestagg->hasLB() && strongestagg->getBound() < (*i)->getBound()) { strongestagg = *i; } else if (strongestagg->hasUB() && strongestagg->getBound() > (*i)->getBound()) { strongestagg = *i; } } } return strongestagg; }
/** * if headtrue && lb => make all literals true with weight > (CP - lb) * ub => make all literals false with weight > (ub - CC) * if !headtrue && lb => make all literals false with weight > (lb - CC) * ub => make all literals true with weight > (CP - ub) * if both bounds: do both for headtrue * do none for headfalse until cc >= lb or cp <= ub */ rClause SPFWAgg::propagateSpecificAtEnd(const Agg& agg, bool headtrue) { rClause c = nullPtrClause; //if (nomoreprops[agg.getIndex()] || headproptime[agg.getIndex()]!=-1) { // return nullPtrClause; //} auto& set = getSet(); const auto& wls = set.getWL(); auto from = wls.cend(); Weight weightbound; bool ub = agg.hasUB(); auto bound = agg.getBound(); //determine the lower bound of which weight literals to consider const AggProp& type = getSet().getType(); if (headtrue) { if (ub) { weightbound = type.removeMin(bound, getCC()); //+1 because larger and not eq if (type.add(weightbound, getCC()) <= bound) { weightbound += 1; } } else { weightbound = type.removeMax(getCP(), bound); //+1 because larger and not eq if (type.add(weightbound, bound) <= getCP()) { weightbound += 1; } } } else { //head false if (ub) { weightbound = type.removeMax(getCP(), bound); } else { weightbound = type.removeMin(bound, getCC()); } } #ifdef NOARBITPREC if (weightbound == posInfinity() || weightbound == negInfinity()) { return c; } #endif from = lower_bound(wls.cbegin(), wls.cend(), weightbound); if (from == getSet().getWL().cend()) { return c; } /** * The lower bound indicates from which bound all literals should be propagate that are not yet known to the aggregate solver * All literals known to the sat solver are certainly sa */ for (auto u = from; c == nullPtrClause && u < wls.cend(); ++u) { auto l = (*u).getLit(); bool propagate = value(l) == l_Undef; if (!propagate && getSet().getPCSolver().getLevel(var(l)) == getSet().getPCSolver().getCurrentDecisionLevel()) { bool found = false; for (auto i = getTrail().back()->props.cbegin(); !found && i < getTrail().back()->props.cend(); ++i) { if (var(l) == var(i->getLit())) { found = true; } } propagate = !found; } //Only propagate those that are not already known in the aggregate solver! if (propagate) { if ((agg.hasUB() && headtrue) || (!agg.hasUB() && !headtrue)) { c = getSet().notifySolver(new SetLitReason(agg, (*u).getLit(), (*u).getWeight(), false)); } else { c = getSet().notifySolver(new SetLitReason(agg, (*u).getLit(), (*u).getWeight(), true)); } } } //TODO the looping over the trail is TOO slow! compared to old card //TODO but bigger problem is that he keeps on deriving the same propagations! //=> add a check that does not do propagations if the derived weight bound is the same //=> add a check that if only cp or cc is adapted, only aggs with such bound are checked! return c; }