    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}