    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}