// Copyright 2011 Google Inc. All Rights Reserved.
// Copyright 1996 John Maloney and Mario Wolczko
//
// This file is part of GNU Smalltalk.
//
// GNU Smalltalk 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, or (at your option) any later version.
//
// GNU Smalltalk 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
// GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
// Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Translated first from Smalltalk to JavaScript, and finally to
// Dart by Google 2008-2010.

/**
 * A Dart 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.
 */

main() {
  new DeltaBlue().run();
}

/// Benchmark class required to report results.
class DeltaBlue {
  void run() {
    chainTest(100);
    projectionTest(100);
  }
}

/**
 * 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 == can be used for value comparison.
 */
class Strength {
  final int value;
  final String name;

  const Strength(this.value, this.name);

  Strength nextWeaker() => const <Strength>[
        STRONG_PREFERRED,
        PREFERRED,
        STRONG_DEFAULT,
        NORMAL,
        WEAK_DEFAULT,
        WEAKEST
      ][value];

  static bool stronger(Strength s1, Strength s2) {
    return s1.value < s2.value;
  }

  static bool weaker(Strength s1, Strength s2) {
    return s1.value > s2.value;
  }

  static Strength weakest(Strength s1, Strength s2) {
    return weaker(s1, s2) ? s1 : s2;
  }

  static Strength strongest(Strength s1, Strength s2) {
    return stronger(s1, s2) ? s1 : s2;
  }
}

// Compile time computed constants.
const REQUIRED = const Strength(0, "required");
const STRONG_PREFERRED = const Strength(1, "strongPreferred");
const PREFERRED = const Strength(2, "preferred");
const STRONG_DEFAULT = const Strength(3, "strongDefault");
const NORMAL = const Strength(4, "normal");
const WEAK_DEFAULT = const Strength(5, "weakDefault");
const WEAKEST = const Strength(6, "weakest");

abstract class Constraint {
  final Strength strength;

  const Constraint(this.strength);

  bool isSatisfied();
  void markUnsatisfied();
  void addToGraph();
  void removeFromGraph();
  void chooseMethod(int mark);
  void markInputs(int mark);
  bool inputsKnown(int mark);
  Variable output();
  void execute();
  void recalculate();

