//@ skip if $model == "Apple Watch Series 3" # added by mark-jsc-stress-test.py
// Copyright 2008 the V8 project authors. All rights reserved.
// Copyright 1996 John Maloney and Mario Wolczko.

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


// This implementation of the DeltaBlue benchmark is derived
// from the Smalltalk implementation by John Maloney and Mario
// Wolczko. Some parts have been translated directly, whereas
// others have been modified more aggresively to make it feel
// more like a JavaScript program.

/**
 * A JavaScript implementation of the DeltaBlue constraint-solving
 * algorithm, as described in:
 *
 * "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver"
 *   Bjorn N. Freeman-Benson and John Maloney
 *   January 1990 Communications of the ACM,
 *   also available as University of Washington TR 89-08-06.
 *
 * Beware: this benchmark is written in a grotesque style where
 * the constraint model is built by side-effects from constructors.
 * I've kept it this way to avoid deviating too much from the original
 * implementation.
 */

// This thing is an evil hack that we use throughout this benchmark so that we can use this benchmark to
// stress our varargs implementation. We also have tests for specific features of the varargs code, but
// having a somewhat large-ish benchmark that uses varargs a lot (even if it's in a silly way) is great
// for shaking out bugs.
function args() {
    var array = [];
    for (var i = 0; i < arguments.length; ++i)
        array.push(arguments[i]);
    return array;
}


/* --- O b j e c t   M o d e l --- */

Object.prototype.inheritsFrom = function (shuper) {
  function Inheriter() { }
  Inheriter.prototype = shuper.prototype;
  this.prototype = new Inheriter(...args());
  this.superConstructor = shuper;
}

function OrderedCollection() {
  this.elms = new Array(...args());
}

OrderedCollection.prototype.add = function (elm) {
  this.elms.push(...args(elm));
}

OrderedCollection.prototype.at = function (index) {
  return this.elms[index];
}

OrderedCollection.prototype.size = function () {
  return this.elms.length;
}

OrderedCollection.prototype.removeFirst = function () {
  return this.elms.pop(...args());
}

OrderedCollection.prototype.remove = function (elm) {
  var index = 0, skipped = 0;
  for (var i = 0; i < this.elms.length; i++) {
    var value = this.elms[i];
    if (value != elm) {
      this.elms[index] = value;
      index++;
    } else {
      skipped++;
    }
  }
  for (var i = 0; i < skipped; i++)
    this.elms.pop(...args());
}

/* --- *
 * S t r e n g t h
 * --- */

/**
 * Strengths are used to measure the relative importance of constraints.
 * New strengths may be inserted in the strength hierarchy without
 * disrupting current constraints.  Strengths cannot be created outside
 * this class, so pointer comparison can be used for value comparison.
 */
function Strength(strengthValue, name) {
  this.strengthValue = strengthValue;
  this.name = name;
}

Strength.stronger = function (s1, s2) {
  return s1.strengthValue < s2.strengthValue;
}

Strength.weaker = function (s1, s2) {
  return s1.strengthValue > s2.strengthValue;
}

Strength.weakestOf = function (s1, s2) {
  return this.weaker(...args(s1, s2)) ? s1 : s2;
}

Strength.strongest = function (s1, s2) {
  return this.stronger(...args(s1, s2)) ? s1 : s2;
}

Strength.prototype.nextWeaker = function () {
  switch (this.strengthValue) {
    case 0: return Strength.WEAKEST;
    case 1: return Strength.WEAK_DEFAULT;
    case 2: return Strength.NORMAL;
    case 3: return Strength.STRONG_DEFAULT;
    case 4: return Strength.PREFERRED;
    case 5: return Strength.REQUIRED;
  }
}

// Strength constants.
Strength.REQUIRED        = new Strength(...args(0, "required"));
Strength.STONG_PREFERRED = new Strength(...args(1, "strongPreferred"));
Strength.PREFERRED       = new Strength(...args(2, "preferred"));
Strength.STRONG_DEFAULT  = new Strength(...args(3, "strongDefault"));
Strength.NORMAL          = new Strength(...args(4, "normal"));
Strength.WEAK_DEFAULT    = new Strength(...args(5, "weakDefault"));
Strength.WEAKEST         = new Strength(...args(6, "weakest"));

/* --- *
 * C o n s t r a i n t
 * --- */

