/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package jmathexpr.arithmetic.rule;
import jmathexpr.Expression;
import jmathexpr.arithmetic.op.Addition;
import jmathexpr.arithmetic.op.Multiplication;
import jmathexpr.arithmetic.op.Subtraction;
import jmathexpr.arithmetic.op.Sum;
import jmathexpr.util.pattern.AnyPattern;
import jmathexpr.util.rule.CompositeRule;
import jmathexpr.util.rule.SubRule;
/**
* The associative law of the numbers: a + (b + c) = (a + b) + c = a + b + c.
*
* @author Elemér Furka
*/
public class AssociativeLaw extends CompositeRule {
private final Expression a = new AnyPattern();
private final Expression b = new AnyPattern();
private final Expression c = new AnyPattern();
public AssociativeLaw() {
super(true);
}
@Override
public boolean matches(Expression expr) {
if ((rule = new AdditionAddition()).matches(expr)) return true;
if ((rule = new AdditionSubtraction()).matches(expr)) return true;
if ((rule = new SubtractionAddition()).matches(expr)) return true;
if ((rule = new LeftMultiplication()).matches(expr)) return true;
if ((rule = new RightMultiplication()).matches(expr)) return true;
return false;
}
/**
* The associative law (a + b) + c = a + (b + c) = a + b + c.
*/
private class AdditionAddition extends SubRule {
@Override
public boolean matches(Expression expr) {
Addition apb = new Addition(a, b);
Addition bpc = new Addition(b, c);
return new Addition(apb, c).matches(expr) ||
new Addition(a, bpc).matches(expr);
}
@Override
public Expression apply() {
return new Sum(new Addition(new Addition(a.evaluate(), b.evaluate()), c.evaluate()));
}
}
/**
* The associative law (a + b) - c = a + (b - c) = a + b - c.
*/
private class AdditionSubtraction extends SubRule {
@Override
public boolean matches(Expression expr) {
Addition apb = new Addition(a, b);
Subtraction bmc = new Subtraction(b, c);
return new Subtraction(apb, c).matches(expr) ||
new Addition(a, bmc).matches(expr);
}
@Override
public Expression apply() {
return new Sum(new Subtraction(new Addition(a.evaluate(), b.evaluate()), c.evaluate()));
}
}
/**
* The associative law (a - b) + c = a - b + c.
*/
private class SubtractionAddition extends SubRule {
@Override
public boolean matches(Expression expr) {
Subtraction amb = new Subtraction(a, b);
return new Addition(amb, c).matches(expr);
}
@Override
public Expression apply() {
return new Sum(new Addition(new Subtraction(a.evaluate(), b.evaluate()), c.evaluate()));
}
}
/**
* The associative law (a * b) * c = a * b * c.
*/
private class LeftMultiplication extends SubRule {
@Override
public boolean matches(Expression expr) {
Expression atb = new Multiplication(a, b);
return new Multiplication(atb, c).matches(expr);
}
@Override
public Expression apply() {
return new Multiplication(a.evaluate(), new Multiplication(b.evaluate(), c.evaluate()));
}
}
/**
* The associative law a * (b * c) = a * b * c.
*/
private class RightMultiplication extends SubRule {
@Override
public boolean matches(Expression expr) {
Expression btc = new Multiplication(b, c);
return new Multiplication(a, btc).matches(expr);
}
@Override
public Expression apply() {
return new Multiplication(new Multiplication(a.evaluate(), b.evaluate()), c.evaluate());
}
}
}