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