Disjunction implies(const TempAgg& from, const TempAgg& to) { // FIXME combine both id for unsat core return Disjunction(DEFAULTCONSTRID, { not from.getHead(), to.getHead() }); }
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; }