// Path: src/com/infdot/analysis/solver/lattice/Domain.java
// public interface Domain<V> {
// 	public V bottom();
// 	
// 	/**
// 	 * Factory method to create analysis state of given size.
// 	 */
// 	public V[] createStartState(int size);
// }


import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.infdot.analysis.solver.lattice.Domain;
package com.infdot.analysis.solver;



/**
 * Helper class to keep set of all dataflow constraints
 * of some specific analysis.
 * 
 * @author Raivo Laanemets
 * 
 * @param <V> type of dataflow values.
 * @param <M> type of metainfo associated with dataflow variables.
 */
public class DataflowConstraintSet<V, M> {
	private Map<Integer, DataflowContraint<V>> constraints =
		new HashMap<Integer, DataflowContraint<V>>();
	
	/**
	 * Associates variable to node where it belongs.
	 * Used for interpreting results later.
	 */
	private Map<Integer, M> metainfo = new HashMap<Integer, M>();
	
	/**
	 * Adds constraint xi = F(x1, ..., xn) to the constraint set.
	 */
	public void addConstraint(int variable, DataflowExpression<V> expression, M metainfo) {
		constraints.put(variable, new DataflowContraint<V>(variable, expression));
		this.metainfo.put(variable, metainfo);
	}
	
	/**
	 * Recalculates dependency sets for each constraints. Constraint
	 * Cd depends on constraint xi = ... when xi occurs as variable
	 * in Cd and thus Cd has to be recalculated. 
	 */
	public void recalculateDependencies() {
		for (DataflowContraint<V> constraint : constraints.values()) {
			constraint.clearDependencies();
		}
		
		for (DataflowContraint<V> constraint : constraints.values()) {
			for (int i : constraint.getVariables()) {
				constraints.get(i).addDependent(constraint);
			}
		}
	}
	
	/**
	 * Creates start state for analysis.
	 */
// Path: src/com/infdot/analysis/solver/lattice/Domain.java
// public interface Domain<V> {
// 	public V bottom();
// 	
// 	/**
// 	 * Factory method to create analysis state of given size.
// 	 */
// 	public V[] createStartState(int size);
// }


// Path: src/com/infdot/analysis/solver/DataflowConstraintSet.java
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.infdot.analysis.solver.lattice.Domain;

package com.infdot.analysis.solver;



/**
 * Helper class to keep set of all dataflow constraints
 * of some specific analysis.
 * 
 * @author Raivo Laanemets
 * 
 * @param <V> type of dataflow values.
 * @param <M> type of metainfo associated with dataflow variables.
 */
public class DataflowConstraintSet<V, M> {
	private Map<Integer, DataflowContraint<V>> constraints =
		new HashMap<Integer, DataflowContraint<V>>();
	
	/**
	 * Associates variable to node where it belongs.
	 * Used for interpreting results later.
	 */
	private Map<Integer, M> metainfo = new HashMap<Integer, M>();
	
	/**
	 * Adds constraint xi = F(x1, ..., xn) to the constraint set.
	 */
	public void addConstraint(int variable, DataflowExpression<V> expression, M metainfo) {
		constraints.put(variable, new DataflowContraint<V>(variable, expression));
		this.metainfo.put(variable, metainfo);
	}
	
	/**
	 * Recalculates dependency sets for each constraints. Constraint
	 * Cd depends on constraint xi = ... when xi occurs as variable
	 * in Cd and thus Cd has to be recalculated. 
	 */
	public void recalculateDependencies() {
		for (DataflowContraint<V> constraint : constraints.values()) {
			constraint.clearDependencies();
		}
		
		for (DataflowContraint<V> constraint : constraints.values()) {
			for (int i : constraint.getVariables()) {
				constraints.get(i).addDependent(constraint);
			}
		}
	}
	
	/**
	 * Creates start state for analysis.
	 */
	public V[] createStartState(Domain<V> domain) {