001package net.sf.cpsolver.ifs.model;
002
003import java.util.Collection;
004import java.util.HashSet;
005import java.util.List;
006
007/**
008 * Generic global constraint. <br>
009 * <br>
010 * Global constraint is a {@link Constraint} that applies to all variables.
011 * 
012 * @see Variable
013 * @see Model
014 * @see Constraint
015 * @see net.sf.cpsolver.ifs.solver.Solver
016 * 
017 * @version IFS 1.2 (Iterative Forward Search)<br>
018 *          Copyright (C) 2006 - 2010 Tomáš Müller<br>
019 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
020 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
021 * <br>
022 *          This library is free software; you can redistribute it and/or modify
023 *          it under the terms of the GNU Lesser General Public License as
024 *          published by the Free Software Foundation; either version 3 of the
025 *          License, or (at your option) any later version. <br>
026 * <br>
027 *          This library is distributed in the hope that it will be useful, but
028 *          WITHOUT ANY WARRANTY; without even the implied warranty of
029 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
030 *          Lesser General Public License for more details. <br>
031 * <br>
032 *          You should have received a copy of the GNU Lesser General Public
033 *          License along with this library; if not see
034 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
035 */
036
037public abstract class GlobalConstraint<V extends Variable<V, T>, T extends Value<V, T>> extends Constraint<V, T> {
038
039    /** The list of variables of this constraint */
040    @Override
041    public List<V> variables() {
042        return getModel().variables();
043    }
044
045    /** The list of variables of this constraint that are assigned */
046    @Override
047    public Collection<V> assignedVariables() {
048        return getModel().assignedVariables();
049    }
050
051    /** Add a variable to this constraint */
052    @Override
053    public void addVariable(V variable) {
054        throw new RuntimeException("A variable cannot be added to a global constraint.");
055    }
056
057    /** Remove a variable from this constraint */
058    @Override
059    public void removeVariable(V variable) {
060        throw new RuntimeException("A variable cannot be removed from a global constraint.");
061    }
062
063    /**
064     * Given value is to be assigned to its varable. In this method, the
065     * constraint should unassigns all varaibles which are in conflict with the
066     * given assignment because of this constraint.
067     */
068    @Override
069    public void assigned(long iteration, T value) {
070        HashSet<T> conf = null;
071        if (isHard()) {
072            conf = new HashSet<T>();
073            computeConflicts(value, conf);
074        }
075        if (constraintListeners() != null)
076            for (ConstraintListener<T> listener : iConstraintListeners)
077                listener.constraintBeforeAssigned(iteration, this, value, conf);
078        if (conf != null) {
079            for (T conflictValue : conf) {
080                conflictValue.variable().unassign(iteration);
081            }
082        }
083        if (constraintListeners() != null)
084            for (ConstraintListener<T> listener : iConstraintListeners)
085                listener.constraintAfterAssigned(iteration, this, value, conf);
086    }
087
088    /**
089     * Given value is unassigned from its varable.
090     */
091    @Override
092    public void unassigned(long iteration, T value) {
093    }
094}