All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.chocosolver.solver.variables.impl.FixedIntVarImpl Maven / Gradle / Ivy

There is a newer version: 4.10.17
Show newest version
/*
 * This file is part of choco-solver, http://choco-solver.org/
 *
 * Copyright (c) 2020, IMT Atlantique. All rights reserved.
 *
 * Licensed under the BSD 4-clause license.
 *
 * See LICENSE file in the project root for full license information.
 */
package org.chocosolver.solver.variables.impl;

import org.chocosolver.solver.ICause;
import org.chocosolver.solver.Model;
import org.chocosolver.solver.exception.ContradictionException;
import org.chocosolver.solver.variables.IVariableMonitor;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.solver.variables.Variable;
import org.chocosolver.solver.variables.delta.IIntDeltaMonitor;
import org.chocosolver.solver.variables.delta.NoDelta;
import org.chocosolver.solver.variables.events.IEventType;
import org.chocosolver.solver.variables.impl.scheduler.IntEvtScheduler;
import org.chocosolver.solver.variables.impl.siglit.SignedLiteral;
import org.chocosolver.solver.variables.view.IView;
import org.chocosolver.util.iterators.DisposableRangeIterator;
import org.chocosolver.util.iterators.DisposableValueIterator;
import org.chocosolver.util.iterators.EvtScheduler;
import org.chocosolver.util.iterators.IntVarValueIterator;
import org.chocosolver.util.objects.setDataStructures.iterable.IntIterableRangeSet;
import org.chocosolver.util.objects.setDataStructures.iterable.IntIterableSet;

import java.util.Iterator;