/**
 * An abstract class representing a system-maintainable relationship
 * (or "constraint") between a set of variables. A constraint supplies
 * a strength instance variable; concrete subclasses provide a means
 * of storing the constrained variables and other information required
 * to represent a constraint.
 */
function Constraint(strength) {
  this.strength = strength;
}

/**
 * Activate this constraint and attempt to satisfy it.
 */
Constraint.prototype.addConstraint = function () {
  this.addToGraph(...args());
  planner.incrementalAdd(...args(this));
}

/**
 * Attempt to find a way to enforce this constraint. If successful,
 * record the solution, perhaps modifying the current dataflow
 * graph. Answer the constraint that this constraint overrides, if
 * there is one, or nil, if there isn't.
 * Assume: I am not already satisfied.
 */
Constraint.prototype.satisfy = function (mark) {
  this.chooseMethod(...args(mark));
  if (!this.isSatisfied(...args())) {
    if (this.strength == Strength.REQUIRED)
      alert(...args("Could not satisfy a required constraint!"));
    return null;
  }
  this.markInputs(...args(mark));
  var out = this.output(...args());
  var overridden = out.determinedBy;
  if (overridden != null) overridden.markUnsatisfied(...args());
  out.determinedBy = this;
  if (!planner.addPropagate(...args(this, mark)))
    alert(...args("Cycle encountered"));
  out.mark = mark;
  return overridden;
}

Constraint.prototype.destroyConstraint = function () {
  if (this.isSatisfied(...args())) planner.incrementalRemove(...args(this));
  else this.removeFromGraph(...args());
}

/**
 * Normal constraints are not input constraints.  An input constraint
 * is one that depends on external state, such as the mouse, the
 * keybord, a clock, or some arbitraty piece of imperative code.
 */
Constraint.prototype.isInput = function () {
  return false;
}

/* --- *
 * U n a r y   C o n s t r a i n t
 * --- */

/**
 * Abstract superclass for constraints having a single possible output
 * variable.
 */
function UnaryConstraint(v, strength) {
  UnaryConstraint.superConstructor.call(this, strength);
  this.myOutput = v;
  this.satisfied = false;
  this.addConstraint(...args());
}

UnaryConstraint.inheritsFrom(...args(Constraint));

/**
 * Adds this constraint to the constraint graph
 */
UnaryConstraint.prototype.addToGraph = function () {
  this.myOutput.addConstraint(...args(this));
  this.satisfied = false;
}

/**
 * Decides if this constraint can be satisfied and records that
 * decision.
 */
UnaryConstraint.prototype.chooseMethod = function (mark) {
  this.satisfied = (this.myOutput.mark != mark)
    && Strength.stronger(...args(this.strength, this.myOutput.walkStrength));
}

/**
 * Returns true if this constraint is satisfied in the current solution.
 */
UnaryConstraint.prototype.isSatisfied = function () {
  return this.satisfied;
}

UnaryConstraint.prototype.markInputs = function (mark) {
  // has no inputs
}

/**
 * Returns the current output variable.
 */
UnaryConstraint.prototype.output = function () {
  return this.myOutput;
}

/**
 * Calculate the walkabout strength, the stay flag, and, if it is
 * 'stay', the value for the current output of this constraint. Assume
 * this constraint is satisfied.
 */
UnaryConstraint.prototype.recalculate = function () {
  this.myOutput.walkStrength = this.strength;
  this.myOutput.stay = !this.isInput(...args());
  if (this.myOutput.stay) this.execute(...args()); // Stay optimization
}

/**
 * Records that this constraint is unsatisfied
 */
UnaryConstraint.prototype.markUnsatisfied = function () {
  this.satisfied = false;
}

UnaryConstraint.prototype.inputsKnown = function () {
  return true;
}

UnaryConstraint.prototype.removeFromGraph = function () {
  if (this.myOutput != null) this.myOutput.removeConstraint(...args(this));
  this.satisfied = false;
}

/* --- *
 * S t a y   C o n s t r a i n t
 * --- */

/**
 * Variables that should, with some level of preference, stay the same.
 * Planners may exploit the fact that instances, if satisfied, will not
 * change their output during plan execution.  This is called "stay
 * optimization".
 */
function StayConstraint(v, str) {
  StayConstraint.superConstructor.call(this, v, str);
}

StayConstraint.inheritsFrom(...args(UnaryConstraint));

