Beispiel #1
0
	//! 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;
		}
	}
Beispiel #2
0
/////////////////////////////////////////////////////////////////////////////////////////
// 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();
}
Beispiel #3
0
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_);
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}