if (LOGGER.isDebugEnabled()) {
LOGGER.debug("explain Cut");
}
// 1. make a backup
mSolver.getEnvironment().worldPush();
Decision d;
try {
Decision previous = mSolver.getSearchLoop().getLastDecision();
assert previous == RootDecision.ROOT;
// 2. apply the decisions
mExplanationEngine.getSolver().getObjectiveManager().postDynamicCut();
for (int i = 0; i < path.size(); i++) {
d = path.get(i);
d.setPrevious(previous);
d.buildNext();
if (refuted.get(i)) d.buildNext();
d.apply();
mSolver.propagate();
previous = d;
}
//mSolver.propagate();
assert false : "SHOULD FAIL!";
} catch (ContradictionException cex) {
if ((cex.v != null) || (cex.c != null)) { // contradiction on domain wipe out
tmpDeductions.clear();
tmpValueDeductions.clear();
related2cut.clear();
unrelated.clear();
// 3. explain the failure
Explanation expl = new Explanation();
if (cex.v != null) {
cex.v.explain(VariableState.DOM, expl);
} else {
cex.c.explain(null, expl);
}
Explanation complete = mExplanationEngine.flatten(expl);
ExplanationToolbox.extractDecision(complete, tmpValueDeductions);
tmpDeductions.addAll(tmpValueDeductions);
if (tmpDeductions.isEmpty()) {
// if (LOGGER.isErrorEnabled()) {
// LOGGER.error("2 cases: (a) optimality proven or (b) bug in explanation");
// }
// throw new SolverException("2 cases: (a) optimality proven or (b) bug in explanation");
isTerminated = true;
}
for (int i = 0; i < tmpDeductions.size(); i++) {
int idx = path.indexOf(((BranchingDecision) tmpDeductions.get(i)).getDecision());
related2cut.set(idx);
}
// 4. need to replace the duplicated decision with the correct one
for (int i = 0; i < path.size(); i++) {
Decision dec = path.get(i);
boolean forceNext = !dec.hasNext();
dec.rewind();
if (forceNext) dec.buildNext();
dec.setPrevious(null); // useless .. but ... you know
}
} else {
throw new UnsupportedOperationException(this.getClass().getName() + ".onContradiction incoherent state");
}