StayConstraint.prototype.execute = function () {
  // Stay constraints do nothing
}

/* --- *
 * E d i t   C o n s t r a i n t
 * --- */

/**
 * A unary input constraint used to mark a variable that the client
 * wishes to change.
 */
function EditConstraint(v, str) {
  EditConstraint.superConstructor.call(this, v, str);
}

EditConstraint.inheritsFrom(...args(UnaryConstraint));

/**
 * Edits indicate that a variable is to be changed by imperative code.
 */
EditConstraint.prototype.isInput = function () {
  return true;
}

EditConstraint.prototype.execute = function () {
  // Edit constraints do nothing
}

/* --- *
 * B i n a r y   C o n s t r a i n t
 * --- */

var Direction = new Object(...args());
Direction.NONE     = 0;
Direction.FORWARD  = 1;
Direction.BACKWARD = -1;

/**
 * Abstract superclass for constraints having two possible output
 * variables.
 */
function BinaryConstraint(var1, var2, strength) {
  BinaryConstraint.superConstructor.call(this, strength);
  this.v1 = var1;
  this.v2 = var2;
  this.direction = Direction.NONE;
  this.addConstraint(...args());
}

BinaryConstraint.inheritsFrom(...args(Constraint));

/**
 * Decides if this constraint can be satisfied and which way it
 * should flow based on the relative strength of the variables related,
 * and record that decision.
 */
BinaryConstraint.prototype.chooseMethod = function (mark) {
  if (this.v1.mark == mark) {
    this.direction = (this.v2.mark != mark && Strength.stronger(...args(this.strength, this.v2.walkStrength)))
      ? Direction.FORWARD
      : Direction.NONE;
  }
  if (this.v2.mark == mark) {
    this.direction = (this.v1.mark != mark && Strength.stronger(...args(this.strength, this.v1.walkStrength)))
      ? Direction.BACKWARD
      : Direction.NONE;
  }
  if (Strength.weaker(...args(this.v1.walkStrength, this.v2.walkStrength))) {
    this.direction = Strength.stronger(...args(this.strength, this.v1.walkStrength))
      ? Direction.BACKWARD
      : Direction.NONE;
  } else {
    this.direction = Strength.stronger(...args(this.strength, this.v2.walkStrength))
      ? Direction.FORWARD
      : Direction.BACKWARD
  }
}

/**
 * Add this constraint to the constraint graph
 */
BinaryConstraint.prototype.addToGraph = function () {
  this.v1.addConstraint(...args(this));
  this.v2.addConstraint(...args(this));
  this.direction = Direction.NONE;
}

/**
 * Answer true if this constraint is satisfied in the current solution.
 */
BinaryConstraint.prototype.isSatisfied = function () {
  return this.direction != Direction.NONE;
}

/**
 * Mark the input variable with the given mark.
 */
BinaryConstraint.prototype.markInputs = function (mark) {
  this.input(...args()).mark = mark;
}

/**
 * Returns the current input variable
 */
BinaryConstraint.prototype.input = function () {
  return (this.direction == Direction.FORWARD) ? this.v1 : this.v2;
}

/**
 * Returns the current output variable
 */
BinaryConstraint.prototype.output = function () {
  return (this.direction == Direction.FORWARD) ? this.v2 : this.v1;
}

/**
 * Calculate the walkabout strength, the stay flag, and, if it is
 * 'stay', the value for the current output of this
 * constraint. Assume this constraint is satisfied.
 */
BinaryConstraint.prototype.recalculate = function () {
  var ihn = this.input(...args()), out = this.output(...args());
  out.walkStrength = Strength.weakestOf(...args(this.strength, ihn.walkStrength));
  out.stay = ihn.stay;
  if (out.stay) this.execute(...args());
}

/**
 * Record the fact that this constraint is unsatisfied.
 */
BinaryConstraint.prototype.markUnsatisfied = function () {
  this.direction = Direction.NONE;
}

BinaryConstraint.prototype.inputsKnown = function (mark) {
  var i = this.input(...args());
  return i.mark == mark || i.stay || i.determinedBy == null;
}

BinaryConstraint.prototype.removeFromGraph = function () {
  if (this.v1 != null) this.v1.removeConstraint(...args(this));
  if (this.v2 != null) this.v2.removeConstraint(...args(this));
  this.direction = Direction.NONE;
}

