From 2ca5a8391a6e13aaedc61eba69e709222ccec187 Mon Sep 17 00:00:00 2001 From: Riccardo Azzolini Date: Sat, 6 Oct 2018 17:41:15 +0200 Subject: [PATCH] Implement patterns for most FunctionOperators --- .../rules/dsl/patterns/DivisionPattern.java | 38 +++++++++++ .../rules/dsl/patterns/LogarithmPattern.java | 38 +++++++++++ .../dsl/patterns/MultiplicationPattern.java | 38 +++++++++++ .../math/rules/dsl/patterns/PowerPattern.java | 38 +++++++++++ .../math/rules/dsl/patterns/RootPattern.java | 38 +++++++++++ .../dsl/patterns/SubtractionPattern.java | 38 +++++++++++ .../dsl/patterns/SumSubtractionPattern.java | 38 +++++++++++ .../warppi/math/rules/dsl/PatternTest.java | 64 +++++++++++++++++-- 8 files changed, 323 insertions(+), 7 deletions(-) create mode 100644 core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/DivisionPattern.java create mode 100644 core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/LogarithmPattern.java create mode 100644 core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/MultiplicationPattern.java create mode 100644 core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/PowerPattern.java create mode 100644 core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/RootPattern.java create mode 100644 core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/SubtractionPattern.java create mode 100644 core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/SumSubtractionPattern.java diff --git a/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/DivisionPattern.java b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/DivisionPattern.java new file mode 100644 index 00000000..b35a4d1a --- /dev/null +++ b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/DivisionPattern.java @@ -0,0 +1,38 @@ +package it.cavallium.warppi.math.rules.dsl.patterns; + +import it.cavallium.warppi.math.Function; +import it.cavallium.warppi.math.MathContext; +import it.cavallium.warppi.math.functions.Division; +import it.cavallium.warppi.math.rules.dsl.Pattern; +import it.cavallium.warppi.math.rules.dsl.PatternUtils; +import it.cavallium.warppi.math.rules.dsl.VisitorPattern; + +import java.util.Map; +import java.util.Optional; + +/** + * Matches and generates a division of two other patterns. + */ +public class DivisionPattern extends VisitorPattern { + private final Pattern dividend; + private final Pattern divisor; + + public DivisionPattern(final Pattern dividend, final Pattern divisor) { + this.dividend = dividend; + this.divisor = divisor; + } + + @Override + public Optional> visit(final Division division) { + return PatternUtils.matchFunctionOperatorParameters(division, dividend, divisor); + } + + @Override + public Function replace(final MathContext mathContext, final Map subFunctions) { + return new Division( + mathContext, + dividend.replace(mathContext, subFunctions), + divisor.replace(mathContext, subFunctions) + ); + } +} diff --git a/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/LogarithmPattern.java b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/LogarithmPattern.java new file mode 100644 index 00000000..956a3c27 --- /dev/null +++ b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/LogarithmPattern.java @@ -0,0 +1,38 @@ +package it.cavallium.warppi.math.rules.dsl.patterns; + +import it.cavallium.warppi.math.Function; +import it.cavallium.warppi.math.MathContext; +import it.cavallium.warppi.math.functions.Logarithm; +import it.cavallium.warppi.math.rules.dsl.Pattern; +import it.cavallium.warppi.math.rules.dsl.PatternUtils; +import it.cavallium.warppi.math.rules.dsl.VisitorPattern; + +import java.util.Map; +import java.util.Optional; + +/** + * Matches and generates a logarithm of base and argument patterns. + */ +public class LogarithmPattern extends VisitorPattern { + private final Pattern base; + private final Pattern argument; + + public LogarithmPattern(final Pattern base, final Pattern argument) { + this.base = base; + this.argument = argument; + } + + @Override + public Optional> visit(final Logarithm logarithm) { + return PatternUtils.matchFunctionOperatorParameters(logarithm, base, argument); + } + + @Override + public Function replace(final MathContext mathContext, final Map subFunctions) { + return new Logarithm( + mathContext, + base.replace(mathContext, subFunctions), + argument.replace(mathContext, subFunctions) + ); + } +} diff --git a/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/MultiplicationPattern.java b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/MultiplicationPattern.java new file mode 100644 index 00000000..f7a01975 --- /dev/null +++ b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/MultiplicationPattern.java @@ -0,0 +1,38 @@ +package it.cavallium.warppi.math.rules.dsl.patterns; + +import it.cavallium.warppi.math.Function; +import it.cavallium.warppi.math.MathContext; +import it.cavallium.warppi.math.functions.Multiplication; +import it.cavallium.warppi.math.rules.dsl.Pattern; +import it.cavallium.warppi.math.rules.dsl.PatternUtils; +import it.cavallium.warppi.math.rules.dsl.VisitorPattern; + +import java.util.Map; +import java.util.Optional; + +/** + * Matches and generates a multiplication of two other patterns. + */ +public class MultiplicationPattern extends VisitorPattern { + private final Pattern left; + private final Pattern right; + + public MultiplicationPattern(final Pattern left, final Pattern right) { + this.left = left; + this.right = right; + } + + @Override + public Optional> visit(final Multiplication multiplication) { + return PatternUtils.matchFunctionOperatorParameters(multiplication, left, right); + } + + @Override + public Function replace(final MathContext mathContext, final Map subFunctions) { + return new Multiplication( + mathContext, + left.replace(mathContext, subFunctions), + right.replace(mathContext, subFunctions) + ); + } +} diff --git a/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/PowerPattern.java b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/PowerPattern.java new file mode 100644 index 00000000..2a6f9548 --- /dev/null +++ b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/PowerPattern.java @@ -0,0 +1,38 @@ +package it.cavallium.warppi.math.rules.dsl.patterns; + +import it.cavallium.warppi.math.Function; +import it.cavallium.warppi.math.MathContext; +import it.cavallium.warppi.math.functions.Power; +import it.cavallium.warppi.math.rules.dsl.Pattern; +import it.cavallium.warppi.math.rules.dsl.PatternUtils; +import it.cavallium.warppi.math.rules.dsl.VisitorPattern; + +import java.util.Map; +import java.util.Optional; + +/** + * Matches and generates a power (exponentiation) of base and exponent patterns. + */ +public class PowerPattern extends VisitorPattern { + private final Pattern base; + private final Pattern exponent; + + public PowerPattern(final Pattern base, final Pattern exponent) { + this.base = base; + this.exponent = exponent; + } + + @Override + public Optional> visit(final Power power) { + return PatternUtils.matchFunctionOperatorParameters(power, base, exponent); + } + + @Override + public Function replace(final MathContext mathContext, final Map subFunctions) { + return new Power( + mathContext, + base.replace(mathContext, subFunctions), + exponent.replace(mathContext, subFunctions) + ); + } +} diff --git a/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/RootPattern.java b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/RootPattern.java new file mode 100644 index 00000000..0d95b402 --- /dev/null +++ b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/RootPattern.java @@ -0,0 +1,38 @@ +package it.cavallium.warppi.math.rules.dsl.patterns; + +import it.cavallium.warppi.math.Function; +import it.cavallium.warppi.math.MathContext; +import it.cavallium.warppi.math.functions.Root; +import it.cavallium.warppi.math.rules.dsl.Pattern; +import it.cavallium.warppi.math.rules.dsl.PatternUtils; +import it.cavallium.warppi.math.rules.dsl.VisitorPattern; + +import java.util.Map; +import java.util.Optional; + +/** + * Matches and generates a root of degree and radicand patterns. + */ +public class RootPattern extends VisitorPattern { + private final Pattern degree; + private final Pattern radicand; + + public RootPattern(final Pattern degree, final Pattern radicand) { + this.degree = degree; + this.radicand = radicand; + } + + @Override + public Optional> visit(final Root root) { + return PatternUtils.matchFunctionOperatorParameters(root, degree, radicand); + } + + @Override + public Function replace(final MathContext mathContext, final Map subFunctions) { + return new Root( + mathContext, + degree.replace(mathContext, subFunctions), + radicand.replace(mathContext, subFunctions) + ); + } +} diff --git a/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/SubtractionPattern.java b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/SubtractionPattern.java new file mode 100644 index 00000000..fe732886 --- /dev/null +++ b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/SubtractionPattern.java @@ -0,0 +1,38 @@ +package it.cavallium.warppi.math.rules.dsl.patterns; + +import it.cavallium.warppi.math.Function; +import it.cavallium.warppi.math.MathContext; +import it.cavallium.warppi.math.functions.Subtraction; +import it.cavallium.warppi.math.rules.dsl.Pattern; +import it.cavallium.warppi.math.rules.dsl.PatternUtils; +import it.cavallium.warppi.math.rules.dsl.VisitorPattern; + +import java.util.Map; +import java.util.Optional; + +/** + * Matches and generates a subtraction of two other patterns. + */ +public class SubtractionPattern extends VisitorPattern { + private final Pattern left; + private final Pattern right; + + public SubtractionPattern(final Pattern left, final Pattern right) { + this.left = left; + this.right = right; + } + + @Override + public Optional> visit(final Subtraction subtraction) { + return PatternUtils.matchFunctionOperatorParameters(subtraction, left, right); + } + + @Override + public Function replace(final MathContext mathContext, final Map subFunctions) { + return new Subtraction( + mathContext, + left.replace(mathContext, subFunctions), + right.replace(mathContext, subFunctions) + ); + } +} diff --git a/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/SumSubtractionPattern.java b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/SumSubtractionPattern.java new file mode 100644 index 00000000..ed084a20 --- /dev/null +++ b/core/src/main/java/it/cavallium/warppi/math/rules/dsl/patterns/SumSubtractionPattern.java @@ -0,0 +1,38 @@ +package it.cavallium.warppi.math.rules.dsl.patterns; + +import it.cavallium.warppi.math.Function; +import it.cavallium.warppi.math.MathContext; +import it.cavallium.warppi.math.functions.SumSubtraction; +import it.cavallium.warppi.math.rules.dsl.Pattern; +import it.cavallium.warppi.math.rules.dsl.PatternUtils; +import it.cavallium.warppi.math.rules.dsl.VisitorPattern; + +import java.util.Map; +import java.util.Optional; + +/** + * Matches and generates a sum/subtraction (±) of two other patterns. + */ +public class SumSubtractionPattern extends VisitorPattern { + private final Pattern left; + private final Pattern right; + + public SumSubtractionPattern(final Pattern left, final Pattern right) { + this.left = left; + this.right = right; + } + + @Override + public Optional> visit(final SumSubtraction sumSubtraction) { + return PatternUtils.matchFunctionOperatorParameters(sumSubtraction, left, right); + } + + @Override + public Function replace(final MathContext mathContext, final Map subFunctions) { + return new SumSubtraction( + mathContext, + left.replace(mathContext, subFunctions), + right.replace(mathContext, subFunctions) + ); + } +} diff --git a/core/src/test/java/it/cavallium/warppi/math/rules/dsl/PatternTest.java b/core/src/test/java/it/cavallium/warppi/math/rules/dsl/PatternTest.java index d750557f..bc795737 100644 --- a/core/src/test/java/it/cavallium/warppi/math/rules/dsl/PatternTest.java +++ b/core/src/test/java/it/cavallium/warppi/math/rules/dsl/PatternTest.java @@ -2,17 +2,15 @@ package it.cavallium.warppi.math.rules.dsl; import it.cavallium.warppi.math.Function; import it.cavallium.warppi.math.MathContext; -import it.cavallium.warppi.math.functions.Negative; +import it.cavallium.warppi.math.functions.*; import it.cavallium.warppi.math.functions.Number; -import it.cavallium.warppi.math.functions.Subtraction; -import it.cavallium.warppi.math.functions.Sum; -import it.cavallium.warppi.math.rules.dsl.patterns.NegativePattern; -import it.cavallium.warppi.math.rules.dsl.patterns.NumberPattern; -import it.cavallium.warppi.math.rules.dsl.patterns.SubFunctionPattern; -import it.cavallium.warppi.math.rules.dsl.patterns.SumPattern; +import it.cavallium.warppi.math.rules.dsl.patterns.*; +import org.apache.commons.lang3.tuple.ImmutablePair; import org.junit.Test; import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Optional; @@ -115,4 +113,56 @@ public class PatternTest { assertTrue(subFunctions.isPresent()); assertEquals(shouldMatch, pattern.replace(mathContext, subFunctions.get())); } + + @Test + public void otherBinaryPatterns() { + final Number one = new Number(mathContext, 1); + final Number two = new Number(mathContext, 2); + final SubFunctionPattern x = new SubFunctionPattern("x"); + final SubFunctionPattern y = new SubFunctionPattern("y"); + + final Function shouldNotMatch = new Sum(mathContext, one, two); + + final List> patternsAndMatchingFunctions = Arrays.asList( + new ImmutablePair<>( + new DivisionPattern(x, y), + new Division(mathContext, one, two) + ), + new ImmutablePair<>( + new LogarithmPattern(x, y), + new Logarithm(mathContext, one, two) + ), + new ImmutablePair<>( + new MultiplicationPattern(x, y), + new Multiplication(mathContext, one, two) + ), + new ImmutablePair<>( + new PowerPattern(x, y), + new Power(mathContext, one, two) + ), + new ImmutablePair<>( + new RootPattern(x, y), + new Root(mathContext, one, two) + ), + new ImmutablePair<>( + new SubtractionPattern(x, y), + new Subtraction(mathContext, one, two) + ), + new ImmutablePair<>( + new SumSubtractionPattern(x, y), + new SumSubtraction(mathContext, one, two) + ) + ); + + for (final ImmutablePair patternAndMatchingFunction : patternsAndMatchingFunctions) { + final Pattern pattern = patternAndMatchingFunction.getLeft(); + final Function shouldMatch = patternAndMatchingFunction.getRight(); + + assertFalse(pattern.match(shouldNotMatch).isPresent()); + + final Optional> subFunctions = pattern.match(shouldMatch); + assertTrue(subFunctions.isPresent()); + assertEquals(shouldMatch, pattern.replace(mathContext, subFunctions.get())); + } + } } \ No newline at end of file