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; } } } }
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; }