Beispiel #1
0
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 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));
}