bool SatBuilder::doEndProgram() { bool ok = ctx()->ok(); if (!softClauses_.empty() && ok) { ctx()->setPreserveModels(true); ctx()->resizeVars(vars_+1); ctx()->startAddConstraints(); LitVec cc; for (LitVec::const_iterator it = softClauses_.begin(), end = softClauses_.end(); it != end && ok; ++it) { weight_t w = (weight_t)it->asUint(); Literal relax = *++it; if (!relax.watched()) { cc.assign(1, relax); do { cc.push_back(*++it); } while (!cc.back().watched()); cc.back().clearWatch(); ok = ClauseCreator::create(*ctx()->master(), cc, Constraint_t::static_constraint).ok(); } relax.clearWatch(); addMinLit(WeightLiteral(relax, w)); } LitVec().swap(softClauses_); } if (ok && !ctx()->preserveModels()) { uint32 p = 12; for (Var v = 1; v != (Var)varState_.size() && ok; ++v) { uint32 m = varState_[v]; if ( (m & p) != p ) { ok = ctx()->addUnary(Literal(v, ((m>>2) & 1u) != 1)); } }
bool solve(Solver& s, const LitVec& assumptions, const SolveParams& params) { s.stats.solve.reset(); // Remove any existing assumptions and simplify problem. // If this fails, the problem is unsat, even under no assumptions. if (!s.clearAssumptions()) return false; // Next, add assumptions. // If this fails, the problem is unsat under the current assumptions // but not necessarily unsat. LitVec::size_type i; for (i = 0; i != assumptions.size(); ++i) { Literal p = assumptions[i]; if (s.value(p.var()) == value_free) { s.assume(p); --s.stats.solve.choices; // increase root level - assumption can't be undone during search s.setRootLevel(s.decisionLevel()); if (!s.propagate()) { break; } } else if (s.isFalse(p)) { s.analyzeRootConflict(~p); break; } } bool ret = i == assumptions.size() && solve(s, params); // Find the subset of assumptions that led to the final conflict if (s.hasConflict()) { s.analyzeRootConflict(); } // Finally, remove the assumptions again and restore // the solver to a usable state if possible. s.clearAssumptions(); return ret; }
bool ClingoPropagator::simplify(Solver& s, bool) { if (!s.validVar(aux_.var())) { ClauseDB::size_type i, j, end = db_.size(); LitVec cc; Var last = s.numVars(); aux_ = lit_true(); for (i = j = 0; i != end; ++i) { db_[j++] = db_[i]; ClauseHead* c = db_[i]->clause(); if (c && c->aux()) { cc.clear(); c->toLits(cc); Literal x = *std::max_element(cc.begin(), cc.end()); if (x.var() > last) { c->destroy(&s, true); --j; } else if (aux_ < x) { aux_ = x; } } } db_.erase(db_.begin()+j, db_.end()); } simplifyDB(s, db_, false); return false; }
void ProgramBuilder::getAssumptions(LitVec& out) const { CLASP_ASSERT_CONTRACT(ctx_ && frozen()); if (!isSentinel(ctx_->stepLiteral())) { out.push_back(ctx_->stepLiteral()); } doGetAssumptions(out); }
bool SatBuilder::addClause(LitVec& clause, wsum_t cw) { if (!ctx()->ok() || satisfied(clause)) { return ctx()->ok(); } CLASP_ASSERT_CONTRACT_MSG(cw >= 0 && (cw <= std::numeric_limits<weight_t>::max() || cw == hardWeight_), "Clause weight out of bounds!"); if (cw == 0 && maxSat_) { cw = 1; } if (cw == hardWeight_ || clause.empty()) { return ClauseCreator::create(*ctx()->master(), clause, Constraint_t::static_constraint).ok() && markAssigned(); } else { // Store weight, relaxtion var, and (optionally) clause softClauses_.push_back(Literal::fromRep((uint32)cw)); if (clause.size() != 1) { softClauses_.push_back(posLit(++vars_)); softClauses_.insert(softClauses_.end(), clause.begin(), clause.end()); } else { softClauses_.push_back(~clause.back()); } softClauses_.back().watch(); // mark end of clause } return true; }
void DimacsParser::parseClauses() { LitVec cc; const bool wcnf = wcnf_; wsum_t cw = 0; const int numV = numVar_; while (input()->skipWhite() && skipComments("c") && **input()) { cc.clear(); if (wcnf) { check(input()->parseInt64(cw) && cw > 0, "wcnf: clause weight expected!"); } for (int lit; (lit = input()->parseInt(-numV, numV, "Invalid variable in clause!")) != 0;) { cc.push_back(Literal(static_cast<uint32>(lit > 0 ? lit : -lit), lit < 0)); input()->skipWhite(); } builder_->addClause(cc, cw); } input()->skipWhite(); }
void ClingoPropagator::reason(Solver&, Literal p, LitVec& r) { if (!todo_.empty() && todo_.mem[0] == p) { for (LitVec::const_iterator it = todo_.mem.begin() + 1, end = todo_.mem.end(); it != end; ++it) { r.push_back(~*it); } } }
void DefaultUnfoundedCheck::reason(Solver&, Literal p, LitVec& r) { LitVec::const_iterator it, end; if (!activeClause_.empty() && activeClause_[0] == p) { it = activeClause_.begin()+1; end = activeClause_.end(); } else { assert(strategy_ == only_reason && reasons_); it = reasons_[p.var()-1].begin(); end = reasons_[p.var()-1].end(); } for (; it != end; ++it) r.push_back( ~*it ); }
bool SatBuilder::satisfied(LitVec& cc) { bool sat = false; LitVec::iterator j = cc.begin(); for (LitVec::const_iterator it = cc.begin(), end = cc.end(); it != end; ++it) { Literal x = *it; uint32 m = 1+x.sign(); uint32 n = uint32(varState_[it->var()] & 3u) + m; if (n == m) { varState_[it->var()] |= m; x.clearWatch(); *j++ = x; } else if (n == 3u){ sat = true; break; } } cc.erase(j, cc.end()); for (LitVec::const_iterator it = cc.begin(), end = cc.end(); it != end; ++it) { if (!sat) { varState_[it->var()] |= (varState_[it->var()] & 3u) << 2; } varState_[it->var()] &= ~3u; } return sat; }
bool SolveAlgorithm::initPath(Solver& s, const LitVec& path, InitParams& params) { assert(!s.hasConflict() && s.decisionLevel() == 0); SingleOwnerPtr<Lookahead> look(0); if (params.lookType != Lookahead::no_lookahead && params.lookOps != 0) { look = new Lookahead(static_cast<Lookahead::Type>(params.lookType)); look->init(s); s.addPost(look.release()); --params.lookOps; } bool ok = s.propagate() && s.simplify(); if (look.get()) { s.removePost(look.get()); look = look.get(); // restore ownership } if (!ok) { return false; } // setup path for (LitVec::size_type i = 0, end = path.size(); i != end; ++i) { Literal p = path[i]; if (s.value(p.var()) == value_free) { s.assume(p); --s.stats.choices; // increase root level - assumption can't be undone during search s.pushRootLevel(); if (!s.propagate()) return false; } else if (s.isFalse(p)) return false; } // do random probings if any if (uint32 i = params.randRuns) { params.randRuns = 0; do { if (s.search(params.randConf, UINT32_MAX, false, 1.0) != value_free) { return !s.hasConflict(); } s.undoUntil(0); } while (--i); } // do initial lookahead choices if requested if (uint32 i = params.lookOps) { params.lookOps = 0; assert(look.get()); RestrictedUnit::decorate(s, i, look.release()); } return true; }
void reason(Solver& s, Literal p, LitVec& x){ for (uint32 i = 1, end = s.level(p.var()); i <= end; ++i) { x.push_back(s.decision(i)); } }
LitVec LinearLiteralPropagator::LinearConstraintClause::getClause(IncrementalSolver& s, VolatileVariableStorage& vs, bool createOnConflict) const { LitVec ret; for (unsigned int i = 0; i < its_.size(); ++i) { if (vs.getVariableStorage().hasGELiteral(its_[i])) { ret.emplace_back(~vs.getVariableStorage().getGELiteral(its_[i])); } else { assert(conclusion_==i); /////// use pure LE lit iterator, but obey the direction of the view, if its reversed i have to go to the other direction etc... Literal l = (!conflict_ || createOnConflict) ? s.getNewLiteral() : s.trueLit(); newLit_ = l != s.trueLit(); if (its_[i].view().reversed()) { auto varit = ViewIterator::viewToVarIterator(its_[i]); if (conflict_) { if (createOnConflict) vs.setLELit(varit,l); // on view auto it = pure_LELiteral_iterator(varit,vs.getVariableStorage().getOrderStorage(varit.view().v),true); --it; if (it.isValid()) ret.emplace_back(~*it); else { assert(false); ret.emplace_back(s.trueLit()); /// huh ? } } else { vs.setLELit(varit,l); // on view ret.emplace_back(~l); } } else { auto varit = ViewIterator::viewToVarIterator(its_[i]-1); if (conflict_) { if (createOnConflict) vs.setLELit(varit,l); // on view auto it = pure_LELiteral_iterator(varit,vs.getVariableStorage().getOrderStorage(varit.view().v),true); ++it; assert(it.isValid()); assert(s.isFalse(*it)); ret.emplace_back(*it); } else { vs.setLELit(varit,l); // on view ret.emplace_back(l); } } /* auto it = ViewIterator::viewToVarIterator(its_[i]-1); pure_LELiteral_iterator pit(it,orderStorage,true); assert(pit.isValid()); assert(*pit == l); ///should be a direct hit, and return the same literal //VariableCreator::pure_literal_iterator pit = vc.setLELiteral(its_[i]-1,~l); //Literal l = vc.createLELitOnline(its_[i]-1,s); if (!reversed()) l = ~l; if (conflict_) { /// just look for the next literal which is already introduced, /// should simulate resolution on this literal if (reversed) { --pit; if (pit.isValid()) l = *pit; else true does not make much sense; } else { ++pit;/// next valid literal if (pit.isValid()) l = ~(*pit); else l = s_.falseLit(); } assert(s.isFalse(l)); } ret.emplace_back(l);*/ } } ret.emplace_back(~constraint_.v); return ret; }
void TheoryPropagator::PP::reason(Solver&, Literal p, LitVec& r) { for (LitVec::const_iterator it = clause_.begin() + (p == clause_[0]), end = clause_.end(); it != end; ++it) { r.push_back(~*it); } }
void ClaspBerkmin::updateReason(const Solver&, const LitVec& lits, Literal r) { for (LitVec::size_type i = 0, e = lits.size(); i != e; ++i) { order_.inc(~lits[i]); } if (!isSentinel(r)) { order_.inc(r); } }