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

import 'package:benchmark_harness/benchmark_harness.dart';

/// 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() {
  const DeltaBlue().report();
}

/// Benchmark class required to report results.
class DeltaBlue extends BenchmarkBase {
  const DeltaBlue() : super("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>[
        WEAKEST,
        WEAK_DEFAULT,
        NORMAL,
        STRONG_DEFAULT,
        PREFERRED,
        STRONG_REFERRED
      ][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 = Strength(0, "required");
const STRONG_REFERRED = Strength(1, "strongPreferred");
const PREFERRED = Strength(2, "preferred");
const STRONG_DEFAULT = Strength(3, "strongDefault");
const NORMAL = Strength(4, "normal");
const WEAK_DEFAULT = Strength(5, "weakDefault");
const WEAKEST = 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(int 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
  /// keybord, a clock, or some arbitraty 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.removeWhere((e) => c == e);
    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 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.
  void incrementalAdd(Constraint c) {
    int mark = newMark();
    for (Constraint overridden = c.satisfy(mark);
        overridden != null;
        overridden = overridden.satisfy(mark)) {
      // NOOP
    }
  }

  /// 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 = Plan();
    List<Constraint> todo = sources;
    while (todo.isNotEmpty) {
      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.isNotEmpty) {
      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.isNotEmpty) {
      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 accomodated. The cost in this case is,
/// of course, very low. Typical situations lie somewhere between these
/// two extremes.
void chainTest(int n) {
  planner = Planner();
  Variable prev, first, last;
  // Build chain of n equality constraints.
  for (int i = 0; i <= n; i++) {
    Variable v = Variable("v", 0);
    if (prev != null) EqualityConstraint(prev, v, REQUIRED);
    if (i == 0) first = v;
    if (i == n) last = v;
    prev = v;
  }
  StayConstraint(last, STRONG_DEFAULT);
  EditConstraint edit = 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.\n{last.value)\n{i}");
    }
  }
}

/// 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 = Planner();
  Variable scale = Variable("scale", 10);
  Variable offset = Variable("offset", 1000);
  Variable src, dst;

  List<Variable> dests = <Variable>[];
  for (int i = 0; i < n; i++) {
    src = Variable("src", i);
    dst = Variable("dst", i);
    dests.add(dst);
    StayConstraint(src, NORMAL);
    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 = EditConstraint(v, PREFERRED);
  Plan plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]);
  for (int i = 0; i < 10; i++) {
    v.value = newValue;
    plan.execute();
  }
  edit.destroyConstraint();
}

Planner planner;
