//! Returns the truth value that is currently assigned to lit or Value_t::Free if lit is unassigned. virtual Value_t value(Lit_t lit) const { CLASP_FAIL_IF(!this->TheoryPropagator::PP::hasLit(lit), "invalid variable"); switch (solver_->value(decodeVar(lit))) { default: return Value_t::Free; case value_true: return lit >= 0 ? Value_t::True : Value_t::False; case value_false: return lit >= 0 ? Value_t::False : Value_t::True; } }
///////////////////////////////////////////////////////////////////////////////////////// // Heuristics ///////////////////////////////////////////////////////////////////////////////////////// DecisionHeuristic* Heuristic_t::create(Type id, const HeuParams& p) { if (id == Berkmin) { return new ClaspBerkmin(p); } if (id == Vmtf) { return new ClaspVmtf(p); } if (id == Unit) { return new UnitHeuristic(); } if (id == Vsids) { return new ClaspVsids(p); } if (id == Domain) { return new DomainHeuristic(p); } CLASP_FAIL_IF(id != Default && id != None, "Unknown heuristic id!"); return new SelectFirst(); }
void TheoryPropagator::PP::undoLevel(Solver& s) { typedef Potassco::AbstractPropagator::ChangeList ChangeList; CLASP_FAIL_IF(s.decisionLevel() != undo_.back().level, "invalid undo!"); delta_ = undo_.back().delta; undo_.pop_back(); ChangeList change = Potassco::toSpan(&trail_[0] + delta_, trail_.size() - delta_); wrapper_->prop_->undo(*this, change); trail_.resize(delta_); }
DecisionHeuristic* BasicSatConfig::heuristic(uint32 i) const { const SolverParams& p = BasicSatConfig::solver(i); Heuristic_t::Type hId = static_cast<Heuristic_t::Type>(p.heuId); if (hId == Heuristic_t::Default && p.search == SolverStrategies::use_learning) hId = Heuristic_t::Berkmin; CLASP_FAIL_IF(p.search != SolverStrategies::use_learning && Heuristic_t::isLookback(hId), "Selected heuristic requires lookback!"); DecisionHeuristic* h = 0; if (heu_) { h = heu_(hId, p.heuristic); } if (!h) { h = Heuristic_t::create(hId, p.heuristic); } if (Lookahead::isType(p.lookType) && p.lookOps > 0 && hId != Heuristic_t::Unit) { h = UnitHeuristic::restricted(h); } return h; }
bool TheoryPropagator::PP::init(Solver& s) { const LitVec& watches = wrapper_->watches_->vec; CLASP_FAIL_IF(init_ > watches.size(), "invalid watch list!"); for (size_t max = watches.size(); init_ != max; ++init_) { Literal p = watches[init_]; if (s.value(p.var()) == value_free || s.level(p.var()) > s.rootLevel()) { s.addWatch(p, this, init_); } else if (s.isTrue(p)) { pushTrail(p); } } return true; }
bool TheoryPropagator::PP::addClause(const Potassco::LitSpan& clause) { CLASP_FAIL_IF(solver_->hasConflict(), "invalid addClause()!"); clause_.clear(); for (const Potassco::Lit_t* it = Potassco::begin(clause); it != Potassco::end(clause); ++it) { clause_.push_back(decodeLit(*it)); } ClauseRep rep = ClauseCreator::prepare(*solver_, clause_, Clasp::ClauseCreator::clause_force_simplify, Constraint_t::Other); if (clause_.size() < 2) { clause_.resize(2, lit_false()); } status_ = ClauseCreator::status(*solver_, rep); uint32 impLevel = (status_ & ClauseCreator::status_asserting) != 0 ? solver_->level(clause_[1].var()) : UINT32_MAX; if (!inProp_ || impLevel >= solver_->decisionLevel()) { status_ = ClauseCreator::status_open; return ClauseCreator::create(*solver_, rep, ccFlags_s); } return false; }
bool ModelEnumerator::BacktrackFinder::doUpdate(Solver& s) { if (hasModel()) { bool ok = true; uint32 sp = s.strategy.saveProgress; if ((opts & ModelEnumerator::project_save_progress) != 0 ) { s.strategy.saveProgress = 1; } s.undoUntil(s.backtrackLevel()); s.strategy.saveProgress = sp; ClauseRep rep = ClauseCreator::prepare(s, solution, 0, Constraint_t::learnt_conflict); if (rep.size == 0 || s.isFalse(rep.lits[0])) { // The decision stack is already ordered. ok = s.backtrack(); } else if (rep.size == 1 || s.isFalse(rep.lits[1])) { // The projection nogood is unit. Force the single remaining literal from the current DL. ok = s.force(rep.lits[0], this); } else if (!s.isTrue(rep.lits[0])) { // Shorten the projection nogood by assuming one of its literals to false. uint32 f = static_cast<uint32>(std::stable_partition(rep.lits+2, rep.lits+rep.size, std::not1(std::bind1st(std::mem_fun(&Solver::isFalse), &s))) - rep.lits); Literal x = (opts & ModelEnumerator::project_use_heuristic) != 0 ? s.heuristic()->selectRange(s, rep.lits, rep.lits+f) : rep.lits[0]; LearntConstraint* c = Clause::newContractedClause(s, rep, f, true); CLASP_FAIL_IF(!c, "Invalid constraint!"); s.assume(~x); // Remember that we must backtrack the current decision // level in order to guarantee a different projected solution. s.setBacktrackLevel(s.decisionLevel()); // Attach nogood to the current decision literal. // Once we backtrack to x, the then obsolete nogood is destroyed // keeping the number of projection nogoods linear in the number of (projection) atoms. s.addWatch(x, this, (uint32)nogoods.size()); nogoods.push_back(c); ok = true; } solution.clear(); return ok; } if (optimize() || s.sharedContext()->concurrency() == 1 || disjointPath()) { return true; } s.setStopConflict(); return false; }
bool TheoryPropagator::PP::propagateFixpoint(Clasp::Solver& s, Clasp::PostPropagator*) { typedef Potassco::AbstractPropagator::ChangeList ChangeList; while (delta_ != trail_.size()) { uint32 dl = s.decisionLevel(); if (undo_.back().level != dl) { s.addUndoWatch(dl, this); undo_.push_back(Undo(dl, delta_)); } ChangeList change = Potassco::toSpan(&trail_[0] + delta_, trail_.size() - delta_); delta_ = trail_.size(); status_ = ClauseCreator::status_open; solver_ = &s; inProp_ = true; bool ok = wrapper_->prop_->propagate(*this, change); inProp_ = false; if (!ok && !s.hasConflict() && (status_ & ClauseCreator::status_asserting) != 0) { if (s.level(clause_[1].var()) < dl && dl != s.backtrackLevel()) { TheoryPropagator::PP::reset(); for (PostPropagator* n = this->next; n; n = n->next) { n->reset(); } dl = s.undoUntil(s.level(clause_[1].var())); } if (!s.isFalse(clause_[0])) { ok = ClauseCreator::create(*solver_, clause_, ccFlags_s | ClauseCreator::clause_no_prepare, Constraint_t::Other); } else { return s.force(clause_[0], this); } } if (s.hasConflict() || !ok || (s.queueSize() && !s.propagateUntil(this))) { if (!s.hasConflict()) { s.setStopConflict(); } return false; } CLASP_FAIL_IF(dl < s.decisionLevel(), "invalid operation in propagation"); } return true; }