Commit 436f272a authored by Chinmay Garde's avatar Chinmay Garde

Avoid using variables as equation members

parent 9ea8abd5
...@@ -16,3 +16,4 @@ part 'row.dart'; ...@@ -16,3 +16,4 @@ part 'row.dart';
part 'utils.dart'; part 'utils.dart';
part 'result.dart'; part 'result.dart';
part 'parser_exception.dart'; part 'parser_exception.dart';
part 'param.dart';
...@@ -15,7 +15,7 @@ abstract class EquationMember { ...@@ -15,7 +15,7 @@ abstract class EquationMember {
Constraint operator <=(EquationMember m) => asExpression() <= m; Constraint operator <=(EquationMember m) => asExpression() <= m;
operator ==(EquationMember m) => asExpression() == m; /* Constraint */ operator ==(EquationMember m) => asExpression() == m;
Expression operator +(EquationMember m) => asExpression() + m; Expression operator +(EquationMember m) => asExpression() + m;
...@@ -24,4 +24,7 @@ abstract class EquationMember { ...@@ -24,4 +24,7 @@ abstract class EquationMember {
Expression operator *(EquationMember m) => asExpression() * m; Expression operator *(EquationMember m) => asExpression() * m;
Expression operator /(EquationMember m) => asExpression() / m; Expression operator /(EquationMember m) => asExpression() / m;
int get hashCode =>
throw "An equation member is not comparable and cannot be added to collections";
} }
...@@ -28,8 +28,9 @@ class Expression extends EquationMember { ...@@ -28,8 +28,9 @@ class Expression extends EquationMember {
relation); relation);
} }
if (value is Variable) { if (value is Param) {
var newTerms = new List<Term>.from(terms)..add(new Term(value, -1.0)); var newTerms = new List<Term>.from(terms)
..add(new Term(value.variable, -1.0));
return new Constraint(new Expression(newTerms, constant), relation); return new Constraint(new Expression(newTerms, constant), relation);
} }
...@@ -64,9 +65,9 @@ class Expression extends EquationMember { ...@@ -64,9 +65,9 @@ class Expression extends EquationMember {
return new Expression(new List.from(terms), constant + m.value); return new Expression(new List.from(terms), constant + m.value);
} }
if (m is Variable) { if (m is Param) {
return new Expression( return new Expression(
new List.from(terms)..add(new Term(m, 1.0)), constant); new List.from(terms)..add(new Term(m.variable, 1.0)), constant);
} }
if (m is Term) { if (m is Term) {
...@@ -87,9 +88,9 @@ class Expression extends EquationMember { ...@@ -87,9 +88,9 @@ class Expression extends EquationMember {
return new Expression(new List.from(terms), constant - m.value); return new Expression(new List.from(terms), constant - m.value);
} }
if (m is Variable) { if (m is Param) {
return new Expression( return new Expression(
new List.from(terms)..add(new Term(m, -1.0)), constant); new List.from(terms)..add(new Term(m.variable, -1.0)), constant);
} }
if (m is Term) { if (m is Term) {
......
// 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 Param extends EquationMember {
final Variable variable;
Param.withVariable(this.variable);
Param(double value) : this.variable = new Variable(value);
bool get isConstant => false;
double get value => variable.value;
Expression asExpression() => new Expression([new Term(variable, 1.0)], 0.0);
}
...@@ -4,11 +4,9 @@ ...@@ -4,11 +4,9 @@
part of cassowary; part of cassowary;
class Variable extends EquationMember { class Variable {
double value = 0.0; double value = 0.0;
Variable(this.value); Variable(this.value);
bool get isConstant => false; // TODO(csg): Add external variable update callbacks here
Expression asExpression() => new Expression([new Term(this, 1.0)], 0.0);
} }
...@@ -10,12 +10,12 @@ import 'package:cassowary/cassowary.dart'; ...@@ -10,12 +10,12 @@ import 'package:cassowary/cassowary.dart';
void main() { void main() {
test('variable', () { test('variable', () {
var v = new Variable(22.0); var v = new Param(22.0);
expect(v.value, 22); expect(v.value, 22);
}); });
test('variable1', () { test('variable1', () {
var v = new Variable(22.0); var v = new Param(22.0);
expect((v + CM(22.0)).value, 44.0); expect((v + CM(22.0)).value, 44.0);
expect((v - CM(20.0)).value, 2.0); expect((v - CM(20.0)).value, 2.0);
}); });
...@@ -35,11 +35,11 @@ void main() { ...@@ -35,11 +35,11 @@ void main() {
}); });
test('expression1', () { test('expression1', () {
var v1 = new Variable(10.0); var v1 = new Param(10.0);
var v2 = new Variable(10.0); var v2 = new Param(10.0);
var v3 = new Variable(22.0); var v3 = new Param(22.0);
expect(v1 is Variable, true); expect(v1 is Param, true);
expect(v1 + CM(20.0) is Expression, true); expect(v1 + CM(20.0) is Expression, true);
expect(v1 + v2 is Expression, true); expect(v1 + v2 is Expression, true);
...@@ -51,7 +51,7 @@ void main() { ...@@ -51,7 +51,7 @@ void main() {
}); });
test('expression2', () { test('expression2', () {
var e = new Variable(10.0) + CM(5.0); var e = new Param(10.0) + CM(5.0);
expect(e.value, 15.0); expect(e.value, 15.0);
expect(e is Expression, true); expect(e is Expression, true);
...@@ -63,8 +63,8 @@ void main() { ...@@ -63,8 +63,8 @@ void main() {
expect(e.value, 15.0); expect(e.value, 15.0);
// Variable // Param
var v = new Variable(2.0); var v = new Param(2.0);
expect((e + v) is Expression, true); expect((e + v) is Expression, true);
expect((e + v).value, 17.0); expect((e + v).value, 17.0);
expect((e - v) is Expression, true); expect((e - v) is Expression, true);
...@@ -73,7 +73,7 @@ void main() { ...@@ -73,7 +73,7 @@ void main() {
expect(e.value, 15.0); expect(e.value, 15.0);
// Term // Term
var t = new Term(v, 2.0); var t = new Term(v.variable, 2.0);
expect((e + t) is Expression, true); expect((e + t) is Expression, true);
expect((e + t).value, 19.0); expect((e + t).value, 19.0);
expect((e - t) is Expression, true); expect((e - t) is Expression, true);
...@@ -82,7 +82,7 @@ void main() { ...@@ -82,7 +82,7 @@ void main() {
expect(e.value, 15.0); expect(e.value, 15.0);
// Expression // Expression
var e2 = new Variable(7.0) + new Variable(3.0); var e2 = new Param(7.0) + new Param(3.0);
expect((e + e2) is Expression, true); expect((e + e2) is Expression, true);
expect((e + e2).value, 25.0); expect((e + e2).value, 25.0);
expect((e - e2) is Expression, true); expect((e - e2) is Expression, true);
...@@ -102,7 +102,7 @@ void main() { ...@@ -102,7 +102,7 @@ void main() {
expect((t - c).value, 10.0); expect((t - c).value, 10.0);
// Variable // Variable
var v = new Variable(2.0); var v = new Param(2.0);
expect((t + v) is Expression, true); expect((t + v) is Expression, true);
expect((t + v).value, 14.0); expect((t + v).value, 14.0);
expect((t - v) is Expression, true); expect((t - v) is Expression, true);
...@@ -116,7 +116,7 @@ void main() { ...@@ -116,7 +116,7 @@ void main() {
expect((t - t2).value, 10.0); expect((t - t2).value, 10.0);
// Expression // Expression
var exp = new Variable(1.0) + CM(1.0); var exp = new Param(1.0) + CM(1.0);
expect((t + exp) is Expression, true); expect((t + exp) is Expression, true);
expect((t + exp).value, 14.0); expect((t + exp).value, 14.0);
expect((t - exp) is Expression, true); expect((t - exp) is Expression, true);
...@@ -124,7 +124,7 @@ void main() { ...@@ -124,7 +124,7 @@ void main() {
}); });
test('variable3', () { test('variable3', () {
var v = new Variable(3.0); var v = new Param(3.0);
// Constant // Constant
var c = CM(2.0); var c = CM(2.0);
...@@ -134,7 +134,7 @@ void main() { ...@@ -134,7 +134,7 @@ void main() {
expect((v - c).value, 1.0); expect((v - c).value, 1.0);
// Variable // Variable
var v2 = new Variable(2.0); var v2 = new Param(2.0);
expect((v + v2) is Expression, true); expect((v + v2) is Expression, true);
expect((v + v2).value, 5.0); expect((v + v2).value, 5.0);
expect((v - v2) is Expression, true); expect((v - v2) is Expression, true);
...@@ -148,7 +148,7 @@ void main() { ...@@ -148,7 +148,7 @@ void main() {
expect((v - t2).value, 1.0); expect((v - t2).value, 1.0);
// Expression // Expression
var exp = new Variable(1.0) + CM(1.0); var exp = new Param(1.0) + CM(1.0);
expect(exp.terms.length, 1); expect(exp.terms.length, 1);
expect((v + exp) is Expression, true); expect((v + exp) is Expression, true);
...@@ -168,7 +168,7 @@ void main() { ...@@ -168,7 +168,7 @@ void main() {
expect((c - c2).value, 1.0); expect((c - c2).value, 1.0);
// Variable // Variable
var v2 = new Variable(2.0); var v2 = new Param(2.0);
expect((c + v2) is Expression, true); expect((c + v2) is Expression, true);
expect((c + v2).value, 5.0); expect((c + v2).value, 5.0);
expect((c - v2) is Expression, true); expect((c - v2) is Expression, true);
...@@ -182,7 +182,7 @@ void main() { ...@@ -182,7 +182,7 @@ void main() {
expect((c - t2).value, 1.0); expect((c - t2).value, 1.0);
// Expression // Expression
var exp = new Variable(1.0) + CM(1.0); var exp = new Param(1.0) + CM(1.0);
expect((c + exp) is Expression, true); expect((c + exp) is Expression, true);
expect((c + exp).value, 5.0); expect((c + exp).value, 5.0);
...@@ -191,27 +191,24 @@ void main() { ...@@ -191,27 +191,24 @@ void main() {
}); });
test('constraint2', () { test('constraint2', () {
var left = new Variable(10.0); var left = new Param(10.0);
var right = new Variable(100.0); var right = new Param(100.0);
var c = right - left >= CM(25.0); var c = right - left >= CM(25.0);
expect(c is Constraint, true); expect(c is Constraint, true);
}); });
// TODO(csg): Address API inconsistency where the multipliers and divisors
// are doubles instead of equation members
test('simple_multiplication', () { test('simple_multiplication', () {
// Constant // Constant
var c = CM(20.0); var c = CM(20.0);
expect((c * CM(2.0)).value, 40.0); expect((c * CM(2.0)).value, 40.0);
// Variable // Variable
var v = new Variable(20.0); var v = new Param(20.0);
expect((v * CM(2.0)).value, 40.0); expect((v * CM(2.0)).value, 40.0);
// Term // Term
var t = new Term(v, 1.0); var t = new Term(v.variable, 1.0);
expect((t * CM(2.0)).value, 40.0); expect((t * CM(2.0)).value, 40.0);
// Expression // Expression
...@@ -225,11 +222,11 @@ void main() { ...@@ -225,11 +222,11 @@ void main() {
expect((c / CM(2.0)).value, 10.0); expect((c / CM(2.0)).value, 10.0);
// Variable // Variable
var v = new Variable(20.0); var v = new Param(20.0);
expect((v / CM(2.0)).value, 10.0); expect((v / CM(2.0)).value, 10.0);
// Term // Term
var t = new Term(v, 1.0); var t = new Term(v.variable, 1.0);
expect((t / CM(2.0)).value, 10.0); expect((t / CM(2.0)).value, 10.0);
// Expression // Expression
...@@ -237,12 +234,9 @@ void main() { ...@@ -237,12 +234,9 @@ void main() {
expect((e / CM(2.0)).value, 10.0); expect((e / CM(2.0)).value, 10.0);
}); });
// TODO: Support and test cases where the multipliers and divisors are more
// than just simple constants.
test('full_constraints_setup', () { test('full_constraints_setup', () {
var left = new Variable(2.0); var left = new Param(2.0);
var right = new Variable(10.0); var right = new Param(10.0);
var c1 = right - left >= CM(20.0); var c1 = right - left >= CM(20.0);
expect(c1 is Constraint, true); expect(c1 is Constraint, true);
...@@ -261,8 +255,8 @@ void main() { ...@@ -261,8 +255,8 @@ void main() {
}); });
test('constraint_strength_update', () { test('constraint_strength_update', () {
var left = new Variable(2.0); var left = new Param(2.0);
var right = new Variable(10.0); var right = new Param(10.0);
var c = (right - left >= CM(200.0)) | 750.0; var c = (right - left >= CM(200.0)) | 750.0;
expect(c is Constraint, true); expect(c is Constraint, true);
...@@ -274,8 +268,8 @@ void main() { ...@@ -274,8 +268,8 @@ void main() {
test('solver', () { test('solver', () {
var s = new Solver(); var s = new Solver();
var left = new Variable(2.0); var left = new Param(2.0);
var right = new Variable(100.0); var right = new Param(100.0);
var c1 = right - left >= CM(200.0); var c1 = right - left >= CM(200.0);
...@@ -285,7 +279,7 @@ void main() { ...@@ -285,7 +279,7 @@ void main() {
}); });
test('constraint_complex', () { test('constraint_complex', () {
var e = new Variable(200.0) - new Variable(100.0); var e = new Param(200.0) - new Param(100.0);
// Constant // Constant
var c1 = e >= CM(50.0); var c1 = e >= CM(50.0);
...@@ -294,7 +288,7 @@ void main() { ...@@ -294,7 +288,7 @@ void main() {
expect(c1.expression.constant, -50.0); expect(c1.expression.constant, -50.0);
// Variable // Variable
var c2 = e >= new Variable(2.0); var c2 = e >= new Param(2.0);
expect(c2 is Constraint, true); expect(c2 is Constraint, true);
expect(c2.expression.terms.length, 3); expect(c2.expression.terms.length, 3);
expect(c2.expression.constant, 0.0); expect(c2.expression.constant, 0.0);
...@@ -320,7 +314,7 @@ void main() { ...@@ -320,7 +314,7 @@ void main() {
expect(c1.expression.constant, 50.0); expect(c1.expression.constant, 50.0);
// Variable // Variable
var c2 = new Variable(100.0) >= new Variable(2.0); var c2 = new Param(100.0) >= new Param(2.0);
expect(c2 is Constraint, true); expect(c2 is Constraint, true);
expect(c2.expression.terms.length, 2); expect(c2.expression.terms.length, 2);
expect(c2.expression.constant, 0.0); expect(c2.expression.constant, 0.0);
...@@ -343,8 +337,8 @@ void main() { ...@@ -343,8 +337,8 @@ void main() {
test('constraint_update_in_solver', () { test('constraint_update_in_solver', () {
var s = new Solver(); var s = new Solver();
var left = new Variable(2.0); var left = new Param(2.0);
var right = new Variable(100.0); var right = new Param(100.0);
var c1 = right - left >= CM(200.0); var c1 = right - left >= CM(200.0);
var c2 = right >= right; var c2 = right >= right;
...@@ -358,8 +352,8 @@ void main() { ...@@ -358,8 +352,8 @@ void main() {
test('test_multiplication_division_override', () { test('test_multiplication_division_override', () {
var c = CM(10.0); var c = CM(10.0);
var v = new Variable(c.value); var v = new Param(c.value);
var t = new Term(v, 1.0); var t = new Term(v.variable, 1.0);
var e = new Expression([t], 0.0); var e = new Expression([t], 0.0);
// Constant // Constant
...@@ -389,8 +383,8 @@ void main() { ...@@ -389,8 +383,8 @@ void main() {
test('test_multiplication_division_exceptions', () { test('test_multiplication_division_exceptions', () {
var c = CM(10.0); var c = CM(10.0);
var v = new Variable(c.value); var v = new Param(c.value);
var t = new Term(v, 1.0); var t = new Term(v.variable, 1.0);
var e = new Expression([t], 0.0); var e = new Expression([t], 0.0);
expect((c * c).value, 100); expect((c * c).value, 100);
...@@ -404,4 +398,28 @@ void main() { ...@@ -404,4 +398,28 @@ void main() {
expect(() => v / c, returnsNormally); expect(() => v / c, returnsNormally);
}); });
test('edit_updates', () {
Solver s = new Solver();
var left = new Param(0.0);
var right = new Param(100.0);
var mid = new Param(0.0);
Constraint c = left + right >= CM(2.0) * mid;
expect(s.addConstraint(c), Result.success);
expect(s.addEditVariable(mid.variable, 999.0), Result.success);
expect(
s.addEditVariable(mid.variable, 999.0), Result.duplicateEditVariable);
expect(s.removeEditVariable(mid.variable), Result.success);
expect(s.removeEditVariable(mid.variable), Result.unknownEditVariable);
});
test('bug1', () {
var left = new Param(0.0);
var right = new Param(100.0);
var mid = new Param(0.0);
expect(((left + right) >= (CM(2.0) * mid)) is Constraint, true);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment