@Override public void propagate(int evtmask) throws ContradictionException { ISet nei; IntVar v; for (int i = 0; i < n; i++) { nei = g.getEnvelopGraph().getSuccessorsOf(i); for (int j = nei.getFirstElement(); j >= 0; j = nei.getNextElement()) { if (!intVars[i].contains(j)) { g.removeArc(i, j, aCause); } } v = intVars[i]; int ub = v.getUB(); for (int j = v.getLB(); j <= ub; j = v.nextValue(j)) { if (j < n && !g.getEnvelopGraph().arcExists(i, j)) { v.removeValue(j, aCause); } } if (!v.hasEnumeratedDomain()) { ub = v.getUB(); while (ub >= 0 && ub < n && !g.getEnvelopGraph().arcExists(i, ub)) { v.removeValue(ub, aCause); ub--; } } } gdm.unfreeze(); for (int i = 0; i < idms.length; i++) { idms[i].unfreeze(); } }
/** * Links intVars and the graph arc (x,y)=var[x]=y values outside range [0,n-1] are not considered * * @param intVars * @param graph */ public PropIntVarChanneling(IntVar[] intVars, DirectedGraphVar graph) { super(ArrayUtils.append(intVars, new Variable[] {graph}), PropagatorPriority.LINEAR, true); g = graph; gdm = (GraphDeltaMonitor) g.monitorDelta(this); this.intVars = intVars; this.idms = new IIntDeltaMonitor[intVars.length]; for (int i = 0; i < intVars.length; i++) { idms[i] = intVars[i].monitorDelta(this); } this.n = g.getEnvelopGraph().getNbNodes(); valRemoved = new ValRem(); arcEnforced = new EnfArc(); if (intVars[0].hasEnumeratedDomain()) { arcRemoved = new RemArcAC(); } else { arcRemoved = new RemArcBC(); } }
@Override public ESat isEntailed() { for (int i = 0; i < vars.length; i++) { if (!vars[i].instantiated()) { return ESat.UNDEFINED; } } int val; for (int i = 0; i < n; i++) { val = intVars[i].getValue(); if (val < n && !g.getEnvelopGraph().arcExists(i, val)) { return ESat.FALSE; } if (g.getEnvelopGraph().getSuccessorsOf(i).getSize() > 1) { return ESat.FALSE; } } return ESat.TRUE; }
@Override public void propagate(int idxVarInProp, int mask) throws ContradictionException { if ((vars[idxVarInProp].getTypeAndKind() & Variable.GRAPH) != 0) { gdm.freeze(); if ((mask & EventType.ENFORCEARC.mask) != 0) { gdm.forEachArc(arcEnforced, EventType.ENFORCEARC); } if ((mask & EventType.REMOVEARC.mask) != 0) { gdm.forEachArc(arcRemoved, EventType.REMOVEARC); } gdm.unfreeze(); } else { varIdx = idxVarInProp; int val = intVars[varIdx].getLB(); if ((mask & EventType.INSTANTIATE.mask) != 0 && val < n) { g.enforceArc(varIdx, val, aCause); } idms[varIdx].freeze(); idms[idxVarInProp].forEach(valRemoved, EventType.REMOVE); idms[varIdx].unfreeze(); } }