// Entry point for retracting a constraint. Remove the given // constraint and incrementally update the dataflow graph. // Details: Retracting the given constraint may allow some currently // unsatisfiable downstream constraint to be satisfied. We therefore collect // a list of unsatisfied downstream constraints and attempt to // satisfy each one in turn. This list is traversed by constraint // strength, strongest first, as a heuristic for avoiding // unnecessarily adding and then overriding weak constraints. // Assume: c is satisfied. // public void incrementalRemove(Constraint c) { Variable outvar = c.output(); c.markUnsatisfied(); c.removeFromGraph(); ArrayList unsatisfied = removePropagateFrom(outvar); Strength strength = Strength.required; do { for (int i = 0; i < unsatisfied.Count; ++i) { Constraint u = (Constraint)unsatisfied[i]; if (u.strength == strength) incrementalAdd(u); } strength = strength.nextWeaker(); } while (strength != Strength.weakest); }
// Recompute the walkabout strengths and stay flags of all variables // downstream of the given constraint and recompute the actual // values of all variables whose stay flag is true. If a cycle is // detected, remove the given constraint and answer // false. Otherwise, answer true. // Details: Cycles are detected when a marked variable is // encountered downstream of the given constraint. The sender is // assumed to have marked the inputs of the given constraint with // the given mark. Thus, encountering a marked node downstream of // the output constraint means that there is a path from the // constraint's output to one of its inputs. // public Boolean addPropagate(Constraint c, int mark) { ArrayList todo = new ArrayList(); todo.Add(c); while (!(todo.Count == 0)) { #if USE_STACK Constraint d = (Constraint)todo[todo.Count - 1]; todo.RemoveAt(todo.Count - 1); #else Constraint d= (Constraint)todo[0]; todo.RemoveAt(0); #endif if (d.output().mark == mark) { incrementalRemove(c); return false; } d.recalculate(); addConstraintsConsumingTo(d.output(), todo); } return true; }
// Attempt to satisfy the given constraint and, if successful, // incrementally update the dataflow graph. Details: If satifying // the constraint is successful, it may override a weaker constraint // on its output. The algorithm attempts to resatisfy that // constraint using some other method. This process is repeated // until either a) it reaches a variable that was not previously // determined by any constraint or b) it reaches a constraint that // is too weak to be satisfied using any of its methods. The // variables of constraints that have been processed are marked with // a unique mark value so that we know where we've been. This allows // the algorithm to avoid getting into an infinite loop even if the // constraint graph has an inadvertent cycle. // public void incrementalAdd(Constraint c) { int mark = newMark(); Constraint overridden = c.satisfy(mark); while (overridden != null) { overridden = overridden.satisfy(mark); } }
public void addConstraint(Constraint c) { _v.Add(c); }
// Remove all traces of c from this variable. public void removeConstraint(Constraint c) { constraints.Remove(c); if (determinedBy == c) determinedBy = null; }
// Add the given constraint to the set of all constraints that refer to me. public void addConstraint(Constraint c) { constraints.Add(c); }
public String name; // a symbolic name for reporting purposes private Variable(String name, int initialValue, Strength walkStrength, int nconstraints) { value = initialValue; constraints = new ArrayList(nconstraints); determinedBy = null; mark = 0; this.walkStrength = walkStrength; stay = true; this.name = name; }