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