Create PatternUtils helper class

This commit is contained in:
Riccardo Azzolini 2018-10-06 16:22:55 +02:00
parent be5ae2d475
commit 0574744921
3 changed files with 74 additions and 40 deletions

View File

@ -0,0 +1,72 @@
package it.cavallium.warppi.math.rules.dsl;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.FunctionOperator;
import it.cavallium.warppi.math.functions.Subtraction;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* Contains helper methods which are useful for writing patterns.
*/
public class PatternUtils {
/**
* Gathers captured sub-functions from two matches, checking for equality
* of ones with the same name.
*
* @param match1 Sub-functions from one match.
* @param match2 Sub-functions from the other match.
* @return A <code>Map</code> containing all sub-functions, or an empty
* <code>Optional</code> if the same name is used to refer to
* non-equal sub-functions in the two matches.
*/
public static Optional<Map<String, Function>> mergeMatches(
final Map<String, Function> match1,
final Map<String, Function> match2
) {
if (!checkSubFunctionEquality(match1, match2)) {
return Optional.empty();
}
final Map<String, Function> merged = new HashMap<>();
merged.putAll(match1);
merged.putAll(match2);
return Optional.of(merged);
}
private static boolean checkSubFunctionEquality(
final Map<String, Function> match1,
final Map<String, Function> match2
) {
for (final Map.Entry<String, Function> leftSubFunction : match1.entrySet()) {
final String key = leftSubFunction.getKey();
if (match2.containsKey(key)
&& !match2.get(key).equals(leftSubFunction.getValue())) {
return false;
}
}
return true;
}
/**
* Tries to match the given patterns against the two parameters of a <code>FunctionOperator</code>.
*
* @param functionOperator The <code>FunctionOperator</code> to be matched.
* @param pattern1 The <code>Pattern</code> used to match <code>functionOperator.parameter1</code>.
* @param pattern2 The <code>Pattern</code> used to match <code>functionOperator.parameter2</code>.
* @return The combined result of the two matches.
* @see #mergeMatches(Map, Map)
*/
public static Optional<Map<String, Function>> matchFunctionOperatorParameters(
final FunctionOperator functionOperator,
final Pattern pattern1,
final Pattern pattern2
) {
return pattern1.match(functionOperator.getParameter1())
.flatMap(match1 -> pattern2.match(functionOperator.getParameter2())
.flatMap(match2 -> mergeMatches(match1, match2))
);
}
}

View File

@ -9,7 +9,6 @@ import it.cavallium.warppi.math.functions.equations.EquationsSystem;
import it.cavallium.warppi.math.functions.equations.EquationsSystemPart; import it.cavallium.warppi.math.functions.equations.EquationsSystemPart;
import it.cavallium.warppi.math.functions.trigonometry.*; import it.cavallium.warppi.math.functions.trigonometry.*;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -22,41 +21,6 @@ public abstract class VisitorPattern implements Pattern, FunctionVisitor<Optiona
return function.accept(this); return function.accept(this);
} }
/**
* Gathers captured sub-functions from two matches, checking for equality
* of ones with the same name.
*
* @param match1 Sub-functions from one match.
* @param match2 Sub-functions from the other match.
* @return A <code>Map</code> containing all sub-functions, or an empty
* <code>Optional</code> if the same name is used to refer to
* non-equal sub-functions in the two matches.
*/
protected Optional<Map<String, Function>> mergeMatches(
final Map<String, Function> match1,
final Map<String, Function> match2
) {
if (!checkSubFunctionEquality(match1, match2)) {
return Optional.empty();
}
final Map<String, Function> merged = new HashMap<>();
merged.putAll(match1);
merged.putAll(match2);
return Optional.of(merged);
}
private boolean checkSubFunctionEquality(final Map<String, Function> match1, final Map<String, Function> match2) {
for (Map.Entry<String, Function> leftSubFunction : match1.entrySet()) {
final String key = leftSubFunction.getKey();
if (match2.containsKey(key)
&& !match2.get(key).equals(leftSubFunction.getValue())) {
return false;
}
}
return true;
}
@Override @Override
public Optional<Map<String, Function>> visit(final ArcCosine arcCosine) { public Optional<Map<String, Function>> visit(final ArcCosine arcCosine) {
return Optional.empty(); return Optional.empty();

View File

@ -4,6 +4,7 @@ import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext; import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.functions.Sum; import it.cavallium.warppi.math.functions.Sum;
import it.cavallium.warppi.math.rules.dsl.Pattern; 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 it.cavallium.warppi.math.rules.dsl.VisitorPattern;
import java.util.Map; import java.util.Map;
@ -23,10 +24,7 @@ public class SumPattern extends VisitorPattern {
@Override @Override
public Optional<Map<String, Function>> visit(final Sum sum) { public Optional<Map<String, Function>> visit(final Sum sum) {
return left.match(sum.getParameter1()) return PatternUtils.matchFunctionOperatorParameters(sum, left, right);
.flatMap(leftMatch -> right.match(sum.getParameter2())
.flatMap(rightMatch -> mergeMatches(leftMatch, rightMatch))
);
} }
@Override @Override