Пример #1
0
void Definition::addRule(uint id, bool onlyif, int defID, bool conj, Atom head, const litlist& ps) {
	auto& def = rules[defID];
	auto it = def.find(head);
	if (it == def.cend()) {
		def[head] = new TempRule(id, onlyif, head, conj, ps);
		return;
	}

	auto prevrule = it->second;
	if(prevrule->onlyif != prevrule->onlyif){
		throw idpexception("Rules on the same head in the same definition need to have the same semantics.");
	}
	if (prevrule->conjunctive) { // introduce new var (we need disjunctive root anyway)
		auto newvar = solver->newAtom();
		def[newvar] = new TempRule(id, onlyif, newvar, prevrule->conjunctive, prevrule->body);
		prevrule->conjunctive = false;
		prevrule->body = {mkLit(newvar)};
	}
	if (conj) { // Create a new var and rule first
		auto newvar = solver->newAtom();
		def[newvar] = new TempRule(id, onlyif, newvar, conj, ps);
		prevrule->body.push_back(mkPosLit(newvar));
	} else { // Disjunctive, so can add directly
		prevrule->body.insert(prevrule->body.end(), ps.cbegin(), ps.cend());
	}
}
Пример #2
0
bool ModelExpand::invalidateValue(litlist& invalidation, OptimStatement& optim) {
	bool currentoptimumfound = false;

	const auto& minim = optim.to_minimize;
	for (uint i = 0; !currentoptimumfound && i < minim.size(); ++i) {
		if (!currentoptimumfound && getSolver().getModelValue(var(minim[i])) == l_True) {
			if (getOptions().verbosity >= 1) {
				clog << "> Current optimum found for: ";
				clog << getSpace()->toString(minim[i]);
				clog << "\n";
			}
			currentoptimumfound = true;
			_solutions->setLatestOptimum(minim[i]);
		}
		if (!currentoptimumfound) {
			invalidation.push_back(minim[i]);
		}
	}

	if (invalidation.size() == 0) {
		return true; //optimum has already been found!!!
	} else {
		return false;
	}
}
std::string ExternalConstraintVisitor::toString(const litlist& literals) const {
	std::stringstream ss;
	bool begin = true;
	for (auto i = literals.cbegin(); i < literals.cend(); ++i) {
		if (not begin) {
			ss << " | ";
		}
		begin = false;
		ss << toString(*i);
	}
	return ss.str();
}
Пример #4
0
// OPTIMIZATION METHODS
bool ModelExpand::invalidateSubset(litlist& invalidation, litlist& assmpt, OptimStatement& optim) {
	int subsetsize = 0;
	const auto& minim = optim.to_minimize;
	for (auto i = minim.cbegin(); i < minim.cend(); ++i) {
		auto lit = *i;
		if (getSolver().getModelValue(var(lit)) == l_True) {
			invalidation.push_back(~lit);
			++subsetsize;
		} else {
			assmpt.push_back(~lit);
		}
	}

	_solutions->setLatestOptimum(subsetsize);

	if (subsetsize == 0) {
		return true; //optimum has already been found!!!
	} else {
		return false;
	}
}
Пример #5
0
bool ModelExpand::invalidateVar(litlist& invalidation, OptimStatement& optim) {
	auto var = optim.var;
	auto bestvalue = var->maxValue();
	_solutions->setLatestOptimum(bestvalue);
	printer->notifyCurrentOptimum(bestvalue);
	if (getOptions().verbosity >= 1) {
		clog << "> Current optimal value " << bestvalue << "\n";
	}

	if(optim.minimize){
		if (var->origMinValue() == bestvalue) {
			return true;
		}
		invalidation.push_back(var->getLEQLit(bestvalue - 1));
	}else{
		if (var->origMaxValue() == bestvalue) {
			return true;
		}
		invalidation.push_back(var->getGEQLit(bestvalue + 1));
	}
	return false;
}
Пример #6
0
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");
		}
	}
}
Пример #7
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());
	}
}
Пример #8
0
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));
}