Beispiel #1
0
void MinisatID::verifySet(const WLSet& set, AggType type) {
	for (auto i = set.getWL().cbegin(); i < set.getWL().cend(); ++i) {
		if (type == AggType::CARD && (*i).getWeight() != 1) {
			throw idpexception("Cardinality set does not have weights equal to 1.\n");
		}
		if (type == AggType::PROD && (*i).getWeight() < 1) { //Exception if product contains negative/zero weights
			stringstream ss;
			ss << "Error: Set nr. " << set.setID << " contains a 0 (zero) or negative weight " << (*i).getWeight()
					<< ", which cannot occur in a product set.\n";
			throw idpexception(ss.str());
		}
#ifdef NOARBITPREC
		if ((*i).getWeight() == posInfinity() || (*i).getWeight() == negInfinity()) {
			throw idpexception("Weights equal to or larger than the largest integer number "
					"are not allowed in limited precision.\n");
		}
#endif
	}
}
double MinisatID::testGenWatchCount(const PCSolver& solver, const WLSet& set, const AggProp& type, const std::vector<TempAgg*> aggs) {
	uint totallits = set.getWL().size(), totalwatches = 0;
	std::vector<TempWatch*> nws;

	//Calculate min and max values over empty interpretation
	//Create sets and watches, initialize min/max values
	minmaxBounds emptyinterpretbounds = minmaxBounds(type.getMinPossible(set.getWL()), type.getMaxPossible(set.getWL()));
	const vwl& wls = set.getWL();
	for (uint i = 0; i < wls.size(); ++i) {
		const WL& wl = wls[i];
		bool mono = type.isMonotone(**aggs.cbegin(), wl.getWeight());
		nws.push_back(new TempWatch(wl, mono));
	}

	//Calculate reference aggregate (the one which will lead to the most watches
	auto worstagg = *aggs.cbegin();
	for (auto i = aggs.cbegin(); i < aggs.cend(); ++i) {
		if ((*i)->hasLB() && worstagg->getBound() < (*i)->getBound()) {
			worstagg = *i;
		} else if ((*i)->hasUB() && worstagg->getBound() > (*i)->getBound()) {
			worstagg = *i;
		}
	}

	bool oneagg = aggs.size() == 1;
	const auto& agg = *worstagg;

	if (oneagg && solver.value(agg.getHead()) == l_True) {
		deleteList<TempWatch>(nws);
		return 0;
	}

	minmaxOptimAndPessBounds bounds(emptyinterpretbounds);
	TempWatch* largest = NULL;
	uint i = 0;
	for (; not isSatisfied(agg, bounds.optim) && not isSatisfied(agg, bounds.pess) && i < nws.size(); ++i) {
		WL wl = nws[i]->getWL();
		lbool val = solver.value(wl.getLit());

		bool inset = val == l_True || (val == l_Undef && nws[i]->isMonotone());
		addValue(type, wl.getWeight(), inset, bounds.optim);
		if (val != l_Undef) {
			addValue(type, wl.getWeight(), val == l_True, bounds.pess);
		}

		if (val != l_False) { //Add to watches
			if (largest == NULL || largest->getWL().getWeight() < wl.getWeight()) {
				largest = nws[i];
			}
			totalwatches++;
		}
	}

	//if head was unknown before method start, at most head can have been propagated
	//so do not have to find second supporting ws
	if ((!oneagg || solver.value(agg.getHead()) != l_Undef) && (largest != NULL && not isSatisfied(agg, bounds.pess))) {
		removeValue(type, largest->getWL().getWeight(), largest->isMonotone(), bounds.optim);

		//Again until satisfied IMPORTANT: continue from previous index!
		for (; not isSatisfied(agg, bounds.optim) && not isSatisfied(agg, bounds.pess) && i < nws.size(); ++i) {
			WL wl = nws[i]->getWL();
			lbool val = solver.value(wl.getLit());

			bool inset = val == l_True || (val == l_Undef && nws[i]->isMonotone());
			addValue(type, wl.getWeight(), inset, bounds.optim);
			if (val != l_Undef) {
				addValue(type, wl.getWeight(), val == l_True, bounds.pess);
			}

			if (val != l_False) { //Add to watches
				if (largest->getWL().getWeight() < wl.getWeight()) {
					largest = nws[i];
				}
				totalwatches++;
			}
		}
	}

	deleteList<TempWatch>(nws);
	return ((double) totalwatches) / totallits;
}