001    package net.sf.cpsolver.ifs.constant;
002    
003    import java.util.Vector;
004    
005    import net.sf.cpsolver.ifs.model.Model;
006    import net.sf.cpsolver.ifs.model.Value;
007    import net.sf.cpsolver.ifs.model.Variable;
008    import net.sf.cpsolver.ifs.util.FastVector;
009    
010    /**
011     * Extension of the model with constant variables.
012     * 
013     * Such variables are excluded from the solver process, however, 
014     * they can be included in constraints. Such model can allow us to build a solution
015     * on top of another solution (e.g., committed classes in the course timetabling).
016     * 
017     * Constant variable has to implement interface {@link ConstantVariable}, 
018     * returning {@link ConstantVariable#isConstant()} true.
019     *
020     * @version
021     * IFS 1.1 (Iterative Forward Search)<br>
022     * Copyright (C) 2006 Tomáš Müller<br>
023     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
024     * Lazenska 391, 76314 Zlin, Czech Republic<br>
025     * <br>
026     * This library is free software; you can redistribute it and/or
027     * modify it under the terms of the GNU Lesser General Public
028     * License as published by the Free Software Foundation; either
029     * version 2.1 of the License, or (at your option) any later version.
030     * <br><br>
031     * This library is distributed in the hope that it will be useful,
032     * but WITHOUT ANY WARRANTY; without even the implied warranty of
033     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
034     * Lesser General Public License for more details.
035     * <br><br>
036     * You should have received a copy of the GNU Lesser General Public
037     * License along with this library; if not, write to the Free Software
038     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
039     *  
040     */
041    
042    public class ConstantModel extends Model {
043            private Vector iConstantVariables = null;
044            
045            /** List of constant variables */
046            public Vector constantVariables() { return iConstantVariables; }
047            
048            /** True, if the model contains at least one constant variable. */
049            public boolean hasConstantVariables() { return iConstantVariables!=null && !iConstantVariables.isEmpty(); }
050            
051            /** True, if the given variable is constant. */
052            public boolean isConstant(Variable variable) {
053                    return (iConstantVariables!=null && variable instanceof ConstantVariable && ((ConstantVariable)variable).isConstant());
054            }
055            
056        /** Adds a variable to the model */
057        public void addVariable(Variable variable) {
058            if (variable instanceof ConstantVariable && ((ConstantVariable)variable).isConstant()) {
059                    if (iConstantVariables==null) iConstantVariables = new FastVector();
060                    variable.setModel(this);
061                    iConstantVariables.addElement(variable);
062                    if (variable.getAssignment()!=null) variable.assign(0L,variable.getAssignment());
063            } else super.addVariable(variable);
064        }
065        
066        /** Removes a variable from the model */
067        public void removeVariable(Variable variable) {
068            if (isConstant(variable)) {
069                    variable.setModel(null);
070                    iConstantVariables.removeElement(variable);
071            } else super.removeVariable(variable);
072        }
073        
074        /** Called before a value is assigned to its variable. Constant variables are excluded from (re)assignment. */
075        public void beforeAssigned(long iteration, Value value) {
076            if (!isConstant(value.variable())) super.beforeAssigned(iteration, value);
077        }
078        
079        /** Called before a value is unassigned from its variable. Constant variables are excluded from (re)assignment. */
080        public void beforeUnassigned(long iteration, Value value) {
081            if (!isConstant(value.variable())) super.beforeUnassigned(iteration, value);
082        }
083        
084        /** Called after a value is assigned to its variable. Constant variables are excluded from (re)assignment. */
085        public void afterAssigned(long iteration, Value value) {
086            if (!isConstant(value.variable())) super.afterAssigned(iteration, value);
087        }
088        
089        /** Called after a value is unassigned from its variable. Constant variables are excluded from (re)assignment. */
090        public void afterUnassigned(long iteration, Value value) {
091            if (!isConstant(value.variable())) super.afterUnassigned(iteration, value);
092        }
093    }