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 }