  /// Activate this constraint and attempt to satisfy it.
  void addConstraint() {
    addToGraph();
    planner.incrementalAdd(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? satisfy(mark) {
    chooseMethod(mark);
    if (!isSatisfied()) {
      if (strength == REQUIRED) {
        print("Could not satisfy a required constraint!");
      }
      return null;
    }
    markInputs(mark);
    Variable out = output();
    Constraint? overridden = out.determinedBy;
    if (overridden != null) overridden.markUnsatisfied();
    out.determinedBy = this;
    if (!planner.addPropagate(this, mark)) print("Cycle encountered");
    out.mark = mark;
    return overridden;
  }

  void destroyConstraint() {
    if (isSatisfied()) planner.incrementalRemove(this);
    removeFromGraph();
  }

  /**
   * Normal constraints are not input constraints.  An input constraint
   * is one that depends on external state, such as the mouse, the
   * keyboard, a clock, or some arbitrary piece of imperative code.
   */
  bool isInput() => false;
}

/**
 * Abstract superclass for constraints having a single possible output variable.
 */
abstract class UnaryConstraint extends Constraint {
  final Variable myOutput;
  bool satisfied = false;

  UnaryConstraint(this.myOutput, Strength strength) : super(strength) {
    addConstraint();
  }

  /// Adds this constraint to the constraint graph
  void addToGraph() {
    myOutput.addConstraint(this);
    satisfied = false;
  }

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

  /// Returns true if this constraint is satisfied in the current solution.
  bool isSatisfied() => satisfied;

  void markInputs(int mark) {
    // has no inputs.
  }

  /// Returns the current output variable.
  Variable output() => 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.
   */
  void recalculate() {
    myOutput.walkStrength = strength;
    myOutput.stay = !isInput();
    if (myOutput.stay) execute(); // Stay optimization.
  }

  /// Records that this constraint is unsatisfied.
  void markUnsatisfied() {
    satisfied = false;
  }

  bool inputsKnown(int mark) => true;

  void removeFromGraph() {
    if (myOutput != null) myOutput.removeConstraint(this);
    satisfied = false;
  }
}

/**
 * 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".
 */
class StayConstraint extends UnaryConstraint {
  StayConstraint(Variable v, Strength str) : super(v, str);

  void execute() {
    // Stay constraints do nothing.
  }
}

/**
 * A unary input constraint used to mark a variable that the client
 * wishes to change.
 */
class EditConstraint extends UnaryConstraint {
  EditConstraint(Variable v, Strength str) : super(v, str);

  /// Edits indicate that a variable is to be changed by imperative code.
  bool isInput() => true;

  void execute() {
    // Edit constraints do nothing.
  }
}

// Directions.
const int NONE = 1;
const int FORWARD = 2;
const int BACKWARD = 0;

/**
 * Abstract superclass for constraints having two possible output
 * variables.
 */
abstract class BinaryConstraint extends Constraint {
  Variable v1;
  Variable v2;
  int direction = NONE;

  BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {
    addConstraint();
  }

  /**
   * 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.
   */
  void chooseMethod(int mark) {
    if (v1.mark == mark) {
      direction =
          (v2.mark != mark && Strength.stronger(strength, v2.walkStrength))
              ? FORWARD
              : NONE;
    }
    if (v2.mark == mark) {
      direction =
          (v1.mark != mark && Strength.stronger(strength, v1.walkStrength))
              ? BACKWARD
              : NONE;
    }
    if (Strength.weaker(v1.walkStrength, v2.walkStrength)) {
      direction =
          Strength.stronger(strength, v1.walkStrength) ? BACKWARD : NONE;
    } else {
      direction =
          Strength.stronger(strength, v2.walkStrength) ? FORWARD : BACKWARD;
    }
  }

  /// Add this constraint to the constraint graph.
  void addToGraph() {
    v1.addConstraint(this);
    v2.addConstraint(this);
    direction = NONE;
  }

  /// Answer true if this constraint is satisfied in the current solution.
  bool isSatisfied() => direction != NONE;

  /// Mark the input variable with the given mark.
  void markInputs(int mark) {
    input().mark = mark;
  }

  /// Returns the current input variable
  Variable input() => direction == FORWARD ? v1 : v2;

  /// Returns the current output variable.
  Variable output() => direction == FORWARD ? v2 : 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.
   */
  void recalculate() {
    Variable ihn = input(), out = output();
    out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
    out.stay = ihn.stay;
    if (out.stay) execute();
  }

  /// Record the fact that this constraint is unsatisfied.
  void markUnsatisfied() {
    direction = NONE;
  }

  bool inputsKnown(int mark) {
    Variable i = input();
    return i.mark == mark || i.stay || i.determinedBy == null;
  }

  void removeFromGraph() {
    if (v1 != null) v1.removeConstraint(this);
    if (v2 != null) v2.removeConstraint(this);
    direction = NONE;
  }
}

/**
 * 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.
 */

class ScaleConstraint extends BinaryConstraint {
  final Variable scale;
  final Variable offset;

  ScaleConstraint(
      Variable src, this.scale, this.offset, Variable dest, Strength strength)
      : super(src, dest, strength);

  /// Adds this constraint to the constraint graph.
  void addToGraph() {
    super.addToGraph();
    scale.addConstraint(this);
    offset.addConstraint(this);
  }

  void removeFromGraph() {
    super.removeFromGraph();
    if (scale != null) scale.removeConstraint(this);
    if (offset != null) offset.removeConstraint(this);
  }

  void markInputs(int mark) {
    super.markInputs(mark);
    scale.mark = offset.mark = mark;
  }

  /// Enforce this constraint. Assume that it is satisfied.
  void execute() {
    if (direction == FORWARD) {
      v2.value = v1.value * scale.value + offset.value;
    } else {
      v1.value = (v2.value - offset.value) ~/ 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.
   */
  void recalculate() {
    Variable ihn = input(), out = output();
    out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
    out.stay = ihn.stay && scale.stay && offset.stay;
    if (out.stay) execute();
  }
}

/**
 * Constrains two variables to have the same value.
 */
class EqualityConstraint extends BinaryConstraint {
  EqualityConstraint(Variable v1, Variable v2, Strength strength)
      : super(v1, v2, strength);

  /// Enforce this constraint. Assume that it is satisfied.
  void execute() {
    output().value = input().value;
  }
}

/**
 * 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.
 **/
class Variable {
  List<Constraint> constraints = <Constraint>[];
  Constraint? determinedBy;
  int mark = 0;
  Strength walkStrength = WEAKEST;
  bool stay = true;
  int value;
  final String name;

  Variable(this.name, this.value);

  /**
   * Add the given constraint to the set of all constraints that refer
   * this variable.
   */
  void addConstraint(Constraint c) {
    constraints.add(c);
  }

  /// Removes all traces of c from this variable.
  void removeConstraint(Constraint c) {
    constraints.remove(c);
    if (determinedBy == c) determinedBy = null;
  }
}

class Planner {
  int currentMark = 0;

  /**
   * Attempt to satisfy the given constraint and, if successful,
   * incrementally update the dataflow graph.  Details: If satisfying
   * 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.
   */
  void incrementalAdd(Constraint c) {
    int mark = newMark();
    for (Constraint? overridden = c.satisfy(mark);
        overridden != null;
        overridden = overridden.satisfy(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.
   */
  void incrementalRemove(Constraint c) {
    Variable out = c.output();
    c.markUnsatisfied();
    c.removeFromGraph();
    List<Constraint> unsatisfied = removePropagateFrom(out);
    Strength strength = REQUIRED;
    do {
      for (int i = 0; i < unsatisfied.length; i++) {
        Constraint u = unsatisfied[i];
        if (u.strength == strength) incrementalAdd(u);
      }
      strength = strength.nextWeaker();
    } while (strength != WEAKEST);
  }

  /// Select a previously unused mark value.
  int newMark() => ++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.
   */
  Plan makePlan(List<Constraint> sources) {
    int mark = newMark();
    Plan plan = new Plan();
    List<Constraint> todo = sources;
    while (todo.length > 0) {
      Constraint c = todo.removeLast();
      if (c.output().mark != mark && c.inputsKnown(mark)) {
        plan.addConstraint(c);
        c.output().mark = mark;
        addConstraintsConsumingTo(c.output(), todo);
      }
    }
    return plan;
  }

  /**
   * Extract a plan for resatisfying starting from the output of the
   * given [constraints], usually a set of input constraints.
   */
  Plan extractPlanFromConstraints(List<Constraint> constraints) {
    List<Constraint> sources = <Constraint>[];
    for (int i = 0; i < constraints.length; i++) {
      Constraint c = constraints[i];
      // if not in plan already and eligible for inclusion.
      if (c.isInput() && c.isSatisfied()) sources.add(c);
    }
    return makePlan(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.
   */
  bool addPropagate(Constraint c, int mark) {
    List<Constraint> todo = <Constraint>[c];
    while (todo.length > 0) {
      Constraint d = todo.removeLast();
      if (d.output().mark == mark) {
        incrementalRemove(c);
        return false;
      }
      d.recalculate();
      addConstraintsConsumingTo(d.output(), 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.
   */
  List<Constraint> removePropagateFrom(Variable out) {
    out.determinedBy = null;
    out.walkStrength = WEAKEST;
    out.stay = true;
    List<Constraint> unsatisfied = <Constraint>[];
    List<Variable> todo = <Variable>[out];
    while (todo.length > 0) {
      Variable v = todo.removeLast();
      for (int i = 0; i < v.constraints.length; i++) {
        Constraint c = v.constraints[i];
        if (!c.isSatisfied()) unsatisfied.add(c);
      }
      Constraint? determining = v.determinedBy;
      for (int i = 0; i < v.constraints.length; i++) {
        Constraint next = v.constraints[i];
        if (next != determining && next.isSatisfied()) {
          next.recalculate();
          todo.add(next.output());
        }
      }
    }
    return unsatisfied;
  }

  void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {
    Constraint? determining = v.determinedBy;
    for (int i = 0; i < v.constraints.length; i++) {
      Constraint c = v.constraints[i];
      if (c != determining && c.isSatisfied()) coll.add(c);
    }
  }
}

/**
 * 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.
 */
class Plan {
  List<Constraint> list = <Constraint>[];

  void addConstraint(Constraint c) {
    list.add(c);
  }

  int size() => list.length;

  void execute() {
    for (int i = 0; i < list.length; i++) {
      list[i].execute();
    }
  }
}

/**
 * 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 accommodated. The cost in this case is,
 * of course, very low. Typical situations lie somewhere between these
 * two extremes.
 */
void chainTest(int n) {
  planner = new Planner();
  Variable? prev = null, first = null, last = null;
  // Build chain of n equality constraints.
  for (int i = 0; i <= n; i++) {
    Variable v = new Variable("v$i", 0);
    if (prev != null) new EqualityConstraint(prev, v, REQUIRED);
    if (i == 0) first = v;
    if (i == n) last = v;
    prev = v;
  }
  new StayConstraint(last!, STRONG_DEFAULT);
  EditConstraint edit = new EditConstraint(first!, PREFERRED);
  Plan plan = planner.extractPlanFromConstraints(<Constraint>[edit]);
  for (int i = 0; i < 100; i++) {
    first.value = i;
    plan.execute();
    if (last.value != i) {
      print("Chain test failed:");
      print("Expected last value to be $i but it was ${last.value}.");
    }
  }
}

/**
 * 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.
 */
void projectionTest(int n) {
  planner = new Planner();
  Variable scale = new Variable("scale", 10);
  Variable offset = new Variable("offset", 1000);
  Variable? src = null, dst = null;

  List<Variable> dests = <Variable>[];
  for (int i = 0; i < n; i++) {
    src = new Variable("src", i);
    dst = new Variable("dst", i);
    dests.add(dst);
    new StayConstraint(src, NORMAL);
    new ScaleConstraint(src, scale, offset, dst, REQUIRED);
  }
  change(src!, 17);
  if (dst!.value != 1170) print("Projection 1 failed");
  change(dst, 1050);
  if (src.value != 5) print("Projection 2 failed");
  change(scale, 5);
  for (int i = 0; i < n - 1; i++) {
    if (dests[i].value != i * 5 + 1000) print("Projection 3 failed");
  }
  change(offset, 2000);
  for (int i = 0; i < n - 1; i++) {
    if (dests[i].value != i * 5 + 2000) print("Projection 4 failed");
  }
}

void change(Variable v, int newValue) {
  EditConstraint edit = new EditConstraint(v, PREFERRED);
  Plan plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]);
  for (int i = 0; i < 10; i++) {
    v.value = newValue;
    plan.execute();
  }
  edit.destroyConstraint();
}

late Planner planner;
