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