예제 #1
0
  @Override
  public void fixSomeVariables(ICause cause) throws ContradictionException {
    // this is called after restart
    // if required, force the cut and explain the cut
    if (forceCft) {
      explainCut();
      nbFixedVariables = related2cut.cardinality();
      nbCall = 0;
      increaseLimit();
    }
    // then fix variables
    // this part is specific: a fake decision path has to be created
    nbCall++;
    restrictLess();
    notFrozen.clear();
    notFrozen.or(related2cut);
    for (; !notFrozen.isEmpty() && notFrozen.cardinality() > nbFixedVariables; ) {
      int idx = selectVariable();
      notFrozen.clear(idx);
    }
    assert mSolver.getSearchLoop().getLastDecision() == RootDecision.ROOT;
    // add the first refuted decisions
    int first = notFrozen.nextSetBit(0);
    for (int i = (first > -1 ? refuted.nextSetBit(first) : first);
        i > -1;
        i = refuted.nextSetBit(i + 1)) {
      notFrozen.clear(i);
    }

    // add unrelated
    notFrozen.or(unrelated);

    // then build the fake decision path
    last = null;
    //        LOGGER.debug("relax cut {}", notFrozen.cardinality());
    for (int id = notFrozen.nextSetBit(0);
        id >= 0 && id < path.size();
        id = notFrozen.nextSetBit(id + 1)) {
      //            last = ExplanationToolbox.mimic(path.get(id)); // required because some
      // unrelated decisions can be refuted
      if (path.get(id).hasNext()) {
        last = path.get(id).duplicate();
        if (refuted.get(id)) last.buildNext();
        ExplanationToolbox.imposeDecisionPath(mSolver, last);
      }
    }
  }
예제 #2
0
  /** Force the failure, apply decisions to the last solution + cut => failure! */
  private void explainCut() {
    // Goal: force the failure to get the set of decisions related to the cut
    forceCft = false;
    // 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(mExplanationEngine, VariableState.DOM, expl);
        } else {
          cex.c.explain(mExplanationEngine, 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");
      }
    }
    mSolver.getEnvironment().worldPop();
    mSolver.getEngine().flush();
    unrelated.andNot(related2cut);
    unrelated.andNot(refuted);
  }