library;
import self as self;
import "dart:core" as core;

class DeltaBlue extends core::Object {
  synthetic constructor •() → self::DeltaBlue
    : super core::Object::•()
    ;
  method run() → void {
    self::chainTest(100);
    self::projectionTest(100);
  }
}
class Strength extends core::Object {
  final field core::int value;
  final field core::String name;
  const constructor •(core::int value, core::String name) → self::Strength
    : self::Strength::value = value, self::Strength::name = name, super core::Object::•()
    ;
  method nextWeaker() → self::Strength
    return const <self::Strength>[self::STRONG_PREFERRED, self::PREFERRED, self::STRONG_DEFAULT, self::NORMAL, self::WEAK_DEFAULT, self::WEAKEST].{core::List::[]}(this.{self::Strength::value});
  static method stronger(self::Strength s1, self::Strength s2) → core::bool {
    return s1.{self::Strength::value}.{core::num::<}(s2.{self::Strength::value});
  }
  static method weaker(self::Strength s1, self::Strength s2) → core::bool {
    return s1.{self::Strength::value}.{core::num::>}(s2.{self::Strength::value});
  }
  static method weakest(self::Strength s1, self::Strength s2) → self::Strength {
    return self::Strength::weaker(s1, s2) ?{self::Strength} s1 : s2;
  }
  static method strongest(self::Strength s1, self::Strength s2) → self::Strength {
    return self::Strength::stronger(s1, s2) ?{self::Strength} s1 : s2;
  }
}
abstract class Constraint extends core::Object {
  final field self::Strength strength;
  const constructor •(self::Strength strength) → self::Constraint
    : self::Constraint::strength = strength, super core::Object::•()
    ;
  abstract method isSatisfied() → core::bool;
  abstract method markUnsatisfied() → void;
  abstract method addToGraph() → void;
  abstract method removeFromGraph() → void;
  abstract method chooseMethod(core::int mark) → void;
  abstract method markInputs(core::int mark) → void;
  abstract method inputsKnown(core::int mark) → core::bool;
  abstract method output() → self::Variable;
  abstract method execute() → void;
  abstract method recalculate() → void;
  method addConstraint() → void {
    this.{self::Constraint::addToGraph}();
    self::planner.{self::Planner::incrementalAdd}(this);
  }
  method satisfy(dynamic mark) → self::Constraint {
    this.{self::Constraint::chooseMethod}(mark as{TypeError} core::int);
    if(!this.{self::Constraint::isSatisfied}()) {
      if(this.{self::Constraint::strength}.{core::Object::==}(self::REQUIRED)) {
        core::print("Could not satisfy a required constraint!");
      }
      return null;
    }
    this.{self::Constraint::markInputs}(mark as{TypeError} core::int);
    self::Variable out = this.{self::Constraint::output}();
    self::Constraint overridden = out.{self::Variable::determinedBy};
    if(!overridden.{core::Object::==}(null))
      overridden.{self::Constraint::markUnsatisfied}();
    out.{self::Variable::determinedBy} = this;
    if(!self::planner.{self::Planner::addPropagate}(this, mark as{TypeError} core::int))
      core::print("Cycle encountered");
    out.{self::Variable::mark} = mark as{TypeError} core::int;
    return overridden;
  }
  method destroyConstraint() → void {
    if(this.{self::Constraint::isSatisfied}())
      self::planner.{self::Planner::incrementalRemove}(this);
    this.{self::Constraint::removeFromGraph}();
  }
  method isInput() → core::bool
    return false;
}
abstract class UnaryConstraint extends self::Constraint {
  final field self::Variable myOutput;
  field core::bool satisfied = false;
  constructor •(self::Variable myOutput, self::Strength strength) → self::UnaryConstraint
    : self::UnaryConstraint::myOutput = myOutput, super self::Constraint::•(strength) {
    this.{self::Constraint::addConstraint}();
  }
  method addToGraph() → void {
    this.{self::UnaryConstraint::myOutput}.{self::Variable::addConstraint}(this);
    this.{self::UnaryConstraint::satisfied} = false;
  }
  method chooseMethod(core::int mark) → void {
    this.{self::UnaryConstraint::satisfied} = !this.{self::UnaryConstraint::myOutput}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::UnaryConstraint::myOutput}.{self::Variable::walkStrength});
  }
  method isSatisfied() → core::bool
    return this.{self::UnaryConstraint::satisfied};
  method markInputs(core::int mark) → void {}
  method output() → self::Variable
    return this.{self::UnaryConstraint::myOutput};
  method recalculate() → void {
    this.{self::UnaryConstraint::myOutput}.{self::Variable::walkStrength} = this.{self::Constraint::strength};
    this.{self::UnaryConstraint::myOutput}.{self::Variable::stay} = !this.{self::Constraint::isInput}();
    if(this.{self::UnaryConstraint::myOutput}.{self::Variable::stay})
      this.{self::Constraint::execute}();
  }
  method markUnsatisfied() → void {
    this.{self::UnaryConstraint::satisfied} = false;
  }
  method inputsKnown(core::int mark) → core::bool
    return true;
  method removeFromGraph() → void {
    if(!this.{self::UnaryConstraint::myOutput}.{core::Object::==}(null))
      this.{self::UnaryConstraint::myOutput}.{self::Variable::removeConstraint}(this);
    this.{self::UnaryConstraint::satisfied} = false;
  }
}
class StayConstraint extends self::UnaryConstraint {
  constructor •(self::Variable v, self::Strength str) → self::StayConstraint
    : super self::UnaryConstraint::•(v, str)
    ;
  method execute() → void {}
}
class EditConstraint extends self::UnaryConstraint {
  constructor •(self::Variable v, self::Strength str) → self::EditConstraint
    : super self::UnaryConstraint::•(v, str)
    ;
  method isInput() → core::bool
    return true;
  method execute() → void {}
}
abstract class BinaryConstraint extends self::Constraint {
  field self::Variable v1;
  field self::Variable v2;
  field core::int direction = self::NONE;
  constructor •(self::Variable v1, self::Variable v2, self::Strength strength) → self::BinaryConstraint
    : self::BinaryConstraint::v1 = v1, self::BinaryConstraint::v2 = v2, super self::Constraint::•(strength) {
    this.{self::Constraint::addConstraint}();
  }
  method chooseMethod(core::int mark) → void {
    if(this.{self::BinaryConstraint::v1}.{self::Variable::mark}.{core::num::==}(mark)) {
      this.{self::BinaryConstraint::direction} = !this.{self::BinaryConstraint::v2}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength}) ?{core::int} self::FORWARD : self::NONE;
    }
    if(this.{self::BinaryConstraint::v2}.{self::Variable::mark}.{core::num::==}(mark)) {
      this.{self::BinaryConstraint::direction} = !this.{self::BinaryConstraint::v1}.{self::Variable::mark}.{core::num::==}(mark) && self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}) ?{core::int} self::BACKWARD : self::NONE;
    }
    if(self::Strength::weaker(this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength})) {
      this.{self::BinaryConstraint::direction} = self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v1}.{self::Variable::walkStrength}) ?{core::int} self::BACKWARD : self::NONE;
    }
    else {
      this.{self::BinaryConstraint::direction} = self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength}) ?{core::int} self::FORWARD : self::BACKWARD;
    }
  }
  method addToGraph() → void {
    this.{self::BinaryConstraint::v1}.{self::Variable::addConstraint}(this);
    this.{self::BinaryConstraint::v2}.{self::Variable::addConstraint}(this);
    this.{self::BinaryConstraint::direction} = self::NONE;
  }
  method isSatisfied() → core::bool
    return !this.{self::BinaryConstraint::direction}.{core::num::==}(self::NONE);
  method markInputs(core::int mark) → void {
    this.{self::BinaryConstraint::input}().{self::Variable::mark} = mark;
  }
  method input() → self::Variable
    return this.{self::BinaryConstraint::direction}.{core::num::==}(self::FORWARD) ?{self::Variable} this.{self::BinaryConstraint::v1} : this.{self::BinaryConstraint::v2};
  method output() → self::Variable
    return this.{self::BinaryConstraint::direction}.{core::num::==}(self::FORWARD) ?{self::Variable} this.{self::BinaryConstraint::v2} : this.{self::BinaryConstraint::v1};
  method recalculate() → void {
    self::Variable ihn = this.{self::BinaryConstraint::input}();
    self::Variable out = this.{self::BinaryConstraint::output}();
    out.{self::Variable::walkStrength} = self::Strength::weakest(this.{self::Constraint::strength}, ihn.{self::Variable::walkStrength});
    out.{self::Variable::stay} = ihn.{self::Variable::stay};
    if(out.{self::Variable::stay})
      this.{self::Constraint::execute}();
  }
  method markUnsatisfied() → void {
    this.{self::BinaryConstraint::direction} = self::NONE;
  }
  method inputsKnown(core::int mark) → core::bool {
    self::Variable i = this.{self::BinaryConstraint::input}();
    return i.{self::Variable::mark}.{core::num::==}(mark) || i.{self::Variable::stay} || i.{self::Variable::determinedBy}.{core::Object::==}(null);
  }
  method removeFromGraph() → void {
    if(!this.{self::BinaryConstraint::v1}.{core::Object::==}(null))
      this.{self::BinaryConstraint::v1}.{self::Variable::removeConstraint}(this);
    if(!this.{self::BinaryConstraint::v2}.{core::Object::==}(null))
      this.{self::BinaryConstraint::v2}.{self::Variable::removeConstraint}(this);
    this.{self::BinaryConstraint::direction} = self::NONE;
  }
}
class ScaleConstraint extends self::BinaryConstraint {
  final field self::Variable scale;
  final field self::Variable offset;
  constructor •(self::Variable src, self::Variable scale, self::Variable offset, self::Variable dest, self::Strength strength) → self::ScaleConstraint
    : self::ScaleConstraint::scale = scale, self::ScaleConstraint::offset = offset, super self::BinaryConstraint::•(src, dest, strength)
    ;
  method addToGraph() → void {
    super.{self::BinaryConstraint::addToGraph}();
    this.{self::ScaleConstraint::scale}.{self::Variable::addConstraint}(this);
    this.{self::ScaleConstraint::offset}.{self::Variable::addConstraint}(this);
  }
  method removeFromGraph() → void {
    super.{self::BinaryConstraint::removeFromGraph}();
    if(!this.{self::ScaleConstraint::scale}.{core::Object::==}(null))
      this.{self::ScaleConstraint::scale}.{self::Variable::removeConstraint}(this);
    if(!this.{self::ScaleConstraint::offset}.{core::Object::==}(null))
      this.{self::ScaleConstraint::offset}.{self::Variable::removeConstraint}(this);
  }
  method markInputs(core::int mark) → void {
    super.{self::BinaryConstraint::markInputs}(mark);
    this.{self::ScaleConstraint::scale}.{self::Variable::mark} = this.{self::ScaleConstraint::offset}.{self::Variable::mark} = mark;
  }
  method execute() → void {
    if(this.{self::BinaryConstraint::direction}.{core::num::==}(self::FORWARD)) {
      this.{self::BinaryConstraint::v2}.{self::Variable::value} = this.{self::BinaryConstraint::v1}.{self::Variable::value}.{core::num::*}(this.{self::ScaleConstraint::scale}.{self::Variable::value}).{core::num::+}(this.{self::ScaleConstraint::offset}.{self::Variable::value});
    }
    else {
      this.{self::BinaryConstraint::v1}.{self::Variable::value} = this.{self::BinaryConstraint::v2}.{self::Variable::value}.{core::num::-}(this.{self::ScaleConstraint::offset}.{self::Variable::value}).{core::num::~/}(this.{self::ScaleConstraint::scale}.{self::Variable::value});
    }
  }
  method recalculate() → void {
    self::Variable ihn = this.{self::BinaryConstraint::input}();
    self::Variable out = this.{self::BinaryConstraint::output}();
    out.{self::Variable::walkStrength} = self::Strength::weakest(this.{self::Constraint::strength}, ihn.{self::Variable::walkStrength});
    out.{self::Variable::stay} = ihn.{self::Variable::stay} && this.{self::ScaleConstraint::scale}.{self::Variable::stay} && this.{self::ScaleConstraint::offset}.{self::Variable::stay};
    if(out.{self::Variable::stay})
      this.{self::ScaleConstraint::execute}();
  }
}
class EqualityConstraint extends self::BinaryConstraint {
  constructor •(self::Variable v1, self::Variable v2, self::Strength strength) → self::EqualityConstraint
    : super self::BinaryConstraint::•(v1, v2, strength)
    ;
  method execute() → void {
    this.{self::BinaryConstraint::output}().{self::Variable::value} = this.{self::BinaryConstraint::input}().{self::Variable::value};
  }
}
class Variable extends core::Object {
  field core::List<self::Constraint> constraints = <self::Constraint>[];
  field self::Constraint determinedBy = null;
  field core::int mark = 0;
  field self::Strength walkStrength = self::WEAKEST;
  field core::bool stay = true;
  field core::int value;
  final field core::String name;
  constructor •(core::String name, core::int value) → self::Variable
    : self::Variable::name = name, self::Variable::value = value, super core::Object::•()
    ;
  method addConstraint(self::Constraint c) → void {
    this.{self::Variable::constraints}.{core::List::add}(c);
  }
  method removeConstraint(self::Constraint c) → void {
    this.{self::Variable::constraints}.{core::List::remove}(c);
    if(this.{self::Variable::determinedBy}.{core::Object::==}(c))
      this.{self::Variable::determinedBy} = null;
  }
}
class Planner extends core::Object {
  field core::int currentMark = 0;
  synthetic constructor •() → self::Planner
    : super core::Object::•()
    ;
  method incrementalAdd(self::Constraint c) → void {
    core::int mark = this.{self::Planner::newMark}();
    for (self::Constraint overridden = c.{self::Constraint::satisfy}(mark); !overridden.{core::Object::==}(null); overridden = overridden.{self::Constraint::satisfy}(mark))
      ;
  }
  method incrementalRemove(self::Constraint c) → void {
    self::Variable out = c.{self::Constraint::output}();
    c.{self::Constraint::markUnsatisfied}();
    c.{self::Constraint::removeFromGraph}();
    core::List<self::Constraint> unsatisfied = this.{self::Planner::removePropagateFrom}(out);
    self::Strength strength = self::REQUIRED;
    do {
      for (core::int i = 0; i.{core::num::<}(unsatisfied.{core::List::length}); i = i.{core::num::+}(1)) {
        self::Constraint u = unsatisfied.{core::List::[]}(i);
        if(u.{self::Constraint::strength}.{core::Object::==}(strength))
          this.{self::Planner::incrementalAdd}(u);
      }
      strength = strength.{self::Strength::nextWeaker}();
    }
    while (!strength.{core::Object::==}(self::WEAKEST))
  }
  method newMark() → core::int
    return this.{self::Planner::currentMark} = this.{self::Planner::currentMark}.{core::num::+}(1);
  method makePlan(core::List<self::Constraint> sources) → self::Plan {
    core::int mark = this.{self::Planner::newMark}();
    self::Plan plan = new self::Plan::•();
    core::List<self::Constraint> todo = sources;
    while (todo.{core::List::length}.{core::num::>}(0)) {
      self::Constraint c = todo.{core::List::removeLast}();
      if(!c.{self::Constraint::output}().{self::Variable::mark}.{core::num::==}(mark) && c.{self::Constraint::inputsKnown}(mark)) {
        plan.{self::Plan::addConstraint}(c);
        c.{self::Constraint::output}().{self::Variable::mark} = mark;
        this.{self::Planner::addConstraintsConsumingTo}(c.{self::Constraint::output}(), todo);
      }
    }
    return plan;
  }
  method extractPlanFromConstraints(core::List<self::Constraint> constraints) → self::Plan {
    core::List<self::Constraint> sources = <self::Constraint>[];
    for (core::int i = 0; i.{core::num::<}(constraints.{core::List::length}); i = i.{core::num::+}(1)) {
      self::Constraint c = constraints.{core::List::[]}(i);
      if(c.{self::Constraint::isInput}() && c.{self::Constraint::isSatisfied}())
        sources.{core::List::add}(c);
    }
    return this.{self::Planner::makePlan}(sources);
  }
  method addPropagate(self::Constraint c, core::int mark) → core::bool {
    core::List<self::Constraint> todo = <self::Constraint>[c];
    while (todo.{core::List::length}.{core::num::>}(0)) {
      self::Constraint d = todo.{core::List::removeLast}();
      if(d.{self::Constraint::output}().{self::Variable::mark}.{core::num::==}(mark)) {
        this.{self::Planner::incrementalRemove}(c);
        return false;
      }
      d.{self::Constraint::recalculate}();
      this.{self::Planner::addConstraintsConsumingTo}(d.{self::Constraint::output}(), todo);
    }
    return true;
  }
  method removePropagateFrom(self::Variable out) → core::List<self::Constraint> {
    out.{self::Variable::determinedBy} = null;
    out.{self::Variable::walkStrength} = self::WEAKEST;
    out.{self::Variable::stay} = true;
    core::List<self::Constraint> unsatisfied = <self::Constraint>[];
    core::List<self::Variable> todo = <self::Variable>[out];
    while (todo.{core::List::length}.{core::num::>}(0)) {
      self::Variable v = todo.{core::List::removeLast}();
      for (core::int i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
        self::Constraint c = v.{self::Variable::constraints}.{core::List::[]}(i);
        if(!c.{self::Constraint::isSatisfied}())
          unsatisfied.{core::List::add}(c);
      }
      self::Constraint determining = v.{self::Variable::determinedBy};
      for (core::int i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
        self::Constraint next = v.{self::Variable::constraints}.{core::List::[]}(i);
        if(!next.{core::Object::==}(determining) && next.{self::Constraint::isSatisfied}()) {
          next.{self::Constraint::recalculate}();
          todo.{core::List::add}(next.{self::Constraint::output}());
        }
      }
    }
    return unsatisfied;
  }
  method addConstraintsConsumingTo(self::Variable v, core::List<self::Constraint> coll) → void {
    self::Constraint determining = v.{self::Variable::determinedBy};
    for (core::int i = 0; i.{core::num::<}(v.{self::Variable::constraints}.{core::List::length}); i = i.{core::num::+}(1)) {
      self::Constraint c = v.{self::Variable::constraints}.{core::List::[]}(i);
      if(!c.{core::Object::==}(determining) && c.{self::Constraint::isSatisfied}())
        coll.{core::List::add}(c);
    }
  }
}
class Plan extends core::Object {
  field core::List<self::Constraint> list = <self::Constraint>[];
  synthetic constructor •() → self::Plan
    : super core::Object::•()
    ;
  method addConstraint(self::Constraint c) → void {
    this.{self::Plan::list}.{core::List::add}(c);
  }
  method size() → core::int
    return this.{self::Plan::list}.{core::List::length};
  method execute() → void {
    for (core::int i = 0; i.{core::num::<}(this.{self::Plan::list}.{core::List::length}); i = i.{core::num::+}(1)) {
      this.{self::Plan::list}.{core::List::[]}(i).{self::Constraint::execute}();
    }
  }
}
static const field self::Strength REQUIRED = const self::Strength::•(0, "required");
static const field self::Strength STRONG_PREFERRED = const self::Strength::•(1, "strongPreferred");
static const field self::Strength PREFERRED = const self::Strength::•(2, "preferred");
static const field self::Strength STRONG_DEFAULT = const self::Strength::•(3, "strongDefault");
static const field self::Strength NORMAL = const self::Strength::•(4, "normal");
static const field self::Strength WEAK_DEFAULT = const self::Strength::•(5, "weakDefault");
static const field self::Strength WEAKEST = const self::Strength::•(6, "weakest");
static const field core::int NONE = 1;
static const field core::int FORWARD = 2;
static const field core::int BACKWARD = 0;
static field self::Planner planner;
static method main() → dynamic {
  new self::DeltaBlue::•().{self::DeltaBlue::run}();
}
static method chainTest(core::int n) → void {
  self::planner = new self::Planner::•();
  self::Variable prev = null;
  self::Variable first = null;
  self::Variable last = null;
  for (core::int i = 0; i.{core::num::<=}(n); i = i.{core::num::+}(1)) {
    self::Variable v = new self::Variable::•("v${i}", 0);
    if(!prev.{core::Object::==}(null))
      new self::EqualityConstraint::•(prev, v, self::REQUIRED);
    if(i.{core::num::==}(0))
      first = v;
    if(i.{core::num::==}(n))
      last = v;
    prev = v;
  }
  new self::StayConstraint::•(last, self::STRONG_DEFAULT);
  self::EditConstraint edit = new self::EditConstraint::•(first, self::PREFERRED);
  self::Plan plan = self::planner.{self::Planner::extractPlanFromConstraints}(<self::Constraint>[edit]);
  for (core::int i = 0; i.{core::num::<}(100); i = i.{core::num::+}(1)) {
    first.{self::Variable::value} = i;
    plan.{self::Plan::execute}();
    if(!last.{self::Variable::value}.{core::num::==}(i)) {
      core::print("Chain test failed:");
      core::print("Expected last value to be ${i} but it was ${last.{self::Variable::value}}.");
    }
  }
}
static method projectionTest(core::int n) → void {
  self::planner = new self::Planner::•();
  self::Variable scale = new self::Variable::•("scale", 10);
  self::Variable offset = new self::Variable::•("offset", 1000);
  self::Variable src = null;
  self::Variable dst = null;
  core::List<self::Variable> dests = <self::Variable>[];
  for (core::int i = 0; i.{core::num::<}(n); i = i.{core::num::+}(1)) {
    src = new self::Variable::•("src", i);
    dst = new self::Variable::•("dst", i);
    dests.{core::List::add}(dst);
    new self::StayConstraint::•(src, self::NORMAL);
    new self::ScaleConstraint::•(src, scale, offset, dst, self::REQUIRED);
  }
  self::change(src, 17);
  if(!dst.{self::Variable::value}.{core::num::==}(1170))
    core::print("Projection 1 failed");
  self::change(dst, 1050);
  if(!src.{self::Variable::value}.{core::num::==}(5))
    core::print("Projection 2 failed");
  self::change(scale, 5);
  for (core::int i = 0; i.{core::num::<}(n.{core::num::-}(1)); i = i.{core::num::+}(1)) {
    if(!dests.{core::List::[]}(i).{self::Variable::value}.{core::num::==}(i.{core::num::*}(5).{core::num::+}(1000)))
      core::print("Projection 3 failed");
  }
  self::change(offset, 2000);
  for (core::int i = 0; i.{core::num::<}(n.{core::num::-}(1)); i = i.{core::num::+}(1)) {
    if(!dests.{core::List::[]}(i).{self::Variable::value}.{core::num::==}(i.{core::num::*}(5).{core::num::+}(2000)))
      core::print("Projection 4 failed");
  }
}
static method change(self::Variable v, core::int newValue) → void {
  self::EditConstraint edit = new self::EditConstraint::•(v, self::PREFERRED);
  self::Plan plan = self::planner.{self::Planner::extractPlanFromConstraints}(<self::EditConstraint>[edit]);
  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
    v.{self::Variable::value} = newValue;
    plan.{self::Plan::execute}();
  }
  edit.{self::Constraint::destroyConstraint}();
}