/**
 * A IntVar with one domain value.
 * 

* Based on "Views and Iterators for Generic Constraint Implementations", * C. Schulte and G. Tack *
* * @author Charles Prud'homme * @since 04/02/11 */ public class FixedIntVarImpl extends AbstractVariable implements IntVar { /** * The constant this variable relies on. */ protected final int constante; /** * Reusable iterator over values. */ private DisposableValueIterator _viterator; /** * Reusable iterator over ranges. */ private DisposableRangeIterator _riterator; /** * Value iterator allowing for(int i:this) loops */ private IntVarValueIterator _javaIterator = new IntVarValueIterator(this); /** * Signed Literal */ protected SignedLiteral literal; /** * Creates a variable whom domain is natively reduced to the singleton {constante}. * * @param name name of the variable * @param constante value its domain is reduced to * @param model the declaring model */ public FixedIntVarImpl(String name, int constante, Model model) { super(name, model); this.constante = constante; } @Override public boolean removeValue(int value, ICause cause) throws ContradictionException { if (value == constante) { assert cause != null; model.getSolver().getEventObserver().removeValue(this, constante, cause); this.contradiction(cause, "unique value removal"); } return false; } @Override public boolean removeValues(IntIterableSet values, ICause cause) throws ContradictionException { if (values.contains(constante)) { assert cause != null; model.getSolver().getEventObserver().removeValue(this, constante, cause); this.contradiction(cause, "unique value removal"); } return false; } @Override public boolean removeAllValuesBut(IntIterableSet values, ICause cause) throws ContradictionException { if (!values.contains(constante)) { assert cause != null; model.getSolver().getEventObserver().removeValue(this, constante, cause); this.contradiction(cause, "unique value removal"); } return false; } @Override public boolean removeInterval(int from, int to, ICause cause) throws ContradictionException { if (from <= constante && constante <= to) { assert cause != null; model.getSolver().getEventObserver().removeValue(this, constante, cause); this.contradiction(cause, "unique value removal"); } return false; } @Override public boolean instantiateTo(int value, ICause cause) throws ContradictionException { if (value != constante) { assert cause != null; model.getSolver().getEventObserver().instantiateTo(this, value, cause, constante, constante); this.contradiction(cause, "outside domain instantitation"); } return false; } @Override public boolean updateLowerBound(int value, ICause cause) throws ContradictionException { if (value > constante) { assert cause != null; model.getSolver().getEventObserver().updateLowerBound(this, value, constante, cause); this.contradiction(cause, "outside domain update bound"); } return false; } @Override public boolean updateUpperBound(int value, ICause cause) throws ContradictionException { if (value < constante) { assert cause != null; model.getSolver().getEventObserver().updateUpperBound(this, value, constante, cause); this.contradiction(cause, "outside domain update bound"); } return false; } @Override public boolean updateBounds(int lb, int ub, ICause cause) throws ContradictionException { if (lb > constante) { assert cause != null; model.getSolver().getEventObserver().updateLowerBound(this, lb, constante, cause); this.contradiction(cause, "outside domain update bound"); } else if (ub < constante) { model.getSolver().getEventObserver().updateUpperBound(this, ub, constante, cause); this.contradiction(cause, "outside domain update bound"); } return false; } @Override public boolean contains(int value) { return constante == value; } @Override public boolean isInstantiatedTo(int value) { return constante == value; } @Override public int getValue() { return constante; } @Override public int getLB() { return constante; } @Override public int getUB() { return constante; } @Override public int getDomainSize() { return 1; } @Override public int getRange() { return 1; } @Override public int nextValue(int v) { if (v < constante) { return constante; } else { return Integer.MAX_VALUE; } } @Override public int nextValueOut(int v) { if (v == constante - 1) { return constante + 1; } else { return v + 1; } } @Override public int previousValue(int v) { if (v > constante) { return constante; } else { return Integer.MIN_VALUE; } } @Override public int previousValueOut(int v) { if (v == constante + 1) { return constante - 1; } else { return v - 1; } } @Override public boolean hasEnumeratedDomain() { return true; } @Override public NoDelta getDelta() { return NoDelta.singleton; } @Override public boolean isInstantiated() { return true; } @Override//void (a constant receives no event) public void addMonitor(IVariableMonitor monitor) { } @Override//void (a constant receives no event) public void removeMonitor(IVariableMonitor monitor) { } @Override//void (a constant receives no event) public void subscribeView(IView view) { } @SuppressWarnings("unchecked") @Override public IIntDeltaMonitor monitorDelta(ICause propagator) { return IIntDeltaMonitor.Default.NONE; } @Override public void createDelta() { } @Override//void (a constant receives no event) public void notifyPropagators(IEventType event, ICause cause) throws ContradictionException { } @Override//void (a constant receives no event) public void notifyMonitors(IEventType event) throws ContradictionException { } @Override//void (a constant receives no event) public void notifyViews(IEventType event, ICause cause) throws ContradictionException { } @Override public String toString() { return name + " = " + constante; } @Override public int getTypeAndKind() { return Variable.INT | Variable.CSTE; } @Override protected EvtScheduler createScheduler() { return new IntEvtScheduler(); } @Override public DisposableValueIterator getValueIterator(boolean bottomUp) { if (_viterator == null || _viterator.isNotReusable()) { _viterator = new DisposableValueIterator() { /** * Set to true if iteration has not started yet, false otherwise */ boolean _next; @Override public void bottomUpInit() { super.bottomUpInit(); _next = true; } @Override public void topDownInit() { super.topDownInit(); _next = true; } @Override public boolean hasNext() { return _next; } @Override public boolean hasPrevious() { return _next; } @Override public int next() { _next = false; return constante; } @Override public int previous() { _next = false; return constante; } }; } if (bottomUp) { _viterator.bottomUpInit(); } else { _viterator.topDownInit(); } return _viterator; } @Override public DisposableRangeIterator getRangeIterator(boolean bottomUp) { if (_riterator == null || _riterator.isNotReusable()) { _riterator = new DisposableRangeIterator() { /** * Set to true if the iteration has not started yet, false otherwise */ boolean _next; @Override public void bottomUpInit() { super.bottomUpInit(); _next = true; } @Override public void topDownInit() { super.topDownInit(); _next = true; } @Override public boolean hasNext() { return _next; } @Override public boolean hasPrevious() { return _next; } @Override public void next() { _next = false; } @Override public void previous() { _next = false; } @Override public int min() { return constante; } @Override public int max() { return constante; } }; } if (bottomUp) { _riterator.bottomUpInit(); } else { _riterator.topDownInit(); } return _riterator; } @Override public Iterator iterator() { _javaIterator.reset(); return _javaIterator; } @Override public void createLit(IntIterableRangeSet rootDomain) { if (this.literal != null) { throw new IllegalStateException("createLit(Implications) called twice"); } this.literal = new SignedLiteral.Set(rootDomain); } @Override public SignedLiteral getLit() { if (this.literal == null) { throw new NullPointerException("getLit() called on null, a call to createLit(Implications) is required"); } return this.literal; } }