import kodkod.instance.Bounds; //导入方法依赖的package包/类
/**
* Returns the trivial solution corresponding to the trivial translation
* stored in {@code this.translation}, and if
* {@code this.translation.cnf.solve()} is true, sets
* {@code this.translation} to a new translation that eliminates the current
* trivial solution from the set of possible solutions. The latter has the
* effect of forcing either the translator or the solver to come up with the
* next solution or return UNSAT. If {@code this.translation.cnf.solve()} is
* false, sets {@code this.translation} to null.
*
* @requires this.translation != null
* @ensures this.translation is modified to eliminate the current trivial
* solution from the set of possible solutions
* @return current solution
*/
private Solution nextTrivialSolution() {
final Translation.Whole transl = this.translation;
final Solution sol = Solver.trivial(transl, translTime); // this also
// frees up
// solver
// resources,
// if unsat
if (sol.instance() == null) {
translation = null; // unsat, no more solutions
} else {
trivial++;
final Bounds bounds = transl.bounds();
final Bounds newBounds = bounds.clone();
final List changes = new ArrayList();
for (Relation r : bounds.relations()) {
final TupleSet lower = bounds.lowerBound(r);
if (lower != bounds.upperBound(r)) { // r may change
if (lower.isEmpty()) {
changes.add(r.some());
} else {
final Relation rmodel = Relation.nary(r.name() + "_" + trivial, r.arity());
newBounds.boundExactly(rmodel, lower);
changes.add(r.eq(rmodel).not());
}
}
}
// nothing can change => there can be no more solutions (besides the
// current trivial one).
// note that transl.formula simplifies to the constant true with
// respect to
// transl.bounds, and that newBounds is a superset of transl.bounds.
// as a result, finding the next instance, if any, for
// transl.formula.and(Formula.or(changes))
// with respect to newBounds is equivalent to finding the next
// instance of Formula.or(changes) alone.
final Formula formula = changes.isEmpty() ? Formula.FALSE : Formula.or(changes);
final long startTransl = System.currentTimeMillis();
translation = Translator.translate(formula, newBounds, transl.options());
translTime += System.currentTimeMillis() - startTransl;
}
return sol;
}