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