All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.metacsp.framework.multi.MultiConstraintSolver Maven / Gradle / Ivy

There is a newer version: 1.3.5
Show newest version
/*******************************************************************************
 * Copyright (c) 2010-2013 Federico Pecora 
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 ******************************************************************************/
package org.metacsp.framework.multi;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Vector;

import org.metacsp.framework.Constraint;
import org.metacsp.framework.ConstraintNetwork;
import org.metacsp.framework.ConstraintSolver;
import org.metacsp.framework.Variable;
import org.metacsp.throwables.ConstraintNotFound;
import org.metacsp.throwables.UnimplementedSubVariableException;
import org.metacsp.utility.UI.ConstraintNetworkHierarchyFrame;
import org.metacsp.utility.UI.ConstraintSolverHierarchyFrame;

import edu.uci.ics.jung.graph.DelegateTree;
import edu.uci.ics.jung.graph.util.TreeUtils;

/**
 * This class extends the {@link ConstraintSolver} class providing functionality
 * to deal with {@link MultiVariable}s and {@link MultiConstraint}s.  It should be extended
 * to create new {@link MultiConstraintSolver}s.  In doing so, the designer should define
 * how variables are created (methods createVariableSub() and createVariablesSub()), how to 
 * create internal constraint solvers underlying this {@link MultiConstraintSolver} (method
 * createConstraintSolvers()) and how propagation should occur (method propagate()).  Note that
 * if propagation occurs by means of the underlying constraint solvers, the propagate() method can
 * left empty (return true).
 *  
 * @author Federico Pecora
 *
 */
public abstract class MultiConstraintSolver extends ConstraintSolver {

	private static final long serialVersionUID = 3328919153619683198L;
	
	/**
	 * These are options used by the {@link ConstraintSolver} class to determine
	 * whether inconsistencies should be allowed in the constraitn networks of the
	 * underlying constraint solvers.
	 *  
	 * @author Federico Pecora
	 */
	public static enum OPTIONS {ALLOW_INCONSISTENCIES,FORCE_CONSISTENCY};
	
	private boolean allowInconsistencies = false;
	protected ConstraintSolver[] constraintSolvers;
	protected int[] ingredients;
	private HashMap newConstraintMapping = new HashMap();
	
	public static ConstraintSolver getConstraintSolver(ConstraintSolver cs, Class constraintSolverClass) {
		if (cs.getClass().equals(constraintSolverClass)) return cs;
		if (cs instanceof MultiConstraintSolver) {
			MultiConstraintSolver mcs = (MultiConstraintSolver)cs;
			for (int i = 0; i < mcs.getConstraintSolvers().length; i++) {
				ConstraintSolver ret = getConstraintSolver(mcs.getConstraintSolvers()[i], constraintSolverClass);
				if (ret != null) return ret;
			}
		}
		return null;
	}

	/**
	 * The constructor of a extending class must call this constructor.
	 * @param constraintTypes
	 * @param internalSolvers
	 */
	protected MultiConstraintSolver(Class[] constraintTypes, Class variableType, ConstraintSolver[] internalSolvers, int[] ingredients) {
		super(constraintTypes, variableType);
		this.constraintSolvers = internalSolvers;
		this.ingredients = ingredients;
	}

	/**
	 *  Method to set the options for this {@link MultiConstraintSolver} (see {@link OPTIONS}).
	 *  @param ops Options to set (see {@link OPTIONS}).
	 */
	public void setOptions(OPTIONS ...ops) {
		for (OPTIONS op : ops)
			if (op.equals(OPTIONS.ALLOW_INCONSISTENCIES)) allowInconsistencies = true;
			else if (op.equals(OPTIONS.FORCE_CONSISTENCY)) allowInconsistencies = false;
	}
	
	/**
	 * Method to get options of this {@link MultiConstraintSolver} (see {@link OPTIONS}).
	 * @param op The option that should be checked
	 * @return true iff the given option was set  
	 */
	public boolean getOption(OPTIONS op) {
		if (op.equals(OPTIONS.ALLOW_INCONSISTENCIES)) return allowInconsistencies;
		else if (op.equals(OPTIONS.FORCE_CONSISTENCY)) return !allowInconsistencies;
		return false;
	}
	
	/**
	 * Set the number of internal variables of different types that are to be created when
	 * calling the method createVariables().
	 * @param ingredients The number of internal variables, oen number for each type, that are to 
	 * be created.
	 */
	public void setIngredients(int[] ingredients) {
		this.ingredients = ingredients;
	}
		
