001    package net.sf.cpsolver.ifs.model;
002    
003    import java.util.Collection;
004    import java.util.HashSet;
005    import 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 Tomas Muller<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    
037    public 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    }