/* --- *
 * S c a l e   C o n s t r a i n t
 * --- */

/**
 * Relates two variables by the linear scaling relationship: "v2 =
 * (v1 * scale) + offset". Either v1 or v2 may be changed to maintain
 * this relationship but the scale factor and offset are considered
 * read-only.
 */
function ScaleConstraint(src, scale, offset, dest, strength) {
  this.direction = Direction.NONE;
  this.scale = scale;
  this.offset = offset;
  ScaleConstraint.superConstructor.call(this, src, dest, strength);
}

ScaleConstraint.inheritsFrom(...args(BinaryConstraint));

/**
 * Adds this constraint to the constraint graph.
 */
ScaleConstraint.prototype.addToGraph = function () {
  ScaleConstraint.superConstructor.prototype.addToGraph.call(this);
  this.scale.addConstraint(...args(this));
  this.offset.addConstraint(...args(this));
}

ScaleConstraint.prototype.removeFromGraph = function () {
  ScaleConstraint.superConstructor.prototype.removeFromGraph.call(this);
  if (this.scale != null) this.scale.removeConstraint(...args(this));
  if (this.offset != null) this.offset.removeConstraint(...args(this));
}

ScaleConstraint.prototype.markInputs = function (mark) {
  ScaleConstraint.superConstructor.prototype.markInputs.call(this, mark);
  this.scale.mark = this.offset.mark = mark;
}

/**
 * Enforce this constraint. Assume that it is satisfied.
 */
ScaleConstraint.prototype.execute = function () {
  if (this.direction == Direction.FORWARD) {
    this.v2.value = this.v1.value * this.scale.value + this.offset.value;
  } else {
    this.v1.value = (this.v2.value - this.offset.value) / this.scale.value;
  }
}

/**
 * Calculate the walkabout strength, the stay flag, and, if it is
 * 'stay', the value for the current output of this constraint. Assume
 * this constraint is satisfied.
 */
ScaleConstraint.prototype.recalculate = function () {
  var ihn = this.input(...args()), out = this.output(...args());
  out.walkStrength = Strength.weakestOf(...args(this.strength, ihn.walkStrength));
  out.stay = ihn.stay && this.scale.stay && this.offset.stay;
  if (out.stay) this.execute(...args());
}

/* --- *
 * E q u a l i t  y   C o n s t r a i n t
 * --- */

/**
 * Constrains two variables to have the same value.
 */
function EqualityConstraint(var1, var2, strength) {
  EqualityConstraint.superConstructor.call(this, var1, var2, strength);
}

EqualityConstraint.inheritsFrom(...args(BinaryConstraint));

/**
 * Enforce this constraint. Assume that it is satisfied.
 */
EqualityConstraint.prototype.execute = function () {
  this.output(...args()).value = this.input(...args()).value;
}

/* --- *
 * V a r i a b l e
 * --- */

/**
 * A constrained variable. In addition to its value, it maintain the
 * structure of the constraint graph, the current dataflow graph, and
 * various parameters of interest to the DeltaBlue incremental
 * constraint solver.
 **/
function Variable(name, initialValue) {
  this.value = initialValue || 0;
  this.constraints = new OrderedCollection(...args());
  this.determinedBy = null;
  this.mark = 0;
  this.walkStrength = Strength.WEAKEST;
  this.stay = true;
  this.name = name;
}

/**
 * Add the given constraint to the set of all constraints that refer
 * this variable.
 */
Variable.prototype.addConstraint = function (c) {
  this.constraints.add(...args(c));
}

/**
 * Removes all traces of c from this variable.
 */
Variable.prototype.removeConstraint = function (c) {
  this.constraints.remove(...args(c));
  if (this.determinedBy == c) this.determinedBy = null;
}

/* --- *
 * P l a n n e r
 * --- */

/**
 * The DeltaBlue planner
 */
function Planner() {
  this.currentMark = 0;
}

/**
 * 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.
 */
Planner.prototype.incrementalAdd = function (c) {
  var mark = this.newMark(...args());
  var overridden = c.satisfy(...args(mark));
  while (overridden != null)
    overridden = overridden.satisfy(...args(mark));
}

/**
 * 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.
 */
