    001package net.sf.cpsolver.ifs.extension;
    002
    003import net.sf.cpsolver.ifs.model.Constraint;
    004import net.sf.cpsolver.ifs.model.Model;
    005import net.sf.cpsolver.ifs.model.ModelListener;
    006import net.sf.cpsolver.ifs.model.Value;
    007import net.sf.cpsolver.ifs.model.Variable;
    008import net.sf.cpsolver.ifs.solver.Solver;
    009import 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 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
    040 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
    041 */
    042public 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}