// ** This file was generated with DemFGen (vers:4/15/2011)

package hsr;

import edu.neu.ccs.demeterf.lib.*;
import edu.neu.ccs.demeterf.lib.*;
import scg.*;





/** Representation of HSRInstance */
public class HSRInstance implements InstanceI{
    protected int n;
    protected int k;

    /** Construct a(n) HSRInstance Instance */
    public HSRInstance(int n, int k){
        this.n = n;
        this.k = k;
    }
    /** Is the given object Equal to this HSRInstance? */
    public boolean equals(Object o){
        if(!(o instanceof HSRInstance))return false;
        if(o == this)return true;
        HSRInstance oo = (HSRInstance)o;
        return (((Object)n).equals(oo.n))&&(((Object)k).equals(oo.k));
    }
    /** Parse an instance of HSRInstance from the given String */
    public static HSRInstance parse(String inpt) throws hsr.ParseException{
        return new hsr.TheParser(new java.io.StringReader(inpt)).parse_HSRInstance();
    }
    /** Parse an instance of HSRInstance from the given Stream */
    public static HSRInstance parse(java.io.InputStream inpt) throws hsr.ParseException{
        return new hsr.TheParser(inpt).parse_HSRInstance();
    }
    /** Parse an instance of HSRInstance from the given Reader */
    public static HSRInstance parse(java.io.Reader inpt) throws hsr.ParseException{
        return new hsr.TheParser(inpt).parse_HSRInstance();
    }

    /** Field Class for HSRInstance.n */
    public static class n extends edu.neu.ccs.demeterf.Fields.any{}
    /** Field Class for HSRInstance.k */
    public static class k extends edu.neu.ccs.demeterf.Fields.any{}
 
	public double valid(SolutionI solution, Config config){
    	HSRSolution hsrSolution = (HSRSolution) solution;
    	boolean isValid = lessThanEqualKBranches(hsrSolution, 0) && areNodesValid(hsrSolution);
    	if(isValid)
    		return 1;
    	else
    		return 0;
	}
	
	private boolean lessThanEqualKBranches(HSRSolution s, int jarsBroken){
		if(jarsBroken > k) return false;
    	else{
    		if(s instanceof Compound){
    			return lessThanEqualKBranches(((Compound) s).getYes(), jarsBroken +1) &&
    				lessThanEqualKBranches(((Compound) s).getNo(), jarsBroken);
    		}else{
    			return true;
    		}
    	}
    }
	
	 private boolean areNodesValid(HSRSolution s){
		java.util.List<Integer> internalNodes = buildIntList(getN());
		internalNodes.remove(0);
		java.util.List<Integer> leaves = buildIntList(getN());
		return nodesValid(s, internalNodes, leaves) && internalNodes.isEmpty() && leaves.isEmpty();
	}
	 
	 private java.util.List<Integer> buildIntList(int bound){
    	java.util.List<Integer> intList = new java.util.ArrayList<Integer>();
    	for(int i=0; i<bound; i++){
    		intList.add(new Integer(i));
    	}
    	return intList;
    }
	 
	 private boolean nodesValid(HSRSolution s, java.util.List<Integer> internalNodes, java.util.List<Integer> leaves){
    	if(s instanceof Compound){
    		Integer question = new Integer(((Compound) s).getQuestion());
    		if(internalNodes.contains(question)){
    			internalNodes.remove(question);
    			return nodesValid(((Compound) s).getYes(), internalNodes, leaves) & 
    					nodesValid(((Compound) s).getNo(), internalNodes, leaves);
    		}else{
    			return false;
    		}
    	}else{
    		Integer hsr = new Integer(((Simple) s).getHighest_safe_rung());
    		if(leaves.contains(hsr)){
    			leaves.remove(hsr);
    			return true;
    		}else{
    			return false;
    		}
    	}
    }
	public double quality(SolutionI solution){
		HSRSolution hsrSolution = (HSRSolution) solution;
		if(n >0){
			return (double)hsrSolution.findDepth()/n;
		}
		return 0;
	}

    /** DGP method from Class Display */
    public String display(){ return hsr.Display.DisplayM(this); }
    /** DGP method from Class Print */
    public String print(){ return hsr.Print.PrintM(this); }
    /** DGP method from Class ToStr */
    public String toStr(){ return hsr.ToStr.ToStrM(this); }
    /** DGP method from Class PrintToString */
    public String toString(){ return hsr.PrintToString.PrintToStringM(this); }
    /** DGP method from Class HashCode */
    public int hashCode(){ return hsr.HashCode.HashCodeM(this); }
    /** Setter for field HSRInstance.n */
    public void setN(int _n){ n = _n; }
    /** Setter for field HSRInstance.k */
    public void setK(int _k){ k = _k; }
    /** Getter for field HSRInstance.n */
    public int getN(){ return n; }
    /** Getter for field HSRInstance.k */
    public int getK(){ return k; }

}


