001    package net.sf.cpsolver.ifs.extension;
002    
003    import net.sf.cpsolver.ifs.model.Constraint;
004    import net.sf.cpsolver.ifs.model.Model;
005    import net.sf.cpsolver.ifs.model.ModelListener;
006    import net.sf.cpsolver.ifs.model.Value;
007    import net.sf.cpsolver.ifs.model.Variable;
008    import net.sf.cpsolver.ifs.solver.Solver;
009    import net.sf.cpsolver.ifs.util.DataProperties;
010    
011    /**
012     * Generic extension of IFS solver. <br>
013     * <br>
014     * All extensions should extend this class. <br>
015     * <br>
016     * An extension may use extra information associated with a variable or a value
017     * (see {@link Variable#setExtra(Object)}, {@link Variable#getExtra()},
018     * {@link Value#setExtra(Object)}, {@link Value#getExtra()}) but there can be
019     * only one extension using these extra objects used during the search. For
020     * instance, {@link MacPropagation} is using these extra objects to memorize
021     * explanations.
022     * 
023     * @version IFS 1.2 (Iterative Forward Search)<br>
024     *          Copyright (C) 2006 - 2010 Tomas Muller<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
040     *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
041     */
042    public class Extension<V extends Variable<V, T>, T extends Value<V, T>> implements ModelListener<V, T> {
043        private Model<V, T> iModel = null;
044        private Solver<V, T> iSolver = null;
045        private DataProperties iProperties = null;
046    
047        /**
048         * Constructor
049         * 
050         * @param solver
051         *            IFS solver
052         * @param properties
053         *            input configuration
054         */
055        public Extension(Solver<V, T> solver, DataProperties properties) {
056            iSolver = solver;
057            iProperties = properties;
058        }
059    
060        /** Registration of a model. This is called by the solver before start. */
061        public void register(Model<V, T> model) {
062            iModel = model;
063            iModel.addModelListener(this);
064        }
065    
066        /**
067         * Unregistration of a model. This is called by the solver when extension is
068         * removed.
069         */
070        public void unregister(Model<V, T> model) {
071            iModel.removeModelListener(this);
072            iModel = null;
073        }
074    
075        /**
076         * Returns true if there is a model registered to this extension, i.e., when
077         * extension is registered.
078         */
079        public boolean isRegistered() {
080            return iModel != null;
081        }
082    
083        /** Returns the model */
084        public Model<V, T> getModel() {
085            return iModel;
086        }
087    
088        /** Returns the solver */
089        public Solver<V, T> getSolver() {
090            return iSolver;
091        }
092    
093        /** Returns input configuration */
094        public DataProperties getProperties() {
095            return iProperties;
096        }
097    
098        /** Called after a value is assigned to a variable */
099        @Override
100        public void afterAssigned(long iteration, T value) {
101        }
102    
103        /** Called after a value is unassigned from a variable */
104        @Override
105        public void afterUnassigned(long iteration, T value) {
106        }
107    
108        /** Called before a value is assigned to a variable */
109        @Override
110        public void beforeAssigned(long iteration, T value) {
111        }
112    
113        /** Called after a value is unassigned from a variable */
114        @Override
115        public void beforeUnassigned(long iteration, T value) {
116        }
117    
118        /** Called when a constraint is added to the model */
119        @Override
120        public void constraintAdded(Constraint<V, T> constraint) {
121        }
122    
123        /** Called when a constraint is removed from the model */
124        @Override
125        public void constraintRemoved(Constraint<V, T> constraint) {
126        }
127    
128        /** Called when a variable is added to the model */
129        @Override
130        public void variableAdded(V variable) {
131        }
132    
133        /** Called when a variable is removed from the model */
134        @Override
135        public void variableRemoved(V variable) {
136        }
137    
138        /** Initialization -- called before the solver is started */
139        @Override
140        public boolean init(Solver<V, T> solver) {
141            return true;
142        }
143    
144        /**
145         * Should return true when {@link Value#setExtra(Object)},
146         * {@link Value#getExtra()} are used by the extension
147         */
148        public boolean useValueExtra() {
149            return false;
150        }
151    
152        /**
153         * Should return true when {@link Variable#setExtra(Object)},
154         * {@link Variable#getExtra()} are used by the extension
155         */
156        public boolean useVariableExtra() {
157            return false;
158        }
159    }