	@Override
	protected final boolean addConstraintsSub(Constraint[] c) {
		HashMap> sortedCons = new HashMap>();
		for (Constraint con : c) {
			if (con instanceof MultiConstraint) {
				MultiConstraint mc = (MultiConstraint)con;
				MultiVariable mv = (MultiVariable)mc.getScope()[0];
				for (ConstraintSolver cs : mv.getInternalConstraintSolvers()) {
					if (mc.propagateImmediately()) {
						if (!sortedCons.containsKey(cs)) {
							sortedCons.put(cs, new ArrayList());
						}
						Constraint[] internalCons = mc.getInternalConstraints();
						if (internalCons != null) {
							for (Constraint ic : internalCons) {
								if (!ic.isSkippableSolver(cs)) sortedCons.get(cs).add(ic);
							}
						}
					}
				}
			}
		}

		HashMap> sortedConsRetract = new HashMap>();
		for (ConstraintSolver cs : sortedCons.keySet()) {
			//if caller is noprop do not prop
			if (!this.skipPropagation) {
				if (cs.addConstraints(sortedCons.get(cs).toArray(new Constraint[sortedCons.get(cs).size()]))) {
					logger.finest("Added sub-constraints " + sortedCons.get(cs));
					sortedConsRetract.put(cs, sortedCons.get(cs));
				}
				else {
					for (ConstraintSolver cs1 : sortedConsRetract.keySet()) {
						logger.finest("Removing internal constraints (" + this.getClass().getSimpleName() + ") " + sortedConsRetract.get(cs1));
						cs1.removeConstraints(sortedConsRetract.get(cs1).toArray(new Constraint[sortedConsRetract.get(cs1).size()]));
					}
					logger.finest("Failed to add sub-constraints " + Arrays.toString(c));
					return false;
				}				
			}
			else {
				cs.addConstraintsNoPropagation(sortedCons.get(cs).toArray(new Constraint[sortedCons.get(cs).size()]));
				logger.finest("Added sub-constraints " + sortedCons.get(cs) + " (but DELAYED propagation)");
			}
		}

		if (!instantiateLiftedConstraints(c)) {
			for (ConstraintSolver cs1 : sortedConsRetract.keySet()) 
				cs1.removeConstraints(sortedConsRetract.get(cs1).toArray(new Constraint[sortedConsRetract.get(cs1).size()]));
			logger.finest("Failed to instantiate lifted constraints " + Arrays.toString(c));
			return false;
		}
		return true;
	
	}

