package ifs.dbt;

import ifs.extension.*;
import ifs.heuristics.*;
import ifs.model.*;
import ifs.solution.*;
import ifs.solver.*;
import ifs.util.*;
import java.util.*;

/**
 * Selection of a variable for dynamic backtracking.
 * <br><br>
 * <li> Returns null if all variables are assigned.
 * <li> Checks if there is a varaible with all values marked as nogood (and pick it if there is any).
 * <li> Returns the first unassigned variable.
 * <br><br>
 * This IFS solver variable selection heuristics is to be used only in case of dynamic backtracking and it has no parameters.
 *
 * 
 * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomas Muller</a>
 * @version 1.0
 */
public class DbtVariableSelection implements VariableSelection {
    private DbtPropagation iProp = null;

    public DbtVariableSelection(DataProperties properties) {}

    /** 
     * Heuristics initialization
     *
     * @see VariableSelection#init(Solver)
     */
    public void init(Solver solver) {
        for (Enumeration i = solver.getExtensions().elements(); i.hasMoreElements();) {
            Extension extension = (Extension) i.nextElement();

            if (extension instanceof DbtPropagation) {
                iProp = (DbtPropagation) extension;
            }
        }
    }
    
    /** 
     * Variable selection 
     *
     * @see VariableSelection#selectVariable(Solution)
     */
    public Variable selectVariable(Solution solution) {
        if (solution.getModel().unassignedVariables().isEmpty()) {
            return null;
        }
        if (iProp != null) { 
            for (Enumeration i1 = solution.getModel().unassignedVariables().elements(); i1.hasMoreElements();) {
                Variable variable = (Variable) i1.nextElement();

                if (iProp.goodValues(variable).isEmpty()) {
                    return variable;
                }
            }
        }
        return (Variable) solution.getModel().unassignedVariables().firstElement();
    }
    
}