Planner.prototype.incrementalRemove = function (c) {
  var out = c.output(...args());
  c.markUnsatisfied(...args());
  c.removeFromGraph(...args());
  var unsatisfied = this.removePropagateFrom(...args(out));
  var strength = Strength.REQUIRED;
  do {
    for (var i = 0; i < unsatisfied.size(...args()); i++) {
      var u = unsatisfied.at(...args(i));
      if (u.strength == strength)
        this.incrementalAdd(...args(u));
    }
    strength = strength.nextWeaker(...args());
  } while (strength != Strength.WEAKEST);
}

/**
 * Select a previously unused mark value.
 */
Planner.prototype.newMark = function () {
  return ++this.currentMark;
}

/**
 * Extract a plan for resatisfaction starting from the given source
 * constraints, usually a set of input constraints. This method
 * assumes that stay optimization is desired; the plan will contain
 * only constraints whose output variables are not stay. Constraints
 * that do no computation, such as stay and edit constraints, are
 * not included in the plan.
 * Details: The outputs of a constraint are marked when it is added
 * to the plan under construction. A constraint may be appended to
 * the plan when all its input variables are known. A variable is
 * known if either a) the variable is marked (indicating that has
 * been computed by a constraint appearing earlier in the plan), b)
 * the variable is 'stay' (i.e. it is a constant at plan execution
 * time), or c) the variable is not determined by any
 * constraint. The last provision is for past states of history
 * variables, which are not stay but which are also not computed by
 * any constraint.
 * Assume: sources are all satisfied.
 */
Planner.prototype.makePlan = function (sources) {
  var mark = this.newMark(...args());
  var plan = new Plan(...args());
  var todo = sources;
  while (todo.size(...args()) > 0) {
    var c = todo.removeFirst(...args());
    if (c.output(...args()).mark != mark && c.inputsKnown(...args(mark))) {
      plan.addConstraint(...args(c));
      c.output(...args()).mark = mark;
      this.addConstraintsConsumingTo(...args(c.output(...args()), todo));
    }
  }
  return plan;
}

/**
 * Extract a plan for resatisfying starting from the output of the
 * given constraints, usually a set of input constraints.
 */
Planner.prototype.extractPlanFromConstraints = function (constraints) {
  var sources = new OrderedCollection(...args());
  for (var i = 0; i < constraints.size(...args()); i++) {
    var c = constraints.at(...args(i));
    if (c.isInput(...args()) && c.isSatisfied(...args()))
      // not in plan already and eligible for inclusion
      sources.add(...args(c));
  }
  return this.makePlan(...args(sources));
}

/**
 * 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.
 */
Planner.prototype.addPropagate = function (c, mark) {
  var todo = new OrderedCollection(...args());
  todo.add(...args(c));
  while (todo.size(...args()) > 0) {
    var d = todo.removeFirst(...args());
    if (d.output(...args()).mark == mark) {
      this.incrementalRemove(...args(c));
      return false;
    }
    d.recalculate(...args());
    this.addConstraintsConsumingTo(...args(d.output(...args()), todo));
  }
  return true;
}


/**
 * Update the walkabout strengths and stay flags of all variables
 * downstream of the given constraint. Answer a collection of
 * unsatisfied constraints sorted in order of decreasing strength.
 */
Planner.prototype.removePropagateFrom = function (out) {
  out.determinedBy = null;
  out.walkStrength = Strength.WEAKEST;
  out.stay = true;
  var unsatisfied = new OrderedCollection(...args());
  var todo = new OrderedCollection(...args());
  todo.add(...args(out));
  while (todo.size(...args()) > 0) {
    var v = todo.removeFirst(...args());
    for (var i = 0; i < v.constraints.size(...args()); i++) {
      var c = v.constraints.at(...args(i));
      if (!c.isSatisfied(...args()))
        unsatisfied.add(...args(c));
    }
    var determining = v.determinedBy;
    for (var i = 0; i < v.constraints.size(...args()); i++) {
      var next = v.constraints.at(...args(i));
      if (next != determining && next.isSatisfied(...args())) {
        next.recalculate(...args());
        todo.add(...args(next.output(...args())));
      }
    }
  }
  return unsatisfied;
}

Planner.prototype.addConstraintsConsumingTo = function (v, coll) {
  var determining = v.determinedBy;
  var cc = v.constraints;
  for (var i = 0; i < cc.size(...args()); i++) {
    var c = cc.at(...args(i));
    if (c != determining && c.isSatisfied(...args()))
      coll.add(...args(c));
  }
}