	private boolean instantiateLiftedConstraints(Constraint[] c) {
		Vector> newToAdd = new Vector>();
		Vector> added = new Vector>();

		for(int i = 0; i < this.constraintTypes.length; ++i) {
			newToAdd.add(new Vector());
			added.add(new Vector());			
		}
		
		for (Constraint constr : c) {
			for (int i = 0; i < this.constraintTypes.length; i++) {				
				Vector internalScope = new Vector(); 
				if (this.constraintTypes[i].isInstance(constr)) {
					Variable[] scope = constr.getScope();
					for (Variable v : scope) {
						MultiVariable mv = (MultiVariable)v;
						internalScope.add(mv.getInternalVariables()[i]);
					}
					Variable[] internalScopeArray = internalScope.toArray(new Variable[internalScope.size()]);
					Constraint newConstraint = (Constraint)constr.clone();
					newConstraint.setScope(internalScopeArray);
					newToAdd.elementAt(i).add(newConstraint);
					newConstraintMapping.put(constr, newConstraint);
					break;
				}
			}
		}
		
		boolean retract = false;
		for (int i = 0; i < this.constraintTypes.length && !retract; i++) {
			Vector newCons = newToAdd.elementAt(i);
			//	if there is something to insert...
			if (!newCons.isEmpty()) {
				Constraint[] newConsArray = newCons.toArray(new Constraint[newCons.size()]);
				if (!this.constraintSolvers[i].addConstraints(newConsArray)) {
					/* if (!allowInconsistencies) */ retract = true;
				}
				else {
					added.set(i, newCons);
				}
			}
		}
		if (retract) {
			for (int i = 0; i < added.size(); i++) {
				Vector toRetract = added.elementAt(i);
				if (!toRetract.isEmpty()) {
					this.constraintSolvers[i].removeConstraints(toRetract.toArray(new Constraint[toRetract.size()]));
					ArrayList toRemoveFromNewConstraintMapping = new ArrayList();
					for (Constraint oldConstr : newConstraintMapping.keySet()) {
						for (Constraint newConstr : toRetract) {
							if (newConstraintMapping.get(oldConstr).equals(newConstr)) {
								//newConstraintMapping.remove(oldConstr);
								toRemoveFromNewConstraintMapping.add(oldConstr);
								break;
							}
						}
					}
					for (Constraint toRemoveFromMapping : toRemoveFromNewConstraintMapping)
						newConstraintMapping.remove(toRemoveFromMapping);
				}
			}
			return false;
		}
		return true;
		
	}
	
//	@Override
//	protected final boolean addConstraintsSub(Constraint[] c) {
//		
//		Vector> newToAdd = new Vector>();
//		Vector> added = new Vector>();
//
//		for(int i = 0; i < this.constraintTypes.length; ++i) {
//			newToAdd.add(new Vector());
//			added.add(new Vector());			
//		}
//		
//		for (Constraint constr : c) {
//			for (int i = 0; i < this.constraintTypes.length; i++) {				
//				Vector internalScope = new Vector(); 
//				if (this.constraintTypes[i].isInstance(constr)) {
//					Variable[] scope = constr.getScope();
//					for (Variable v : scope) {
//						MultiVariable mv = (MultiVariable)v;
//						internalScope.add(mv.getInternalVariables()[i]);
//					}
//					Variable[] internalScopeArray = internalScope.toArray(new Variable[internalScope.size()]);
//					Constraint newConstraint = (Constraint)constr.clone();
//					newConstraint.setScope(internalScopeArray);
//					newToAdd.elementAt(i).add(newConstraint);
//					newConstraintMapping.put(constr, newConstraint);
//					break;
//				}
//			}
//		}
//		
//		boolean retract = false;
//		for (int i = 0; i < this.constraintTypes.length && !retract; i++) {
//			Vector newCons = newToAdd.elementAt(i);
//			//	if there is something to insert...
//			if (!newCons.isEmpty()) {
//				Constraint[] newConsArray = newCons.toArray(new Constraint[newCons.size()]);
//				if (!this.constraintSolvers[i].addConstraints(newConsArray)) {
//					/* if (!allowInconsistencies) */ retract = true;
//				}
//				else {
//					added.set(i, newCons);
//				}
//			}
//		}
//		if (retract) {
//			for (int i = 0; i < added.size(); i++) {
//				Vector toRetract = added.elementAt(i);
//				if (!toRetract.isEmpty()) {
//					this.constraintSolvers[i].removeConstraints(toRetract.toArray(new Constraint[toRetract.size()]));
//					for (Constraint oldConstr : newConstraintMapping.keySet()) {
//						for (Constraint newConstr : toRetract) {
//							if (newConstraintMapping.get(oldConstr).equals(newConstr)) newConstraintMapping.remove(oldConstr);
//							break;
//						}
//					}
//				}
//			}
//			return false;
//		}
//		return true;
//	}
	

	@Override
	protected final void removeVariablesSub(Variable[] v) {
		HashMap> solvers = new HashMap>();
		for (Variable oneVar : v) {
			if (oneVar instanceof MultiVariable) {
				MultiVariable mv = (MultiVariable)oneVar;
				Variable[] intVars = mv.getInternalVariables();
				for (Variable intVar : intVars) {
					if (solvers.get(intVar.getConstraintSolver()) == null) solvers.put(intVar.getConstraintSolver(), new Vector());
					solvers.get(intVar.getConstraintSolver()).add(intVar);
				}
			}		
		}
		for (ConstraintSolver cs : solvers.keySet()) {
			logger.finest("Removing " + solvers.get(cs).size() + " internal variables (" + cs.getClass().getSimpleName() + ")");
			cs.removeVariables(solvers.get(cs).toArray(new Variable[solvers.get(cs).size()]));
		}
	}
		
