/*
* 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.ANumber;
import jmathexpr.arithmetic.op.Addition;
import jmathexpr.arithmetic.op.Multiplication;
import jmathexpr.arithmetic.op.Subtraction;
import jmathexpr.util.pattern.AnyPattern;
import jmathexpr.util.pattern.TerminationPattern;
import jmathexpr.util.rule.CompositeRule;
import jmathexpr.util.rule.SubRule;
/**
* The distributive law of the numbers: a(b + c) = ab + ac.
*
* @author Elemér Furka
*/
public class DistributiveLaw extends CompositeRule {
private final TerminationPattern a = new AnyPattern();
private final TerminationPattern b = new AnyPattern();
private final TerminationPattern c = new AnyPattern();
public DistributiveLaw() {
super(true);
}
@Override
public boolean matches(Expression expr) {
if ((rule = new LeftAddition()).matches(expr)) return true;
if ((rule = new LeftSubtraction()).matches(expr)) return true;
if ((rule = new RightAddition()).matches(expr)) return true;
if ((rule = new RightSubtraction()).matches(expr)) return true;
return false;
}
/**
* The distributive law a(b + c) = ab + ac.
*/
private class LeftAddition extends SubRule {
@Override
public boolean matches(Expression expr) {
boolean matches = new Multiplication(a, new Addition(b, c)).matches(expr);
return matches && !(a.hit() instanceof ANumber && ((ANumber) a.hit()).isOne());
}
@Override
public Expression apply() {
return new Addition(new Multiplication(a.hit(), b.hit()),
new Multiplication(a.hit(), c.hit()));
}
}
/**
* The distributive law a(b - c) = ab - ac.
*/
private class LeftSubtraction extends SubRule {
@Override
public boolean matches(Expression expr) {
boolean matches = new Multiplication(a, new Subtraction(b, c)).matches(expr);
return matches && !(a.hit() instanceof ANumber && ((ANumber) a.hit()).isOne());
}
@Override
public Expression apply() {
return new Subtraction(new Multiplication(a.hit(), b.hit()),
new Multiplication(a.hit(), c.hit()));
}
}
/**
* The distributive law (a + b)c = ab + ac.
*/
private class RightAddition extends SubRule {
@Override
public boolean matches(Expression expr) {
boolean matches = new Multiplication(new Addition(a, b), c).matches(expr);
return matches && !(c.hit() instanceof ANumber && ((ANumber) c.hit()).isOne());
}
@Override
public Expression apply() {
return new Addition(new Multiplication(a.hit(), b.hit()),
new Multiplication(a.hit(), c.hit()));
}
}
/**
* The distributive law (a - b)c = ab - ac.
*/
private class RightSubtraction extends SubRule {
@Override
public boolean matches(Expression expr) {
boolean matches = new Multiplication(new Subtraction(a, b), c).matches(expr);
return matches && !(c.hit() instanceof ANumber && ((ANumber) c.hit()).isOne());
}
@Override
public Expression apply() {
return new Subtraction(new Multiplication(a.hit(), b.hit()),
new Multiplication(a.hit(), c.hit()));
}
}
}