/* --- *
 * P l a n
 * --- */

/**
 * A Plan is an ordered list of constraints to be executed in sequence
 * to resatisfy all currently satisfiable constraints in the face of
 * one or more changing inputs.
 */
function Plan() {
  this.v = new OrderedCollection(...args());
}

Plan.prototype.addConstraint = function (c) {
  this.v.add(...args(c));
}

Plan.prototype.size = function () {
  return this.v.size(...args());
}

Plan.prototype.constraintAt = function (index) {
  return this.v.at(...args(index));
}

Plan.prototype.execute = function () {
  for (var i = 0; i < this.size(...args()); i++) {
    var c = this.constraintAt(...args(i));
    c.execute(...args());
  }
}

/* --- *
 * M a i n
 * --- */

/**
 * This is the standard DeltaBlue benchmark. A long chain of equality
 * constraints is constructed with a stay constraint on one end. An
 * edit constraint is then added to the opposite end and the time is
 * measured for adding and removing this constraint, and extracting
 * and executing a constraint satisfaction plan. There are two cases.
 * In case 1, the added constraint is stronger than the stay
 * constraint and values must propagate down the entire length of the
 * chain. In case 2, the added constraint is weaker than the stay
 * constraint so it cannot be accomodated. The cost in this case is,
 * of course, very low. Typical situations lie somewhere between these
 * two extremes.
 */
function chainTest(n) {
  planner = new Planner(...args());
  var prev = null, first = null, last = null;

  // Build chain of n equality constraints
  for (var i = 0; i <= n; i++) {
    var name = "v" + i;
    var v = new Variable(...args(name));
    if (prev != null)
      new EqualityConstraint(...args(prev, v, Strength.REQUIRED));
    if (i == 0) first = v;
    if (i == n) last = v;
    prev = v;
  }

  new StayConstraint(...args(last, Strength.STRONG_DEFAULT));
  var edit = new EditConstraint(...args(first, Strength.PREFERRED));
  var edits = new OrderedCollection(...args());
  edits.add(...args(edit));
  var plan = planner.extractPlanFromConstraints(...args(edits));
  for (var i = 0; i < 100; i++) {
    first.value = i;
    plan.execute(...args());
    if (last.value != i)
      alert(...args("Chain test failed."));
  }
}

/**
 * This test constructs a two sets of variables related to each
 * other by a simple linear transformation (scale and offset). The
 * time is measured to change a variable on either side of the
 * mapping and to change the scale and offset factors.
 */
function projectionTest(n) {
  planner = new Planner(...args());
  var scale = new Variable(...args("scale", 10));
  var offset = new Variable(...args("offset", 1000));
  var src = null, dst = null;

  var dests = new OrderedCollection(...args());
  for (var i = 0; i < n; i++) {
    src = new Variable(...args("src" + i, i));
    dst = new Variable(...args("dst" + i, i));
    dests.add(...args(dst));
    new StayConstraint(...args(src, Strength.NORMAL));
    new ScaleConstraint(...args(src, scale, offset, dst, Strength.REQUIRED));
  }

  change(...args(src, 17));
  if (dst.value != 1170) alert(...args("Projection 1 failed"));
  change(...args(dst, 1050));
  if (src.value != 5) alert(...args("Projection 2 failed"));
  change(...args(scale, 5));
  for (var i = 0; i < n - 1; i++) {
    if (dests.at(...args(i)).value != i * 5 + 1000)
      alert(...args("Projection 3 failed"));
  }
  change(...args(offset, 2000));
  for (var i = 0; i < n - 1; i++) {
    if (dests.at(...args(i)).value != i * 5 + 2000)
      alert(...args("Projection 4 failed"));
  }
}

function change(v, newValue) {
  var edit = new EditConstraint(...args(v, Strength.PREFERRED));
  var edits = new OrderedCollection(...args());
  edits.add(...args(edit));
  var plan = planner.extractPlanFromConstraints(...args(edits));
  for (var i = 0; i < 10; i++) {
    v.value = newValue;
    plan.execute(...args());
  }
  edit.destroyConstraint(...args());
}

// Global variable holding the current planner.
var planner = null;

function deltaBlue() {
  chainTest(...args(25));
  projectionTest(...args(25));
}

for (var i = 0; i < 5; ++i)
    deltaBlue(...args());
