package edu.neu.ccs.evergreen.model; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import edu.neu.ccs.evergreen.exception.ContradictionException; /** * Tracks all of the assignments that have been made. */ public class Assignments { /** * The weight unsatisfied by this assignment. */ public int unsatisfiedWeight; private Map assignments = new HashMap(); private LinkedList assignmentOrder = new LinkedList(); private LinkedList decisions = new LinkedList(); /** * @see java.lang.Object#clone() */ public Assignments clone() { Assignments newAssignments = new Assignments(); newAssignments.assignments.putAll(assignments); newAssignments.decisions.addAll(decisions); newAssignments.assignmentOrder.addAll(assignmentOrder); newAssignments.unsatisfiedWeight = unsatisfiedWeight; return newAssignments; } /** * Add a new assignment. * * @param assignment * Assignment to add * @return True if assignment was new; false otherwise */ public boolean addAssignment(Assignment assignment) { Assignment oldAssignment = assignments.put(assignment.getVariable(), assignment); if (oldAssignment != null) { assignments.put(assignment.getVariable(), oldAssignment); if (oldAssignment.getValue() != assignment.getValue()) { throw new ContradictionException(assignment.getVariable() + " caused a contradiction", assignment .getForcingConstraint()); } return true; } if (assignment.getDecision()) { decisions.add(assignment); // TODO: Convert to aspect Stats.decide++; } else { // TODO: Convert to aspect Stats.unitPropagate++; } assignmentOrder.add(assignment); return true; } /** * Add all of the assignments from another assignment instance to this one. * * @param assignments * Assignments to add */ public void addAssignments(Assignments assignments) { for (Assignment assignment : assignments.assignments.values()) { addAssignment(assignment); } } /** * Does the given variable have an assignment? * * @param variable * Variable to check * @return True if it is assigned. */ public boolean assigned(int variable) { return assignments.containsKey(variable); } /** * How many variables have been given an assignment. * * @return # of variables assigned */ public int size() { return assignments.size(); } /** * Remove an assignment from the system. * * @return Removed assignment */ public Assignment removeAnAssignment() { Integer variable = assignments.keySet().iterator().next(); return assignments.remove(variable); } /** * Return an ordered list of decisions that were made. * * @return Decision assignments */ public List getDecisions() { return Collections.unmodifiableList(decisions); } /** * Return the last decision that was made. * * @return Last decision assignment */ public Assignment getLastDecision() { return decisions.getLast(); } /** * Return assignment for a variable. * * @param variable * Variable * @return Assignment to variable */ public Assignment getAssignment(int variable) { return assignments.get(variable); } /** * Generate the assignment this instance represents in the standard output * format. * * @param maxVariable * Maximum variable to include in output * @return Assignment string */ public String solutionString(int maxVariable) { StringBuffer result = new StringBuffer(); for (int variable = 1; variable <= maxVariable; variable++) { Assignment assignment = getAssignment(variable); if ((variable % 10) != 1) { result.append(" "); } if (assignment.getValue() == 0) { result.append("!"); } result.append("v"); result.append(assignment.getVariable()); if ((variable % 10) == 0) { result.append("\n"); } } if ((maxVariable % 10) != 0) { result.append("\n"); } return result.toString(); } /** * @see java.lang.Object#toString() */ @Override public String toString() { StringBuffer result = new StringBuffer(); for (Assignment assignment : assignments.values()) { if (result.length() > 0) { result.append(", "); } result.append(assignment.toString()); } return result.toString(); } /** * Return all of the assignments made. * @return List of assignment */ public List getAssignments() { return assignmentOrder; } }