001package org.cpsolver.ifs.constant;
002
003
004import java.util.ArrayList;
005import java.util.List;
006
007import org.cpsolver.ifs.assignment.Assignment;
008import org.cpsolver.ifs.model.Model;
009import org.cpsolver.ifs.model.Value;
010import org.cpsolver.ifs.model.Variable;
011
012
013/**
014 * Extension of the model with constant variables.
015 * 
016 * Such variables are excluded from the solver process, however, they can be
017 * included in constraints. Such model can allow us to build a solution on top
018 * of another solution (e.g., committed classes in the course timetabling).
019 * 
020 * Constant variable has to implement interface {@link ConstantVariable},
021 * returning {@link ConstantVariable#isConstant()} true.
022 * 
023 * @author  Tomáš Müller
024 * @version IFS 1.3 (Iterative Forward Search)<br>
025 *          Copyright (C) 2006 - 2014 Tomáš Müller<br>
026 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
027 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
028 * <br>
029 *          This library is free software; you can redistribute it and/or modify
030 *          it under the terms of the GNU Lesser General Public License as
031 *          published by the Free Software Foundation; either version 3 of the
032 *          License, or (at your option) any later version. <br>
033 * <br>
034 *          This library is distributed in the hope that it will be useful, but
035 *          WITHOUT ANY WARRANTY; without even the implied warranty of
036 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
037 *          Lesser General Public License for more details. <br>
038 * <br>
039 *          You should have received a copy of the GNU Lesser General Public
040 *          License along with this library; if not see <a href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>.
041 * 
042 * @param <V> Variable
043 * @param <T> Value
044 */
045public class ConstantModel<V extends Variable<V, T>, T extends Value<V, T>> extends Model<V, T> {
046    private List<V> iConstantVariables = null;
047
048    /** List of constant variables 
049     * @return all constants
050     **/
051    public List<V> constantVariables() {
052        return iConstantVariables;
053    }
054
055    /** True, if the model contains at least one constant variable.
056     * @return true, if there is at least one constant in this model
057     **/
058    public boolean hasConstantVariables() {
059        return iConstantVariables != null && !iConstantVariables.isEmpty();
060    }
061
062    /** True, if the given variable is constant.
063     * @param variable given variable
064     * @return true if constant
065     **/
066    public boolean isConstant(V variable) {
067        return (iConstantVariables != null && variable instanceof ConstantVariable && ((ConstantVariable<?>) variable).isConstant());
068    }
069
070    /** Adds a variable to the model */
071    @Override
072    public void addVariable(V variable) {
073        if (variable instanceof ConstantVariable && ((ConstantVariable<?>) variable).isConstant()) {
074            if (iConstantVariables == null)
075                iConstantVariables = new ArrayList<V>();
076            variable.setModel(this);
077            iConstantVariables.add(variable);
078        } else
079            super.addVariable(variable);
080    }
081
082    /** Removes a variable from the model */
083    @Override
084    public void removeVariable(V variable) {
085        if (isConstant(variable)) {
086            variable.setModel(null);
087            iConstantVariables.remove(variable);
088        } else
089            super.removeVariable(variable);
090    }
091
092    /**
093     * Called before a value is assigned to its variable. Constant variables are
094     * excluded from (re)assignment.
095     */
096    @Override
097    public void beforeAssigned(Assignment<V, T> assignment, long iteration, T value) {
098        if (!isConstant(value.variable()))
099            super.beforeAssigned(assignment, iteration, value);
100    }
101
102    /**
103     * Called before a value is unassigned from its variable. Constant variables
104     * are excluded from (re)assignment.
105     */
106    @Override
107    public void beforeUnassigned(Assignment<V, T> assignment, long iteration, T value) {
108        if (!isConstant(value.variable()))
109            super.beforeUnassigned(assignment, iteration, value);
110    }
111
112    /**
113     * Called after a value is assigned to its variable. Constant variables are
114     * excluded from (re)assignment.
115     */
116    @Override
117    public void afterAssigned(Assignment<V, T> assignment, long iteration, T value) {
118        if (!isConstant(value.variable()))
119            super.afterAssigned(assignment, iteration, value);
120    }
121
122    /**
123     * Called after a value is unassigned from its variable. Constant variables
124     * are excluded from (re)assignment.
125     */
126    @Override
127    public void afterUnassigned(Assignment<V, T> assignment, long iteration, T value) {
128        if (!isConstant(value.variable()))
129            super.afterUnassigned(assignment, iteration, value);
130    }
131}