// dynamic is not a subtype of dart.core::int (DeltaBlue.dart:139:16)
library;
import self as self;
import "dart:core" as core;

class DeltaBlue extends core::Object {
  constructor •() → void
    : 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) → void
    : 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) ? s1 : s2;
  }
}
abstract class Constraint extends core::Object {
  final field self::Strength strength;
  const constructor •(self::Strength strength) → void
    : 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 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 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 core::int))
      core::print("Cycle encountered");
    out.{self::Variable::mark} = mark;
    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) → void
    : 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) → void
    : super self::UnaryConstraint::•(v, str)
    ;
  method execute() → void {}
}
class EditConstraint extends self::UnaryConstraint {
  constructor •(self::Variable v, self::Strength str) → void
    : 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) → void
    : 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}) ? 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}) ? 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}) ? self::BACKWARD : self::NONE;
    }
    else {
      this.{self::BinaryConstraint::direction} = self::Strength::stronger(this.{self::Constraint::strength}, this.{self::BinaryConstraint::v2}.{self::Variable::walkStrength}) ? 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) ? this.{self::BinaryConstraint::v1} : this.{self::BinaryConstraint::v2};
  method output() → self::Variable
    return this.{self::BinaryConstraint::direction}.{core::num::==}(self::FORWARD) ? 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) → void
    : self::ScaleConstraint::scale = scale, self::ScaleConstraint::offset = offset, super self::BinaryConstraint::•(src, dest, strength)
    ;
  method addToGraph() → void {
    this.{=self::BinaryConstraint::addToGraph}();
    this.{self::ScaleConstraint::scale}.{self::Variable::addConstraint}(this);
    this.{self::ScaleConstraint::offset}.{self::Variable::addConstraint}(this);
  }
  method removeFromGraph() → void {
    this.{=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 {
    this.{=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) → void
    : 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) → void
    : self::Variable::name = name, self::Variable::value = value, super core::Object::•()
    ;
  method addConstraint(self::Constraint c) → void {
    this.{self::Variable::constraints}.{core::List::add$cc}(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;
  constructor •() → void
    : 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$cc}(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$cc}(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$cc}(c);
    }
  }
}
class Plan extends core::Object {
  field core::List<self::Constraint> list = <self::Constraint>[];
  constructor •() → void
    : super core::Object::•()
    ;
  method addConstraint(self::Constraint c) → void {
    this.{self::Plan::list}.{core::List::add$cc}(c);
  }
  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 = null;
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}();
}
