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