@Override public ESat isEntailed() { if (G.instantiated()) { int nr = 0; for (int i = 0; i < n_R.get(); i++) { nr += G_R.getSuccessorsOf(i).neighborhoodSize(); } if (nr == n_R.get() - 1) { return ESat.TRUE; } return ESat.FALSE; } return ESat.UNDEFINED; }
public int nextValue(int aValue) { aValue -= OFFSET; int lb = LB.get(); if (aValue < 0 || aValue < lb) return lb + OFFSET; aValue = VALUES.nextSetBit(aValue + 1); if (aValue > -1) return aValue + OFFSET; return Integer.MAX_VALUE; }
/** * Returns <tt>true</tt> if the iteration has more elements. (In other words, returns * <tt>true</tt> if <tt>next</tt> would return an element rather than throwing an exception.) * * @return <tt>true</tt> if the iterator has more elements. */ @Override public boolean hasNext() { i++; while (i < nlast && elements[i].isInstantiated()) { storedBipartiteVarSet.swap(i); nlast = last.get(); } return i < nlast; }
@Override public int previousValue(int aValue) { aValue -= OFFSET; int ub = UB.get(); if (aValue > ub) return ub + OFFSET; aValue = VALUES.prevSetBit(aValue - 1); if (aValue > -1) return aValue + OFFSET; return Integer.MIN_VALUE; }
/** * Updates the lower bound of the domain of <code>this</code> to <code>value</code>. The * instruction comes from <code>propagator</code>. * * <ul> * <li>If <code>value</code> is smaller than the lower bound of the domain, nothing is done and * the return value is <code>false</code>, * <li>if updating the lower bound to <code>value</code> leads to a dead-end (domain wipe-out), * a <code>ContradictionException</code> is thrown, * <li>otherwise, if updating the lower bound to <code>value</code> can be done safely, the * event type is created (the original event can be promoted) and observers are notified and * the return value is <code>true</code> * </ul> * * @param value new lower bound (included) * @param cause updating releaser * @param informCause * @return true if the lower bound has been updated, false otherwise * @throws solver.exception.ContradictionException if the domain become empty due to this action */ public boolean updateLowerBound(int value, ICause cause, boolean informCause) throws ContradictionException { boolean change; ICause antipromo = cause; if (informCause) { cause = Cause.Null; } int old = this.getLB(); if (old < value) { if (this.getUB() < value) { solver.getExplainer().updateLowerBound(this, old, value, antipromo); this.contradiction(cause, MSG_LOW); } else { EventType e = EventType.INCLOW; int aValue = value - OFFSET; if (reactOnRemoval) { // BEWARE: this loop significantly decreases performances for (int i = old - OFFSET; i < aValue; i = VALUES.nextSetBit(i + 1)) { delta.add(i + OFFSET); } } VALUES.clear(old - OFFSET, aValue); LB.set(VALUES.nextSetBit(aValue)); int _size = SIZE.get(); int card = VALUES.cardinality(); SIZE.set(card); change = _size - card > 0; if (instantiated()) { e = EventType.INSTANTIATE; if (cause.reactOnPromotion()) { cause = Cause.Null; } } assert (change); this.notifyPropagators(e, cause); solver.getExplainer().updateLowerBound(this, old, value, antipromo); return change; } } return false; }
/** Freeze the iterator, cannot be reused. */ public void init( final StoredBipartiteVarSet aStoredBipartiteVarSet, final E[] someElements, final IStateInt aLast) { super.init(); this.storedBipartiteVarSet = aStoredBipartiteVarSet; this.elements = someElements; this.last = aLast; this.nlast = aLast.get(); i = -1; }
private void updateBeta() throws ContradictionException { do { beta.add(1); } while (beta.get() < n && checkKerEnv(vars[beta.get()])); if (beta.get() > gamma.get()) { vars[alpha.get()].remFromEnveloppe(t, this, true); vars[alpha.get()].addToKernel(s, this, true); } }
private void checkGamma(int idx) throws ContradictionException { if (beta.get() < gamma.get() && idx < gamma.get() && !vars[idx].isInDomainEnveloppe(s) && vars[idx].isInDomainKernel(t)) { gamma.set(idx); if (beta.get() > idx) { vars[alpha.get()].remFromEnveloppe(t, this, true); vars[alpha.get()].addToKernel(s, this, true); } } }
public String toString() { StringBuilder s = new StringBuilder(20); s.append(name).append(" = "); if (SIZE.get() == 1) { s.append(this.getLB()); } else { s.append('{').append(getLB()); int nb = 5; for (int i = nextValue(getLB()); i < Integer.MAX_VALUE && nb > 0; i = nextValue(i)) { s.append(',').append(i); nb--; } if (nb == 0) { s.append("...,").append(this.getUB()); } s.append('}'); } return s.toString(); }
private void propagate(int idx) throws ContradictionException { if (beta.get() <= gamma.get()) { SetVar var = vars[idx]; if ((idx == alpha.get()) && checkKerEnv(var)) { updateVar(var); alpha.add(1); while (alpha.get() < beta.get()) { updateVar(vars[alpha.get()]); alpha.add(1); } while (alpha.get() < n && checkKerEnv(vars[alpha.get()])) { updateVar(vars[alpha.get()]); alpha.add(1); } beta.set(alpha.get()); if (alpha.get() < n) updateBeta(); } else if (idx == beta.get() && checkKerEnv(var)) { updateBeta(); } checkGamma(idx); } }
/** Returns the current size of the domain. */ public int getSize() { return size.get(); }
public int getDomainSize() { return SIZE.get(); }
@Override public void propagate(int evtmask) throws ContradictionException { for (int i = 0; i < n; i++) { sccFirst[i].set(-1); sccNext[i].set(-1); mates[i].clear(); G_R.getActiveNodes().desactivate(i); } ArrayList<TIntArrayList> allSCC = StrongConnectivityFinder.findAllSCCOf(G.getEnvelopGraph()); int s = allSCC.size(); n_R.set(s); int elem; TIntArrayList list; for (int i = 0; i < s; i++) { list = allSCC.get(i); G_R.getActiveNodes().activate(i); for (int j = list.size() - 1; j >= 0; j--) { elem = list.get(j); sccOf[elem].set(i); addNode(i, elem); } } INeighbors succs; int x; for (int i = 0; i < n; i++) { x = sccOf[i].get(); succs = G.getEnvelopGraph().getSuccessorsOf(i); for (int j = succs.getFirstElement(); j >= 0; j = succs.getNextElement()) { if (x != sccOf[j].get()) { G_R.addArc(x, sccOf[j].get()); mates[x].add((i + 1) * n + j); } } } int first = -1; int last = -1; for (int i = 0; i < s; i++) { if (G_R.getPredecessorsOf(i).isEmpty()) { first = i; } if (G_R.getSuccessorsOf(i).isEmpty()) { last = i; } } if (first == -1 || last == -1 || first == last) { contradiction(G, ""); } if (visit(first, last) != n_R.get()) { contradiction(G, ""); } int to, arc; for (int i = 0; i < n; i++) { to = G.getKernelGraph().getSuccessorsOf(i).getFirstElement(); x = sccOf[i].get(); if (to != -1 && sccOf[to].get() != x && mates[x].neighborhoodSize() > 1) { arc = (i + 1) * n + to; for (int a = mates[x].getFirstElement(); a >= 0; a = mates[x].getNextElement()) { if (a != arc) { G.removeArc(a / n - 1, a % n, this); } } mates[x].clear(); mates[x].add(arc); } } }
/** Returns the minimal present value. */ public int getFirstVal() { if (size.get() > 0) return contents.nextSetBit(0) + offset; else return -1; }
public boolean instantiated() { return SIZE.get() == 1; }
/** * Removes <code>value</code>from the domain of <code>this</code>. The instruction comes from * <code>propagator</code>. * * <ul> * <li>If <code>value</code> is out of the domain, nothing is done and the return value is * <code>false</code>, * <li>if removing <code>value</code> leads to a dead-end (domain wipe-out), a <code> * ContradictionException</code> is thrown, * <li>otherwise, if removing <code>value</code> from the domain can be done safely, the event * type is created (the original event can be promoted) and observers are notified and the * return value is <code>true</code> * </ul> * * @param value value to remove from the domain (int) * @param cause removal releaser * @param informCause * @return true if the value has been removed, false otherwise * @throws solver.exception.ContradictionException if the domain become empty due to this action */ public boolean removeValue(int value, ICause cause, boolean informCause) throws ContradictionException { // BEWARE: THIS CODE SHOULD NOT BE MOVED TO THE DOMAIN TO NOT DECREASE PERFORMANCES! boolean change = false; ICause antipromo = cause; if (informCause) { cause = Cause.Null; } int inf = getLB(); int sup = getUB(); if (value == inf && value == sup) { solver.getExplainer().removeValue(this, value, antipromo); this.contradiction(cause, MSG_REMOVE); } else { if (inf <= value && value <= sup) { EventType e = EventType.REMOVE; int aValue = value - OFFSET; change = VALUES.get(aValue); this.VALUES.set(aValue, false); if (change) { this.SIZE.add(-1); if (reactOnRemoval) { delta.add(aValue + OFFSET); } } if (value == inf) { LB.set(VALUES.nextSetBit(aValue)); e = EventType.INCLOW; if (cause.reactOnPromotion()) { cause = Cause.Null; } } else if (value == sup) { UB.set(VALUES.prevSetBit(aValue)); e = EventType.DECUPP; if (cause.reactOnPromotion()) { cause = Cause.Null; } } if (change && !VALUES.isEmpty()) { if (this.instantiated()) { e = EventType.INSTANTIATE; if (cause.reactOnPromotion()) { cause = Cause.Null; } } this.notifyPropagators(e, cause); } else { if (VALUES.isEmpty()) { solver.getExplainer().removeValue(this, value, antipromo); this.contradiction(cause, MSG_EMPTY); } } } } if (change) { solver.getExplainer().removeValue(this, value, antipromo); } return change; }
/** Returns the maximal present value. */ public int getLastVal() { if (size.get() > 0) return contents.prevSetBit(capacity - 1) + offset; else return -1; }
private void removeIndex(int i) { contents.clear(i); delatDom.remove(i + offset); if (contents.get(i)) LOGGER.severe("etrange etrange"); size.add(-1); }
private void initialize() throws ContradictionException { alpha = environment.makeInt(0); while ((alpha.get() < n) && checkKerEnv(vars[alpha.get()])) { updateVar(vars[alpha.get()]); alpha.add(1); } beta = environment.makeInt(alpha.get()); gamma = environment.makeInt(alpha.get()); if (alpha.get() < n) { do { gamma.add(1); } while ((gamma.get()) < n && (vars[gamma.get()].isInDomainEnveloppe(s) || !vars[gamma.get()].isInDomainKernel(t))); updateBeta(); } }
private void addIndex(int i) { contents.set(i); delatDom.remove(i + offset); if (!contents.get(i)) LOGGER.severe("etrange etrange"); size.add(1); }