flutter/packages/cassowary/lib/expression.dart
Ian Hickson 43b0104114 Revert "Merge pull request #2639 from Hixie/always_specify_types"
This reverts commit f41b3411da35929b09009e47cb52474389e42874, reversing
changes made to e33d8d96212f3e337a6660f1eb1118bffc945bf5.

This was a bad check-in due to my mangling uploading a new version of the branch from a different machine.

This reverts https://github.com/flutter/flutter/pull/2639 and will be replaced by https://github.com/flutter/flutter/pull/2640
2016-03-12 00:34:37 -08:00

181 lines
4.8 KiB
Dart

// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of cassowary;
class Expression extends _EquationMember {
Expression(this.terms, this.constant);
Expression.fromExpression(Expression expr)
: this.terms = new List<Term>.from(expr.terms),
this.constant = expr.constant;
final List<Term> terms;
final double constant;
@override
bool get isConstant => terms.length == 0;
@override
double get value => terms.fold(constant, (value, term) => value + term.value);
@override
Expression asExpression() => this;
Constraint _createConstraint(
_EquationMember /* rhs */ value, Relation relation) {
if (value is ConstantMember) {
return new Constraint(
new Expression(new List.from(terms), constant - value.value),
relation);
}
if (value is Param) {
var newTerms = new List<Term>.from(terms)
..add(new Term(value.variable, -1.0));
return new Constraint(new Expression(newTerms, constant), relation);
}
if (value is Term) {
var newTerms = new List<Term>.from(terms)
..add(new Term(value.variable, -value.coefficient));
return new Constraint(new Expression(newTerms, constant), relation);
}
if (value is Expression) {
var newTerms = value.terms.fold(new List<Term>.from(terms),
(list, t) => list..add(new Term(t.variable, -t.coefficient)));
return new Constraint(
new Expression(newTerms, constant - value.constant), relation);
}
assert(false);
return null;
}
@override
Constraint operator >=(_EquationMember value) =>
_createConstraint(value, Relation.greaterThanOrEqualTo);
@override
Constraint operator <=(_EquationMember value) =>
_createConstraint(value, Relation.lessThanOrEqualTo);
@override
Constraint equals(_EquationMember value) =>
_createConstraint(value, Relation.equalTo);
@override
Expression operator +(_EquationMember m) {
if (m is ConstantMember) {
return new Expression(new List.from(terms), constant + m.value);
}
if (m is Param) {
return new Expression(
new List.from(terms)..add(new Term(m.variable, 1.0)), constant);
}
if (m is Term) {
return new Expression(new List.from(terms)..add(m), constant);
}
if (m is Expression) {
return new Expression(
new List.from(terms)..addAll(m.terms), constant + m.constant);
}
assert(false);
return null;
}
@override
Expression operator -(_EquationMember m) {
if (m is ConstantMember) {
return new Expression(new List.from(terms), constant - m.value);
}
if (m is Param) {
return new Expression(
new List.from(terms)..add(new Term(m.variable, -1.0)), constant);
}
if (m is Term) {
return new Expression(new List.from(terms)
..add(new Term(m.variable, -m.coefficient)), constant);
}
if (m is Expression) {
var copiedTerms = new List<Term>.from(terms);
m.terms.forEach(
(t) => copiedTerms.add(new Term(t.variable, -t.coefficient)));
return new Expression(copiedTerms, constant - m.constant);
}
assert(false);
return null;
}
_EquationMember _applyMultiplicand(double m) {
var newTerms = terms.fold(new List<Term>(), (list, term) => list
..add(new Term(term.variable, term.coefficient * m)));
return new Expression(newTerms, constant * m);
}
_Pair<Expression, double> _findMulitplierAndMultiplicand(_EquationMember m) {
// At least on of the the two members must be constant for the resulting
// expression to be linear
if (!this.isConstant && !m.isConstant) {
return null;
}
if (this.isConstant) {
return new _Pair(m.asExpression(), this.value);
}
if (m.isConstant) {
return new _Pair(this.asExpression(), m.value);
}
assert(false);
return null;
}
_EquationMember operator *(_EquationMember m) {
_Pair<Expression, double> args = _findMulitplierAndMultiplicand(m);
if (args == null) {
throw new ParserException(
'Could not find constant multiplicand or multiplier', [this, m]);
return null;
}
return args.first._applyMultiplicand(args.second);
}
_EquationMember operator /(_EquationMember m) {
if (!m.isConstant) {
throw new ParserException(
'The divisor was not a constant expression', [this, m]);
return null;
}
return this._applyMultiplicand(1.0 / m.value);
}
String toString() {
StringBuffer buffer = new StringBuffer();
terms.forEach((t) => buffer.write('$t'));
if (constant != 0.0) {
buffer.write(constant.sign > 0.0 ? '+' : '-');
buffer.write(constant.abs());
}
return buffer.toString();
}
}