예제 #1
0
void MinisatID::addHeadImplications(PCSolver* solver, WLSet*, std::vector<TempAgg*>& aggs, bool&, bool&) {
	if (aggs.size() > 1 && aggs[0]->getSem() != AggSem::OR) {
		tempagglist lbaggs, ubaggs;
		for (auto i = aggs.cbegin(); i < aggs.cend(); ++i) {
			if ((*i)->hasLB()) {
				lbaggs.push_back(*i);
			} else {
				ubaggs.push_back(*i);
			}
		}
		if (lbaggs.size() > 1) {
			sort(lbaggs.begin(), lbaggs.end(), compareAggBounds);
			TempAgg* first = *lbaggs.cbegin();
			for (auto i = lbaggs.cbegin() + 1; i < lbaggs.cend(); ++i) {
				TempAgg* second = *i;
				internalAdd(implies(*second, *first), solver->getTheoryID(), *solver);
				if (first->getBound() == second->getBound()) {
					internalAdd(implies(*first, *second), solver->getTheoryID(), *solver);
				}
				first = second;
			}
		}
		if (ubaggs.size() > 1) {
			sort(ubaggs.begin(), ubaggs.end(), compareAggBounds);
			reverse(ubaggs.begin(), ubaggs.end());
			TempAgg* first = *ubaggs.cbegin();
			for (auto i = ubaggs.cbegin() + 1; i < ubaggs.cend(); ++i) {
				TempAgg* second = *i;
				internalAdd(implies(*second, *first), solver->getTheoryID(), *solver);
				if (first->getBound() == second->getBound()) {
					internalAdd(implies(*first, *second), solver->getTheoryID(), *solver);
				}
				first = second;
			}
		}
	}
}
예제 #2
0
void AggToCNFTransformer::add(WLSet* set, std::vector<TempAgg*>& aggs) {
	tempagglist remaining;
	for (auto i = aggs.cbegin(); i != aggs.cend(); ++i) {
		TempAgg* agg = *i;

		if ((agg->getType() != AggType::SUM && agg->getType() != AggType::CARD) || agg->getSem() != AggSem::COMP) {
			// TODO allow complete translation into sat? => double bounds
			remaining.push_back(agg);
			continue;
		}

		auto pbaggeq = new PBAgg();
		auto pbaggineq = new PBAgg();
		auto bound = agg->getBound();
		pbaggeq->bound = bound;
		pbaggineq->bound = bound;
		if (agg->hasUB()) {
			pbaggeq->sign = -1;
			pbaggineq->sign = 1;
			pbaggineq->bound+=Weight(1); // Strictly larger than
		} else {
			pbaggineq->sign = -1;
			pbaggineq->bound-=Weight(1); // Strictly lower than
			pbaggeq->sign = 1;
		}
		Weight min = 0, max = 0;
		for (auto wlt : set->getWL()) {
			pbaggeq->literals.push(mapToPBLit(wlt.getLit()));
			pbaggineq->literals.push(mapToPBLit(wlt.getLit()));
			if (var(wlt.getLit()) > maxvar) {
				maxvar = var(wlt.getLit());
			}
			if (wlt.getWeight() < 0) {
				min += wlt.getWeight();
			} else {
				max += wlt.getWeight();
			}
			pbaggeq->weights.push(MiniSatPP::Int(toInt(wlt.getWeight())));  // FIXME use the bignums without downcast? (5 places in file)
			pbaggineq->weights.push(MiniSatPP::Int(toInt(wlt.getWeight())));
		}
		auto headval = pcsolver.rootValue(agg->getHead());
		if (headval == l_Undef) {
			pbaggeq->literals.push(mapToPBLit(~agg->getHead()));
			pbaggineq->literals.push(mapToPBLit(agg->getHead()));
			if (var(agg->getHead()) > maxvar) {
				maxvar = var(agg->getHead());
			}
			Weight eqval, ineqval;
			if (agg->hasUB()) {
				ineqval = abs(pbaggineq->bound) + abs(min) + 1;
				eqval = -abs(pbaggeq->bound) - abs(max) - 1;
			} else {
				eqval = abs(pbaggeq->bound) + abs(min) + 1;
				ineqval = -abs(pbaggineq->bound) - abs(max) - 1;
			}
			pbaggeq->weights.push(MiniSatPP::Int(toInt(eqval)));
			pbaggineq->weights.push(MiniSatPP::Int(toInt(ineqval)));
		}
		if (headval != l_False) {
			pbaggs.push_back(pbaggeq);
		}
		if (headval != l_True) {
			pbaggs.push_back(pbaggineq);
		}

		/**
		 * Doel voor H <=> set >= n
		 * H => set >= n
		 * ~H => set < n
		 *
		 * richting 1: H true moet zich gedragen als  set >= n
		 * 				H false moet triviaal true zijn
		 * 					dus set + (n+abs minwaarde)*~H >= n
		 * 	richting 2: H false moet zich gedragen als set < n
		 * 				H true moet triviaal true zijn
		 * 					dus set + (-n-abs max)*H < n of dus =< n-1
		 */

	}
	aggs = remaining;
}