Exemple #1
0
/////////////////////////////////////////////////////////////////////////////////////////
// Lookback selection strategies
/////////////////////////////////////////////////////////////////////////////////////////
uint32 momsScore(const Solver& s, Var v) {
	uint32 sc;
	if (s.numBinaryConstraints()) {
		uint32 s1 = s.estimateBCP(posLit(v), 0) - 1;
		uint32 s2 = s.estimateBCP(negLit(v), 0) - 1;
		sc = ((s1 * s2)<<10) + (s1 + s2);
	}
	else {
		// problem does not contain binary constraints - fall back to counting watches
		uint32 s1 = s.numWatches(posLit(v));
		uint32 s2 = s.numWatches(negLit(v));
		sc = ((s1 * s2)<<10) + (s1 + s2);
	}
	return sc;
}
void ModelEnumerator::RecordFinder::doCommitModel(Enumerator& x, Solver& s) {
	ModelEnumerator& ctx = static_cast<ModelEnumerator&>(x);
	if (ctx.trivial()) { return; }
	assert(solution.empty() && "Update not called!");
	solution.clear();
	if (!ctx.projectionEnabled()) {
		for (uint32 x = s.decisionLevel(); x != 0; --x) {
			Literal d = s.decision(x);
			if      (!s.auxVar(d.var()))  { solution.push_back(~d); }
			else if (d != s.tagLiteral()) {
				// Todo: set of vars could be reduced to those having the aux var in their reason set.
				const LitVec& tr = s.trail();
				const uint32  end= x != s.decisionLevel() ? s.levelStart(x+1) : (uint32)tr.size();
				for (uint32 n = s.levelStart(x)+1; n != end; ++n) {
					if (!s.auxVar(tr[n].var())) { solution.push_back(~tr[n]); }
				}
			}
		}
	}
	else {
		for (uint32 i = 0, end = ctx.numProjectionVars(); i != end; ++i) {
			solution.push_back(~s.trueLit(ctx.projectVar(i)));
		}
	}
	if (queue) {
		assert(!queue->hasItems(id));
		// parallel solving active - share solution nogood with other solvers
		SL* shared = SL::newShareable(solution, Constraint_t::learnt_other);
		queue->addSolution(shared, id);
		solution.clear();
	}
	else if (solution.empty()) { 
		solution.push_back(negLit(0)); 
	}
}
void ModelEnumerator::addProjectVar(SharedContext& ctx, Var v, bool tag) {
	if (ctx.master()->value(v) == value_free && (!tag || !ctx.marked(posLit(v)))) {
		project_->push_back(v);
		ctx.setFrozen(v, true);
		ctx.setProject(v, true);
		if (tag) { ctx.mark(posLit(v)); ctx.mark(negLit(v)); }
	}
}
Exemple #4
0
void ClingoPropagator::destroy(Solver* s, bool detach) {
	if (s && detach) {
		for (Var v = 1; v <= s->numVars(); ++v) {
			s->removeWatch(posLit(v), this);
			s->removeWatch(negLit(v), this);
		}
	}
	destroyDB(db_, s, detach);
	PostPropagator::destroy(s, detach);
}
Exemple #5
0
Literal RestrictedUnit::doSelect(Solver& s) {
	s.addPost(look_);
	Literal choice = look_->propagateFixpoint(s) ? look_->heuristic(s) : negLit(0);
	s.removePost(look_);
	// if all fld-candidates are currently assigned, use
	// decorated heuristic to select next choice -
	// if all vars are assigned after fld, we return posLit(0)
	// as the "noop" choice.
	if (choice == posLit(0) && s.numFreeVars() > 0) {
		choice = default_->doSelect(s);
	}
	if (!isSentinel(choice) && --numChoices_ == 0) {
		destroy(s);
	}
	return choice;
}
void ModelEnumerator::BacktrackFinder::doCommitModel(Enumerator& ctx, Solver& s) {
	ModelEnumerator& en = static_cast<ModelEnumerator&>(ctx);
	uint32           dl = s.decisionLevel();
	solution.assign(1, dl ? ~s.decision(dl) : negLit(0));
	if (en.projectionEnabled()) {
		// Remember the current projected assignment as a nogood.
		solution.clear();
		for (uint32 i = 0, end = en.numProjectionVars(); i != end; ++i) {
			solution.push_back(~s.trueLit(en.projectVar(i)));
		}
		// Remember initial decisions that are projection vars.
		for (dl = s.backtrackLevel(); dl < s.decisionLevel(); ++dl) {
			if (!s.varInfo(s.decision(dl+1).var()).project()) { break; }
		}
	}
	s.setBacktrackLevel(dl);
}
Exemple #7
0
bool CBConsequences::backtrack(Solver& s) {
	if (C_.empty()) {
		// no more consequences possible
		C_.push_back(negLit(0));
	}
	// C_ stores the violated nogood, ie. the new integrity constraint.
	// C_[0] is the literal assigned on the highest DL and hence the
	// decision level on which we must analyze the conflict.
	uint32 newDl = s.level(C_[0].var());
	if (getHighestActiveLevel() < newDl) {
		// C_ is not the most important nogood, ie. there is some other
		// nogood that is violated below C_. 
		newDl = getHighestActiveLevel() - 1;
	}
	s.undoUntil(newDl, true);
	addNewConstraint(s);
	return !s.hasConflict() || s.resolveConflict();
}
Exemple #8
0
Literal UnitHeuristic::doSelect(Solver& s) {
	Literal x = look_->heuristic(s);
	if (x != posLit(0) || s.numFreeVars() == 0) { return x; }
	// No candidates. This can happen if the problem
	// contains choice rules and lookahead is not atom-based.
	// Add remaining free vars to lookahead so that we can
	// make an informed decision.
	VarType types = look_->score.types;
	for (Var v = 1, end = s.numVars()+1; v != end; ++v) {
		if ((s.value(v) == value_free || s.level(v) > 0) && (s.sharedContext()->type(v) & types) == 0) {
			look_->append(s.sharedContext()->preferredLiteralByType(v), true);
		}
	}
	look_->score.clearDeps();
	look_->score.types = Var_t::atom_body_var;
	return look_->propagateFixpoint(s)
		? look_->heuristic(s)
		: negLit(0);
}
Exemple #9
0
Literal ClaspBerkmin::selectLiteral(Solver& s, Var var, bool vsids) {
	Literal l;
	if ( (l = savedLiteral(s,var)) == posLit(0) ) {
		int32 w0 = vsids ? (int32)s.estimateBCP(posLit(var), 5) : order_.occ(var);
		int32 w1 = vsids ? (int32)s.estimateBCP(negLit(var), 5) : 0;
		if (w1 == 1 && w0 == w1) {
			// no binary bcp - use occurrences
			w0 = order_.occ(var);
			w1 = 0;
		}
		return w0 != w1 
			? Literal(var, (w0-w1)<0)
			: s.preferredLiteralByType(var);
	}
	else if (order_.huang && (order_.occ(var)*(-1+(2*l.sign()))) > 32) {
		l = ~l;
	}
	return l;
}
Exemple #10
0
Literal Lookahead::heuristic(Solver& s) {
	if (s.value(score.best) != value_free) {
		// no candidate available
		return posLit(0);
	}
	ScoreLook& sc = score;
	Literal choice= Literal(sc.best, sc.score[sc.best].prefSign());
	if (!sc.deps.empty() && sc.mode == ScoreLook::score_max_min) {
		// compute heuristic values for candidates skipped during last lookahead
		uint32 min, max;
		sc.score[sc.best].score(max, min);
		sc.addDeps = false;
		bool ok    = true;
		LitVec::size_type i = 0;
		do {
			Var v        = sc.deps[i];
			VarScore& vs = sc.score[v];
			if (s.value(v) == value_free) {
				uint32 vMin, vMax;
				vs.score(vMax, vMin);
				if (vMin == 0 || vMin > min || (vMin == min && vMax > max)) {
					uint32 neg = vs.score(negLit(v)) > 0 ? vs.score(negLit(v)) : max+1;
					uint32 pos = vs.score(posLit(v)) > 0 ? vs.score(posLit(v)) : max+1;
					if (!vs.tested(negLit(v))) {
						ok  = ok && s.test(negLit(v), this);
						neg = vs.score(negLit(v));
					}
					if ((neg > min || (neg == min && pos > max)) && !vs.tested(posLit(v))) {
						ok  = ok && s.test(posLit(v), this);
					}
				}
				if (vs.testedBoth() && sc.greaterMaxMin(v, max, min)) {
					vs.score(max, min);
					choice = Literal(v, vs.prefSign());
				}
			}
		} while (++i != sc.deps.size() && ok);
		if (!ok) {
			// One of the candidates failed. Since none of them failed
			// during previous propagation, this indicates that
			// either some post propagator has wrong priority or
			// parallel solving is active and a stop conflict was set.
			// Since we can't resolve the problem here, we simply return the
			// literal that caused the conflict
			assert(s.hasConflict());
			return negLit(0);
		}
	}
	return choice;
}