Example #1
0
/**
 * 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;
}
Example #2
0
/**
 * 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;
}
Example #4
0
/**
 * 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;
}
Example #6
0
/**
 * 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;
}