parent
ae31e0faf9
commit
76014e1903
|
@ -22,8 +22,8 @@ public class Constraint {
|
|||
this.strength = Strength.clip(strength);
|
||||
}
|
||||
|
||||
public Constraint(Constraint other, RelationalOperator op) {
|
||||
this(other.expression, other.op, other.strength);
|
||||
public Constraint(Constraint other, double strength) {
|
||||
this(other.expression, other.op, strength);
|
||||
}
|
||||
|
||||
public Expression getExpression() {
|
||||
|
@ -38,8 +38,9 @@ public class Constraint {
|
|||
return strength;
|
||||
}
|
||||
|
||||
public void setStrength(double strength) {
|
||||
public Constraint setStrength(double strength) {
|
||||
this.strength = strength;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RelationalOperator getOp() {
|
||||
|
|
|
@ -36,6 +36,10 @@ public class Expression {
|
|||
this.constant = constant;
|
||||
}
|
||||
|
||||
public Expression(List<Term> terms) {
|
||||
this(terms, 0);
|
||||
}
|
||||
|
||||
public double getConstant() {
|
||||
return constant;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,410 @@
|
|||
package no.birkett.kiwi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by alex on 31/01/15.
|
||||
*/
|
||||
public class Symbolics {
|
||||
|
||||
private Symbolics() {
|
||||
}
|
||||
|
||||
// Variable multiply, divide, and unary invert
|
||||
public static Term multiply(Variable variable, double coefficient) {
|
||||
return new Term(variable, coefficient);
|
||||
}
|
||||
|
||||
public static Term divide(Variable variable, double denominator) {
|
||||
return multiply(variable, (1.0 / denominator));
|
||||
}
|
||||
|
||||
public static Term negate(Variable variable) {
|
||||
return multiply(variable, -1.0);
|
||||
}
|
||||
|
||||
// Term multiply, divide, and unary invert
|
||||
public static Term multiply(Term term, double coefficient) {
|
||||
return new Term(term.getVariable(), term.getCoefficient() * coefficient);
|
||||
}
|
||||
|
||||
public static Term divide(Term term, double denominator) {
|
||||
return multiply(term, (1.0 / denominator));
|
||||
}
|
||||
|
||||
public static Term negate(Term term) {
|
||||
return multiply(term, -1.0);
|
||||
}
|
||||
|
||||
// Expression multiply, divide, and unary invert
|
||||
public static Expression multiply(Expression expression, double coefficient) {
|
||||
|
||||
List<Term> terms = new ArrayList<Term>();
|
||||
|
||||
for (Term term : expression.getTerms()) {
|
||||
terms.add(multiply(term, coefficient));
|
||||
}
|
||||
|
||||
// TODO Do we need to make a copy of the term objects in the array?
|
||||
return new Expression(terms, expression.getConstant() * coefficient);
|
||||
}
|
||||
|
||||
public static Expression divide(Expression expression, double denominator) {
|
||||
return multiply(expression, (1.0 / denominator));
|
||||
}
|
||||
|
||||
|
||||
public static Expression negate(Expression expression) {
|
||||
return multiply(expression, -1.0);
|
||||
}
|
||||
|
||||
// Double multiply
|
||||
public static Expression multiply(double coefficient, Expression expression) {
|
||||
return multiply(expression, coefficient);
|
||||
}
|
||||
|
||||
|
||||
public static Term multiply(double coefficient, Term term) {
|
||||
return multiply(term, coefficient);
|
||||
}
|
||||
|
||||
|
||||
public static Term multiply(double coefficient, Variable variable) {
|
||||
return multiply(variable, coefficient);
|
||||
}
|
||||
|
||||
// Expression add and subtract
|
||||
public static Expression add(Expression first, Expression second) {
|
||||
//TODO do we need to copy term objects?
|
||||
List<Term> terms = new ArrayList<Term>(first.getTerms().size() + second.getTerms().size());
|
||||
|
||||
terms.addAll(first.getTerms());
|
||||
terms.addAll(second.getTerms());
|
||||
|
||||
return new Expression(terms, first.getConstant() + second.getConstant());
|
||||
}
|
||||
|
||||
public static Expression add(Expression first, Term second) {
|
||||
//TODO do we need to copy term objects?
|
||||
List<Term> terms = new ArrayList<Term>(first.getTerms().size() + 1);
|
||||
|
||||
terms.addAll(first.getTerms());
|
||||
terms.add(second);
|
||||
|
||||
return new Expression(terms, first.getConstant());
|
||||
}
|
||||
|
||||
public static Expression add(Expression expression, Variable variable) {
|
||||
return add(expression, new Term(variable));
|
||||
}
|
||||
|
||||
public static Expression add(Expression expression, double constant) {
|
||||
return new Expression(expression.getTerms(), expression.getConstant() + constant);
|
||||
}
|
||||
|
||||
public static Expression subtract(Expression first, Expression second) {
|
||||
return add(first, negate(second));
|
||||
}
|
||||
|
||||
public static Expression subtract(Expression expression, Term term) {
|
||||
return add(expression, negate(term));
|
||||
}
|
||||
|
||||
public static Expression subtract(Expression expression, Variable variable) {
|
||||
return add(expression, negate(variable));
|
||||
}
|
||||
|
||||
public static Expression subtract(Expression expression, double constant) {
|
||||
return add(expression, -constant);
|
||||
}
|
||||
|
||||
// Term add and subtract
|
||||
public static Expression add(Term term, Expression expression) {
|
||||
return add(expression, term);
|
||||
}
|
||||
|
||||
public static Expression add(Term first, Term second) {
|
||||
List<Term> terms = new ArrayList<Term>(2);
|
||||
terms.add(first);
|
||||
terms.add(second);
|
||||
return new Expression(terms);
|
||||
}
|
||||
|
||||
public static Expression add(Term term, Variable variable) {
|
||||
return add(term, new Term(variable));
|
||||
}
|
||||
|
||||
public static Expression add(Term term, double constant) {
|
||||
return new Expression(term, constant);
|
||||
}
|
||||
|
||||
public static Expression subtract(Term term, Expression expression) {
|
||||
return add(negate(expression), term);
|
||||
}
|
||||
|
||||
public static Expression subtract(Term first, Term second) {
|
||||
return add(first, negate(second));
|
||||
}
|
||||
|
||||
public static Expression subtract(Term term, Variable variable) {
|
||||
return add(term, negate(variable));
|
||||
}
|
||||
|
||||
public static Expression subtract(Term term, double constant) {
|
||||
return add(term, -constant);
|
||||
}
|
||||
|
||||
// Variable add and subtract
|
||||
public static Expression add(Variable variable, Expression expression) {
|
||||
return add(expression, variable);
|
||||
}
|
||||
|
||||
public static Expression add(Variable variable, Term term) {
|
||||
return add(term, variable);
|
||||
}
|
||||
|
||||
public static Expression add(Variable first, Variable second) {
|
||||
return add(new Term(first), second);
|
||||
}
|
||||
|
||||
public static Expression add(Variable variable, double constant) {
|
||||
return add(new Term(variable), constant);
|
||||
}
|
||||
|
||||
public static Expression subtract(Variable variable, Expression expression) {
|
||||
return add(variable, negate(expression));
|
||||
}
|
||||
|
||||
public static Expression subtract(Variable variable, Term term) {
|
||||
return add(variable, negate(term));
|
||||
}
|
||||
|
||||
public static Expression subtract(Variable first, Variable second) {
|
||||
return add(first, negate(second));
|
||||
}
|
||||
|
||||
public static Expression subtract(Variable variable, double constant) {
|
||||
return add(variable, -constant);
|
||||
}
|
||||
|
||||
// Double add and subtract
|
||||
|
||||
public static Expression add(double constant, Expression expression) {
|
||||
return add(expression, constant);
|
||||
}
|
||||
|
||||
public static Expression add(double constant, Term term) {
|
||||
return add(term, constant);
|
||||
}
|
||||
|
||||
public static Expression add(double constant, Variable variable) {
|
||||
return add(variable, constant);
|
||||
}
|
||||
|
||||
public static Expression subtract(double constant, Expression expression) {
|
||||
return add(negate(expression), constant);
|
||||
}
|
||||
|
||||
public static Expression subtract(double constant, Term term) {
|
||||
return add(negate(term), constant);
|
||||
}
|
||||
|
||||
public static Expression subtract(double constant, Variable variable) {
|
||||
return add(negate(variable), constant);
|
||||
}
|
||||
|
||||
// Expression relations
|
||||
public static Constraint equals(Expression first, Expression second) {
|
||||
return new Constraint(subtract(first, second), RelationalOperator.OP_EQ);
|
||||
}
|
||||
|
||||
public static Constraint equals(Expression expression, Term term) {
|
||||
return equals(expression, new Expression(term));
|
||||
}
|
||||
|
||||
public static Constraint equals(Expression expression, Variable variable) {
|
||||
return equals(expression, new Term(variable));
|
||||
}
|
||||
|
||||
public static Constraint equals(Expression expression, double constant) {
|
||||
return equals(expression, new Expression(constant));
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Expression first, Expression second) {
|
||||
return new Constraint(subtract(first, second), RelationalOperator.OP_LE);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Expression expression, Term term) {
|
||||
return lessThanOrEqualTo(expression, new Expression(term));
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Expression expression, Variable variable) {
|
||||
return lessThanOrEqualTo(expression, new Term(variable));
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Expression expression, double constant) {
|
||||
return lessThanOrEqualTo(expression, new Expression(constant));
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Expression first, Expression second) {
|
||||
return new Constraint(subtract(first, second), RelationalOperator.OP_GE);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Expression expression, Term term) {
|
||||
return greaterThanOrEqualTo(expression, new Expression(term));
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Expression expression, Variable variable) {
|
||||
return greaterThanOrEqualTo(expression, new Term(variable));
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Expression expression, double constant) {
|
||||
return greaterThanOrEqualTo(expression, new Expression(constant));
|
||||
}
|
||||
|
||||
// Term relations
|
||||
public static Constraint equals(Term term, Expression expression) {
|
||||
return equals(expression, term);
|
||||
}
|
||||
|
||||
public static Constraint equals(Term first, Term second) {
|
||||
return equals(new Expression(first), second);
|
||||
}
|
||||
|
||||
public static Constraint equals(Term term, Variable variable) {
|
||||
return equals(new Expression(term), variable);
|
||||
}
|
||||
|
||||
public static Constraint equals(Term term, double constant) {
|
||||
return equals(new Expression(term), constant);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Term term, Expression expression) {
|
||||
return lessThanOrEqualTo(expression, term);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Term first, Term second) {
|
||||
return lessThanOrEqualTo(new Expression(first), second);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Term term, Variable variable) {
|
||||
return lessThanOrEqualTo(new Expression(term), variable);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Term term, double constant) {
|
||||
return lessThanOrEqualTo(new Expression(term), constant);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Term term, Expression expression) {
|
||||
return greaterThanOrEqualTo(expression, term);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Term first, Term second) {
|
||||
return greaterThanOrEqualTo(new Expression(first), second);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Term term, Variable variable) {
|
||||
return greaterThanOrEqualTo(new Expression(term), variable);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Term term, double constant) {
|
||||
return greaterThanOrEqualTo(new Expression(term), constant);
|
||||
}
|
||||
|
||||
// Variable relations
|
||||
public static Constraint equals(Variable variable, Expression expression) {
|
||||
return equals(expression, variable);
|
||||
}
|
||||
|
||||
public static Constraint equals(Variable variable, Term term) {
|
||||
return equals(term, variable);
|
||||
}
|
||||
|
||||
public static Constraint equals(Variable first, Variable second) {
|
||||
return equals(new Term(first), second);
|
||||
}
|
||||
|
||||
public static Constraint equals(Variable variable, double constant) {
|
||||
return equals(new Term(variable), constant);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Variable variable, Expression expression) {
|
||||
return lessThanOrEqualTo(expression, variable);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Variable variable, Term term) {
|
||||
return lessThanOrEqualTo(term, variable);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Variable first, Variable second) {
|
||||
return lessThanOrEqualTo(new Term(first), second);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(Variable variable, double constant) {
|
||||
return lessThanOrEqualTo(new Term(variable), constant);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Variable variable, Expression expression) {
|
||||
return greaterThanOrEqualTo(expression, variable);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Variable variable, Term term) {
|
||||
return greaterThanOrEqualTo(term, variable);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Variable first, Variable second) {
|
||||
return greaterThanOrEqualTo(new Term(first), second);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(Variable variable, double constant) {
|
||||
return greaterThanOrEqualTo(new Term(variable), constant);
|
||||
}
|
||||
|
||||
// Double relations
|
||||
public static Constraint equals(double constant, Expression expression) {
|
||||
return equals(expression, constant);
|
||||
}
|
||||
|
||||
public static Constraint equals(double constant, Term term) {
|
||||
return equals(term, constant);
|
||||
}
|
||||
|
||||
public static Constraint equals(double constant, Variable variable) {
|
||||
return equals(variable, constant);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(double constant, Expression expression) {
|
||||
return lessThanOrEqualTo(expression, constant);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(double constant, Term term) {
|
||||
return lessThanOrEqualTo(term, constant);
|
||||
}
|
||||
|
||||
public static Constraint lessThanOrEqualTo(double constant, Variable variable) {
|
||||
return lessThanOrEqualTo(variable, constant);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(double constant, Expression expression) {
|
||||
return greaterThanOrEqualTo(expression, constant);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(double constant, Term term) {
|
||||
return greaterThanOrEqualTo(term, constant);
|
||||
}
|
||||
|
||||
public static Constraint greaterThanOrEqualTo(double constant, Variable variable) {
|
||||
return greaterThanOrEqualTo(variable, constant);
|
||||
}
|
||||
|
||||
// Constraint strength modifier
|
||||
public static Constraint modifyStrength(Constraint constraint, double strength) {
|
||||
return new Constraint(constraint, strength);
|
||||
}
|
||||
|
||||
public static Constraint modifyStrength(double strength, Constraint constraint) {
|
||||
return modifyStrength(strength, constraint);
|
||||
}
|
||||
|
||||
}
|
|
@ -14,9 +14,8 @@ public class Variable {
|
|||
}
|
||||
|
||||
public Variable(double value) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
@ -25,11 +24,4 @@ public class Variable {
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
public Expression times(double value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Expression plus(double value) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,36 +10,73 @@ public class Tests {
|
|||
private static double EPSILON = 1.0e-8;
|
||||
|
||||
@Test
|
||||
public void testKiwi() throws UnsatisfiableConstraintException, DuplicateConstraintException {
|
||||
public void simpleNew() throws UnsatisfiableConstraintException, DuplicateConstraintException {
|
||||
Solver solver = new Solver();
|
||||
Variable x = new Variable("x");
|
||||
|
||||
|
||||
solver.addConstraint(Symbolics.equals(Symbolics.add(x,2), 20));
|
||||
|
||||
solver.updateVariables();
|
||||
|
||||
assertEquals(x.getValue(), 18, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simple0() throws UnsatisfiableConstraintException, DuplicateConstraintException {
|
||||
Solver solver = new Solver();
|
||||
Variable x = new Variable("x");
|
||||
Variable y = new Variable("y");
|
||||
|
||||
// x = 20
|
||||
solver.addConstraint(Symbolics.equals(x, 20));
|
||||
|
||||
Term term = new Term(x);
|
||||
// x + 2 == y + 10
|
||||
//
|
||||
solver.addConstraint(Symbolics.equals(Symbolics.add(x,2), Symbolics.add(y, 10)));
|
||||
|
||||
Expression expression = new Expression(term);
|
||||
|
||||
Constraint constraint = new Constraint(expression, RelationalOperator.OP_EQ);
|
||||
|
||||
solver.addConstraint(constraint);
|
||||
solver.updateVariables();
|
||||
|
||||
System.out.println("x " + x.getValue() + " y " + y.getValue());
|
||||
|
||||
assertEquals(y.getValue(), 12, EPSILON);
|
||||
assertEquals(x.getValue(), 20, EPSILON);
|
||||
}
|
||||
|
||||
/*@Test
|
||||
public void simple1() {
|
||||
Variable x = new Variable(167);
|
||||
Variable y = new Variable(2);
|
||||
@Test
|
||||
public void simple1() throws DuplicateConstraintException, UnsatisfiableConstraintException {
|
||||
Variable x = new Variable("x");
|
||||
Variable y = new Variable("y");
|
||||
Solver solver = new Solver();
|
||||
solver.addConstraint(Symbolics.equals(x, y));
|
||||
solver.updateVariables();
|
||||
assertEquals(x.getValue(), y.getValue(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void casso1() throws DuplicateConstraintException, UnsatisfiableConstraintException {
|
||||
Variable x = new Variable("x");
|
||||
Variable y = new Variable("y");
|
||||
Solver solver = new Solver();
|
||||
|
||||
Constraint eq = new Constraint(x, Constraint.Operator.EQ, new Expression(y));
|
||||
//ClLinearEquation eq = new ClLinearEquation(x, new ClLinearExpression(y));
|
||||
solver.addConstraint(eq);
|
||||
assertEquals(x.value(), y.value(), EPSILON);
|
||||
solver.addConstraint(Symbolics.lessThanOrEqualTo(x, y));
|
||||
solver.addConstraint(Symbolics.equals(y, Symbolics.add(x, 3.0)));
|
||||
solver.addConstraint(Symbolics.equals(x, 10.0).setStrength(Strength.WEAK));
|
||||
solver.addConstraint(Symbolics.equals(y, 10.0).setStrength(Strength.WEAK));
|
||||
|
||||
solver.updateVariables();
|
||||
|
||||
if (Math.abs(x.getValue() - 10.0) < EPSILON) {
|
||||
assertEquals(10, x.getValue(), EPSILON);
|
||||
assertEquals(13, y.getValue(), EPSILON);
|
||||
} else {
|
||||
assertEquals(7, x.getValue(), EPSILON);
|
||||
assertEquals(10, y.getValue(), EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
/*@Test
|
||||
public void addDelete1() {
|
||||
Variable x = new Variable("x");
|
||||
Solver solver = new Solver();
|
||||
|
@ -112,25 +149,7 @@ public class Tests {
|
|||
assertEquals(120, y.value(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void casso1() {
|
||||
Variable x = new Variable("x");
|
||||
Variable y = new Variable("y");
|
||||
Solver solver = new Solver();
|
||||
|
||||
solver.addConstraint(new Constraint(x, Constraint.Operator.LEQ, y));
|
||||
solver.addConstraint(new Constraint(y, Constraint.Operator.EQ, x.plus(3.0)));
|
||||
solver.addConstraint(new Constraint(x, Constraint.Operator.EQ, 10.0, Strength.WEAK));
|
||||
solver.addConstraint(new Constraint(y, Constraint.Operator.EQ, 10.0, Strength.WEAK));
|
||||
|
||||
if (Math.abs(x.getValue() - 10.0) < EPSILON) {
|
||||
assertEquals(10, x.value(), EPSILON);
|
||||
assertEquals(13, y.value(), EPSILON);
|
||||
} else {
|
||||
assertEquals(7, x.value(), EPSILON);
|
||||
assertEquals(10, y.value(), EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = RequiredFailure.class)
|
||||
public void inconsistent1() throws InternalError {
|
||||
|
|
Loading…
Reference in New Issue