	private Variable[][] createInternalVariables(int[] ingredients, int num) {
		Vector> ret = new Vector>();
		for (int k = 0; k < this.getConstraintSolvers().length; k++) {
			Variable[] oneType = this.getConstraintSolvers()[k].createVariables(ingredients[k]*num);
			logger.finest("Created " + ingredients[k]*num + " internal variables for " + this.getConstraintSolvers()[k].getClass().getSimpleName());
			for (int i = 0; i < num; i++) {
				Vector oneVar = null;
				if (ret.size() > i) oneVar = ret.elementAt(i);
				else {
					oneVar = new Vector();
					ret.add(oneVar);
				}
				for (int j = i*ingredients[k]; j < (i+1)*ingredients[k]; j++) {
					try { oneVar.add(oneType[j]); }
					catch(NullPointerException e) {
						throw new UnimplementedSubVariableException(this.getConstraintSolvers()[k]);
					}
				}
			}
		}
		Variable[][] retArray = new Variable[ret.size()][];
		for (int i = 0; i < num; i++) retArray[i] = ret.elementAt(i).toArray(new Variable[ret.elementAt(i).size()]);
		return retArray;
	}
	
	/**
	 * This method creates {@code num} {@link MultiVariable}s. The creation of internal variables is
	 * taken care of automatically, given a specification of the number of internal variables to create
	 * for each internal solver.
	 * @param ingredients The number of internal variables to create for each internal solver.   
	 * @param num The number of {@link MultiVariable}s for which internal variables are to be created.
	 * @param component The label (component) the created variables should be associated with.
	 * @return The {@link Variable}s for {@code num} {@link MultiVariable}s.
	 */
	protected Variable[] createVariablesSub(int[] ingredients, int num, String component) {
		Variable[][] internalVars = createInternalVariables(ingredients, num);
		Variable[] ret = (Variable[]) java.lang.reflect.Array.newInstance(this.variableType, num);
		HashMap> solvers2Constraints = new HashMap>();
		for (int i = 0; i < num; i++) {
			try {
				ret[i] = (Variable) this.variableType.getConstructor(new Class[] {ConstraintSolver.class, int.class, ConstraintSolver[].class, Variable[].class}).newInstance(new Object[] {this, this.IDs++, this.constraintSolvers, internalVars[i]});
				for (Variable internalVar : internalVars[i]) {
					if (component != null) {
						internalVar.getConstraintSolver().setComponent(component, internalVar);
						logger.finest("Set component of " + internalVar + " to " + component);
					}
					internalVar.setParentVariable((MultiVariable)ret[i]);
				}
				if (component != null) {
					ret[i].getConstraintSolver().setComponent(component, ret[i]);
					logger.finest("Set component of " + ret[i] + " to " + component);
//					for (Variable internalVar : internalVars[i]) {
//						internalVar.getConstraintSolver().setComponent(component, internalVar);
//						logger.finest("Set component of " + internalVar + " to " + component);
//					}
				}
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			if (ret[i] instanceof MultiVariable) {
				Constraint[] internalCons = ((MultiVariable)ret[i]).getInternalConstraints();
				if (internalCons != null) {
					logger.finest("Adding internal constraints for " + ret[i]);
					for (Constraint con : internalCons) {
						if (!solvers2Constraints.containsKey(con.getScope()[0].getConstraintSolver()))
							solvers2Constraints.put(con.getScope()[0].getConstraintSolver(), new Vector());
						solvers2Constraints.get(con.getScope()[0].getConstraintSolver()).add(con);
					}
				}
			}
		}
		for (Entry> es : solvers2Constraints.entrySet()) {
			//if we are called from addconstraintsnoprop, call addconsnoprop on the internals, otherwise call normal addconstraints
			if (!es.getKey().addConstraintsNoPropagation(es.getValue().toArray(new Constraint[es.getValue().size()])))
				throw new Error("Malformed internal constraints: " + es.getValue());
			else logger.finest("Added " + es.getValue().size() + " internal constraints to " + es.getKey().getClass().getSimpleName() + " (but DELAYED propagation)");
		}
		return ret;
	}

	@Override
	protected final Variable[] createVariablesSub(int num) {
		return createVariablesSub(ingredients, num, null);
	}

	@Override
	protected final Variable[] createVariablesSub(int num, String component) {
		return createVariablesSub(ingredients, num, component);
	}
	
	@Override
	public abstract boolean propagate();
	
	@Override
	protected final void removeConstraintsSub(Constraint[] c) {
		HashMap> internalCons = new HashMap>();
		//gather internal constraints
		for (Constraint con : c) {
			/**/
			if (con instanceof MultiConstraint) {
				MultiConstraint mc = (MultiConstraint)con;
				MultiVariable mv = (MultiVariable)mc.getScope()[0];
				for (ConstraintSolver cs : mv.getInternalConstraintSolvers()) {
					if (!internalCons.containsKey(cs)) internalCons.put(cs,new ArrayList());
					if (mc.getInternalConstraints() != null) for (Constraint c1 : mc.getInternalConstraints()) internalCons.get(cs).add(c1);
				}
			}
			/**/
		}
		
		//get rid of internal constraints
		for (ConstraintSolver cs : internalCons.keySet()) {
			cs.removeConstraints(internalCons.get(cs).toArray(new Constraint[internalCons.get(cs).size()]));
		}

		uninstantiateLiftedConstraints(c);
	}

	
	private void uninstantiateLiftedConstraints(Constraint[] c) {
		Vector> newToRemove = new Vector>();
		for (int i = 0; i < this.constraintTypes.length; i++) {
			newToRemove.add(new Vector());
		}
		for (Constraint constr : c) {
			Constraint newConstraint = newConstraintMapping.get(constr);
			if (newConstraint == null) throw new ConstraintNotFound(constr);
			for (int i = 0; i < this.constraintTypes.length; i++) {
				if (newConstraint.getClass().equals(this.constraintTypes[i])) {
					newToRemove.elementAt(i).add(newConstraint);
					break;
				}
			}
		}
		for (int i = 0; i < newToRemove.size(); i++) {
			Vector toRemove = newToRemove.elementAt(i);
			if (!toRemove.isEmpty()) {
				this.constraintSolvers[i].removeConstraints(toRemove.toArray(new Constraint[toRemove.size()]));
			}
		}
		for (Constraint constr : c) {
			newConstraintMapping.remove(constr);
		}
	}

	/**
	 * Get the {@link ConstraintSolver}s underlying this {@link MultiConstraintSolver}.
	 * @return The {@link ConstraintSolver}s underlying this {@link MultiConstraintSolver}.
	 */
	public ConstraintSolver[] getConstraintSolvers() {
		return this.constraintSolvers;
	}
	
	public void setConstraintSolver( int i, ConstraintSolver cSolver ) {
		this.constraintSolvers[i] = cSolver;
	}

	@Override
	public String getDescription() {
		String spacer = "";
		for (int i = 0; i < nesting; i++) spacer += spacing;
		String ret = spacer + "[" + this.getClass().getSimpleName() + " vars: [";
		ret += this.variableType.getSimpleName();
		ret += "] constraints: [";
		for (int i = 0; i < this.constraintTypes.length; i++) {
			ret += this.constraintTypes[i].getSimpleName();
			if (i != this.constraintTypes.length-1) ret += ",";
		}
		ret += "]";
		nesting++;
		for (ConstraintSolver cs : this.getConstraintSolvers()) ret += "\n" + cs.getDescription();
		nesting--;
		return ret + "]";
	}
	
	/**
	 * Get the hierarchy of {@link ConstraintSolver}s rooted in this {@link MultiConstraintSolver}.
	 * @return The hierarchy of {@link ConstraintSolver}s rooted in this {@link MultiConstraintSolver}.
	 */
	public DelegateTree getConstraintSolverHierarchy() {
		DelegateTree ret = new DelegateTree();
		ret.setRoot(this);
		ConstraintSolver[] myConstraintSolvers = this.getConstraintSolvers();
		for (int i = 0; i < myConstraintSolvers.length; i++) {
			String edgeLabel = i + " (" + this.hashCode() + ")";
			if (myConstraintSolvers[i] instanceof MultiConstraintSolver) {
				DelegateTree subtree = ((MultiConstraintSolver)myConstraintSolvers[i]).getConstraintSolverHierarchy();
				TreeUtils.addSubTree(ret, subtree, this, edgeLabel);
			}
			else {
				ret.addChild(edgeLabel, this, myConstraintSolvers[i]);
			}
		}
		return ret;
	}

	/**
	 * Get the {@link ConstraintSolver}s of a given type from this {@link MultiConstraintSolver}'s
	 * hierarchy of {@link ConstraintSolver}s.
	 * @param cl The type of {@link ConstraintSolver}s to get.
	 * @return All {@link ConstraintSolver}s of the given type in this {@link MultiConstraintSolver}'s
	 * hierarchy of {@link ConstraintSolver}s.
	 */
	public ConstraintSolver[] getConstraintSolversFromConstraintSolverHierarchy(Class cl) {
		ArrayList ret = new ArrayList();
		DelegateTree csTree = this.getConstraintSolverHierarchy();
		for (ConstraintSolver cs : csTree.getVertices()) {
			if (cs.getClass().equals(cl)) ret.add(cs);
		}
		return ret.toArray(new ConstraintSolver[ret.size()]);
	}
	
	/**
	 * Get all {@link ConstraintNetwork}s underlying {@link ConstraintSolver}s of a given type in
	 * this {@link MultiConstraintSolver}'s hierarchy of solvers.
	 * @param cl The type of {@link ConstraintNetwork} to get.
	 * @return All {@link ConstraintNetwork}s underlying {@link ConstraintSolver}s of a given type in
	 * this {@link MultiConstraintSolver}'s hierarchy of solvers.
	 */
	public ConstraintNetwork[] getConstraintNetworksFromSolverHierarchy(Class cl) {
		ArrayList ret = new ArrayList();
		DelegateTree csTree = this.getConstraintSolverHierarchy();
		for (ConstraintSolver cs : csTree.getVertices()) {
			if (cs.getClass().equals(cl)) ret.add(cs.getConstraintNetwork());
		}
		if (ret.size() == 0) throw new Error(this.getClass().getSimpleName() + " does not have a " + cl.getSimpleName() + " in its hierarchy");
		return ret.toArray(new ConstraintNetwork[ret.size()]);
	}
	
	/**
	 * Get a tree whose nodes are the constraint networks managed by the hierarchy of
	 * {@link ConstraintSolver}s underlying this {@link MultiConstraintSolver}.
	 * @return A tree whose nodes are the constraint networks managed by the hierarchy of
	 * {@link ConstraintSolver}s underlying this {@link MultiConstraintSolver}.
	 */
	public DelegateTree getConstraintNetworkHierarchy() {
		DelegateTree ret = new DelegateTree();
		ConstraintNetwork myCN = this.getConstraintNetwork();
		ret.setRoot(myCN);
		ConstraintSolver[] myConstraintSolvers = this.getConstraintSolvers();
		for (int i = 0; i < myConstraintSolvers.length; i++) {
			String edgeLabel = i + " (" + this.hashCode() + ")";
			if (myConstraintSolvers[i] instanceof MultiConstraintSolver) {
				DelegateTree subtree = ((MultiConstraintSolver)myConstraintSolvers[i]).getConstraintNetworkHierarchy();
				TreeUtils.addSubTree(ret, subtree, myCN, edgeLabel);
			}
			else {
				ret.addChild(edgeLabel, myCN, myConstraintSolvers[i].getConstraintNetwork());
			}
		}
		return ret;
	}
	
	public void failurePruning(int failure_time){

		
//		for(Constraint c: this.getConstraints()){
//			this.removeConstraint(c);
//		}
//		for(Variable v: this.getVariables()){
//			
//			this.removeVariable(v);
//		}
		
		this.removeConstraints(this.getConstraints());
		this.removeVariables(this.getVariables());
		
		
		
//		this.deplenish();
//		for(ConstraintSolver cs: this.constraintSolvers){
//			cs.deplenish();
//		}
		
//		for(Constraint c: this.theNetwork.getConstraints()){
//			this.theNetwork.removeConstraint(c);
//		}
//		for(Variable v: this.theNetwork.getVariables()){
//			this.theNetwork.removeVariable(v);
//		}
		
//		this.theNetwork= createConstraintNetwork();
		for(String k: this.components.keySet()){
			ArrayList list= this.components.get(k);
			list.clear();
		}
	}
	
	@Override
	public void registerValueChoiceFunctions() {
		// TODO Auto-generated method stub	
	}
	
	/**
	 * Draw a hierarchy of {@link ConstraintNetwork}s.
	 * @param tree The hierarchy of {@link ConstraintNetwork}s to draw.
	 */
	public static void drawConstraintNetworkHierarchy(DelegateTree tree) {
		new ConstraintNetworkHierarchyFrame(tree, "Constraint Network Hierarchy");
	}

	/**
	 * Draw a hierarchy of {@link ConstraintSolver}s.
	 * @param tree The hierarchy of {@link ConstraintSolver}s to draw.
	 */
	public static void drawConstraintSolverHierarchy(DelegateTree tree) {
		new ConstraintSolverHierarchyFrame(tree, "Constraint Solver Hierarchy");
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy