From 528e94966e98b1ae66e1254df4a3d77d544ca39c Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Wed, 7 Feb 2018 22:06:40 +0100 Subject: [PATCH] Added more rules --- .../gui/expression/blocks/BlockChar.java | 1 + .../gui/expression/blocks/BlockUndefined.java | 62 +++++++++++ .../warp/picalculator/math/MathSolver.java | 59 +++++----- .../math/MathematicalSymbols.java | 3 +- .../math/functions/Undefined.java | 15 ++- .../math/rules/FractionsRule12.java | 49 --------- .../math/rules/FractionsRule14.java | 84 -------------- .../picalculator/math/rules/NumberRule1.java | 44 -------- .../picalculator/math/rules/NumberRule2.java | 63 ----------- .../picalculator/math/rules/NumberRule3.java | 60 ---------- .../picalculator/math/rules/NumberRule4.java | 37 ------- .../picalculator/math/rules/NumberRule5.java | 46 -------- .../picalculator/math/rules/NumberRule7.java | 33 ------ .../picalculator/math/rules/RuleType.java | 17 ++- .../picalculator/math/rules/RulesManager.java | 2 +- .../math/rules/UndefinedRule1.java | 37 ------- .../math/rules/UndefinedRule2.java | 40 ------- .../math/rules/VariableRule1.java | 63 ----------- .../math/rules/VariableRule2.java | 52 --------- .../math/rules/VariableRule3.java | 53 --------- src/main/resources/rules.csv | 13 +++ src/main/resources/rules/FractionsRule12.js | 68 ++++++++++++ src/main/resources/rules/FractionsRule14.js | 104 ++++++++++++++++++ src/main/resources/rules/NumberRule1.js | 64 +++++++++++ src/main/resources/rules/NumberRule2.js | 83 ++++++++++++++ src/main/resources/rules/NumberRule3.js | 80 ++++++++++++++ src/main/resources/rules/NumberRule4.js | 55 +++++++++ src/main/resources/rules/NumberRule5.js | 71 ++++++++++++ src/main/resources/rules/NumberRule7.js | 54 +++++++++ src/main/resources/rules/UndefinedRule1.js | 57 ++++++++++ src/main/resources/rules/UndefinedRule2.js | 60 ++++++++++ src/main/resources/rules/VariableRule1.js | 83 ++++++++++++++ src/main/resources/rules/VariableRule2.js | 72 ++++++++++++ src/main/resources/rules/VariableRule3.js | 73 ++++++++++++ 34 files changed, 1064 insertions(+), 693 deletions(-) create mode 100644 src/main/java/org/warp/picalculator/gui/expression/blocks/BlockUndefined.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/NumberRule1.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/NumberRule2.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/NumberRule3.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/NumberRule4.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/NumberRule5.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/NumberRule7.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/UndefinedRule1.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/UndefinedRule2.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/VariableRule1.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/VariableRule2.java delete mode 100755 src/main/java/org/warp/picalculator/math/rules/VariableRule3.java create mode 100644 src/main/resources/rules/FractionsRule12.js create mode 100644 src/main/resources/rules/FractionsRule14.js create mode 100644 src/main/resources/rules/NumberRule1.js create mode 100644 src/main/resources/rules/NumberRule2.js create mode 100644 src/main/resources/rules/NumberRule3.js create mode 100644 src/main/resources/rules/NumberRule4.js create mode 100644 src/main/resources/rules/NumberRule5.js create mode 100644 src/main/resources/rules/NumberRule7.js create mode 100644 src/main/resources/rules/UndefinedRule1.js create mode 100644 src/main/resources/rules/UndefinedRule2.js create mode 100644 src/main/resources/rules/VariableRule1.js create mode 100644 src/main/resources/rules/VariableRule2.js create mode 100644 src/main/resources/rules/VariableRule3.js diff --git a/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockChar.java b/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockChar.java index 664eaa88..74cbb049 100755 --- a/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockChar.java +++ b/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockChar.java @@ -4,6 +4,7 @@ import org.warp.picalculator.gui.expression.Caret; import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.parser.features.FeatureChar; import org.warp.picalculator.math.parser.features.interfaces.Feature; diff --git a/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockUndefined.java b/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockUndefined.java new file mode 100644 index 00000000..fd2dde36 --- /dev/null +++ b/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockUndefined.java @@ -0,0 +1,62 @@ +package org.warp.picalculator.gui.expression.blocks; + +import org.warp.picalculator.gui.expression.Caret; +import org.warp.picalculator.gui.graphicengine.GraphicEngine; +import org.warp.picalculator.gui.graphicengine.Renderer; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.MathematicalSymbols; +import org.warp.picalculator.math.parser.features.FeatureChar; +import org.warp.picalculator.math.parser.features.interfaces.Feature; + +public class BlockUndefined extends Block { + + public BlockUndefined() { + recomputeDimensions(); + } + + @Override + public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) { + BlockContainer.getDefaultFont(small).use(ge); + r.glColor(BlockContainer.getDefaultColor()); + r.glDrawStringLeft(x, y, "UNDEFINED"); + } + + @Override + public boolean putBlock(Caret caret, Block newBlock) { + return false; + } + + @Override + public boolean delBlock(Caret caret) { + return false; + } + + @Override + public Block getBlock(Caret caret) { + return null; + } + + @Override + public void recomputeDimensions() { + width = BlockContainer.getDefaultFont(small).getStringWidth("UNDEFINED"); + height = BlockContainer.getDefaultCharHeight(small); + line = height / 2; + } + + @Override + public void setSmall(boolean small) { + this.small = small; + recomputeDimensions(); + } + + @Override + public int computeCaretMaxBound() { + return 0; + } + + @Override + public Feature toFeature(MathContext context) { + return new FeatureChar(MathematicalSymbols.UNDEFINED); + } + +} diff --git a/src/main/java/org/warp/picalculator/math/MathSolver.java b/src/main/java/org/warp/picalculator/math/MathSolver.java index 33edb497..76e17874 100644 --- a/src/main/java/org/warp/picalculator/math/MathSolver.java +++ b/src/main/java/org/warp/picalculator/math/MathSolver.java @@ -19,9 +19,9 @@ public class MathSolver { private int consecutiveNullSteps = 0; private enum StepState { _1_CALCULATION, - _2_REDUCTION, + _2_EXPANSION, _3_CALCULATION, - _4_EXPANSION + _4_REDUCTION } private final StepState[] stepStates = StepState.values(); @SuppressWarnings("unchecked") @@ -73,45 +73,33 @@ public class MathSolver { } private ObjectArrayList solveStep(ObjectArrayList fncs) throws InterruptedException, Error { + ObjectArrayList processedFncs = applyRules(fncs, RuleType.EXISTENCE); // Apply existence rules before everything + if (processedFncs != null) { + fncs = processedFncs; + } RuleType currentAcceptedRules; switch(stepStates[stepState]) { case _1_CALCULATION: { currentAcceptedRules = RuleType.CALCULATION; break; } - case _2_REDUCTION: { - currentAcceptedRules = RuleType.REDUCTION; + case _2_EXPANSION: { + currentAcceptedRules = RuleType.EXPANSION; break; } case _3_CALCULATION: { currentAcceptedRules = RuleType.CALCULATION; break; } - case _4_EXPANSION: { - currentAcceptedRules = RuleType.EXPANSION; + case _4_REDUCTION: { + currentAcceptedRules = RuleType.REDUCTION; break; } default: System.err.println("Unknown Step State"); throw new NotImplementedException(); } - ObjectArrayList rules = initialFunction.getMathContext().getAcceptableRules(currentAcceptedRules); - ObjectArrayList results = null; - Rule appliedRule = null; - for (Function fnc : fncs) { - for (Rule rule : rules) { - List ruleResults = fnc.simplify(rule); - if (ruleResults != null && !ruleResults.isEmpty()) { - if (results == null) results = new ObjectArrayList(); - results.addAll(ruleResults); - appliedRule = rule; - break; - } - } - } - if (StaticVars.debugOn & results != null & appliedRule != null) { - Utils.out.println(Utils.OUTPUTLEVEL_NODEBUG, stepStates[stepState].toString().substring(3) + ": " + appliedRule.getRuleName()); - } + ObjectArrayList results = applyRules(fncs, currentAcceptedRules); switch(stepStates[stepState]) { case _1_CALCULATION: { if (results == null) { @@ -125,7 +113,7 @@ public class MathSolver { } break; } - case _2_REDUCTION: { + case _2_EXPANSION: { if (results == null) { if (currentStepStateN == 0) { stepState += 2; @@ -154,7 +142,7 @@ public class MathSolver { } break; } - case _4_EXPANSION: { + case _4_REDUCTION: { if (results == null) { stepState = 1; consecutiveNullSteps++; @@ -173,4 +161,25 @@ public class MathSolver { } return null; } + + private ObjectArrayList applyRules(ObjectArrayList fncs, RuleType currentAcceptedRules) throws InterruptedException, Error { + ObjectArrayList rules = initialFunction.getMathContext().getAcceptableRules(currentAcceptedRules); + ObjectArrayList results = null; + Rule appliedRule = null; + for (Function fnc : fncs) { + for (Rule rule : rules) { + List ruleResults = fnc.simplify(rule); + if (ruleResults != null && !ruleResults.isEmpty()) { + if (results == null) results = new ObjectArrayList(); + results.addAll(ruleResults); + appliedRule = rule; + break; + } + } + } + if (StaticVars.debugOn & results != null & appliedRule != null) { + Utils.out.println(Utils.OUTPUTLEVEL_NODEBUG, stepStates[stepState].toString().substring(3) + ": " + appliedRule.getRuleName()); + } + return results; + } } diff --git a/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java b/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java index 96ed1150..fc2f4af2 100755 --- a/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java +++ b/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java @@ -25,6 +25,7 @@ public class MathematicalSymbols { public static final char ARC_SINE = 'Ⓕ'; public static final char ARC_COSINE = 'Ⓖ'; public static final char ARC_TANGENT = 'Ⓗ'; + public static final char UNDEFINED = '∅'; public static final char PI = 'π'; public static final char[] functionsNSN = new char[] { NTH_ROOT, POWER }; @@ -48,7 +49,7 @@ public class MathematicalSymbols { public static final char[] parentheses = new char[] { PARENTHESIS_OPEN, PARENTHESIS_CLOSE }; - public static final char[] variables = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'ⓧ', 'Ⓨ', 'Z', PI }; + public static final char[] variables = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'ⓧ', 'Ⓨ', 'Z', PI, UNDEFINED }; public static final char[] genericSyntax = new char[] { SYSTEM, EQUATION }; diff --git a/src/main/java/org/warp/picalculator/math/functions/Undefined.java b/src/main/java/org/warp/picalculator/math/functions/Undefined.java index 4f8153a3..b7849532 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Undefined.java +++ b/src/main/java/org/warp/picalculator/math/functions/Undefined.java @@ -5,8 +5,11 @@ import java.util.List; import org.warp.picalculator.Error; import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; +import org.warp.picalculator.gui.expression.blocks.BlockChar; +import org.warp.picalculator.gui.expression.blocks.BlockUndefined; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -53,9 +56,15 @@ public class Undefined implements Function { } @Override - public ObjectArrayList toBlock(MathContext context) throws Error { - // TODO Auto-generated method stub - throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + getClass().getSimpleName()); + public ObjectArrayList toBlock(MathContext context) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new BlockUndefined()); + return result; + } + + @Override + public String toString() { + return "UNDEFINED"; } } diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java deleted file mode 100755 index f6a623e5..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * (b / c) / a = b / (a * c) - * - * @author Andrea Cavalli - * - */ -public class FractionsRule12 { - - public static boolean compare(Function f) throws InterruptedException { - final Division fnc = (Division) f; - Function a; - Function c; - if (fnc.getParameter1() instanceof Division) { - final Division div2 = (Division) fnc.getParameter1(); - a = fnc.getParameter1(); - c = div2.getParameter2(); - return new Multiplication(fnc.getMathContext(), a, c).simplify(this) != null; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final Division fnc = (Division) f; - Function a; - Function b; - Function c; - - final Division div2 = (Division) fnc.getParameter1(); - a = fnc.getParameter2(); - b = div2.getParameter1(); - c = div2.getParameter2(); - result.add(new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), b)); - - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java deleted file mode 100755 index 42d15aaf..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Multiplication; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * (a / b) * (c / d) = (a * c) / (b * d) - * - * @author Andrea Cavalli - * - */ -public class FractionsRule14 { - - public static boolean compare(Function f) throws InterruptedException { - final Multiplication fnc = (Multiplication) f; - Function a; - Function b; - Function c; - Function d; - if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Division) { - final Division div1 = (Division) fnc.getParameter1(); - final Division div2 = (Division) fnc.getParameter2(); - a = div1.getParameter1(); - b = div1.getParameter2(); - c = div2.getParameter1(); - d = div2.getParameter2(); - return new Multiplication(f.getMathContext(), a, c).simplify(this) != null || new Multiplication(f.getMathContext(), b, d).isSimplified() == false; - } else if (fnc.getParameter1() instanceof Division) { - final Division div1 = (Division) fnc.getParameter1(); - a = div1.getParameter1(); - b = div1.getParameter2(); - c = fnc.getParameter2(); - return new Multiplication(f.getMathContext(), a, c).simplify(this) != null; - } else if (fnc.getParameter2() instanceof Division) { - final Division div2 = (Division) fnc.getParameter2(); - a = fnc.getParameter1(); - c = div2.getParameter1(); - d = div2.getParameter2(); - return new Multiplication(f.getMathContext(), a, c).simplify(this) != null; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication fnc = (Multiplication) f; - Function a; - Function b; - Function c; - Function d; - - if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Division) { - final Division div1 = (Division) fnc.getParameter1(); - final Division div2 = (Division) fnc.getParameter2(); - a = div1.getParameter1(); - b = div1.getParameter2(); - c = div2.getParameter1(); - d = div2.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), new Multiplication(fnc.getMathContext(), b, d)); - result.add(div); - } else if (fnc.getParameter1() instanceof Division) { - final Division div1 = (Division) fnc.getParameter1(); - a = div1.getParameter1(); - b = div1.getParameter2(); - c = fnc.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), b); - result.add(div); - } else if (fnc.getParameter2() instanceof Division) { - final Division div2 = (Division) fnc.getParameter2(); - a = fnc.getParameter1(); - c = div2.getParameter1(); - d = div2.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), d); - result.add(div); - } - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule1.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule1.java deleted file mode 100755 index 29cf7029..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule1.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a * 0 = 0 - * - * @author Andrea Cavalli - * - */ -public class NumberRule1 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Multiplication mult = (Multiplication) f; - if (mult.getParameter1() instanceof Number) { - final Number numb = (Number) mult.getParameter1(); - if (numb.equals(new Number(root, 0))) { - return true; - } - } - if (mult.getParameter2() instanceof Number) { - final Number numb = (Number) mult.getParameter2(); - if (numb.equals(new Number(root, 0))) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Number(f.getMathContext(), "0")); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule2.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule2.java deleted file mode 100755 index 817fadb0..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule2.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a * 1 = a - * - * @author Andrea Cavalli - * - */ -public class NumberRule2 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Multiplication mult = (Multiplication) f; - if (mult.getParameter1() instanceof Number) { - final Number numb = (Number) mult.getParameter1(); - if (numb.equals(new Number(root, 1))) { - return true; - } - } - if (mult.getParameter2() instanceof Number) { - final Number numb = (Number) mult.getParameter2(); - if (numb.equals(new Number(root, 1))) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - Function a = null; - boolean aFound = false; - final Multiplication mult = (Multiplication) f; - if (aFound == false & mult.getParameter1() instanceof Number) { - final Number numb = (Number) mult.getParameter1(); - if (numb.equals(new Number(root, 1))) { - a = mult.getParameter2(); - aFound = true; - } - } - if (aFound == false && mult.getParameter2() instanceof Number) { - final Number numb = (Number) mult.getParameter2(); - if (numb.equals(new Number(root, 1))) { - a = mult.getParameter1(); - aFound = true; - } - } - - result.add(a); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule3.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule3.java deleted file mode 100755 index edc8a816..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule3.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Negative; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; -import org.warp.picalculator.math.functions.SumSubtraction; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a - a = 0
- * -a + a = 0
- * a ± a = {0, 2a} - * - * @author Andrea Cavalli - * - */ -public class NumberRule3 { - - public static boolean compare(Function f) { - if (f instanceof Subtraction) { - final Subtraction sub = (Subtraction) f; - if (sub.getParameter1().equals(sub.getParameter2())) { - return true; - } - } else if (f instanceof Sum) { - final Sum sub = (Sum) f; - if (sub.getParameter1() instanceof Negative) { - final Negative neg = (Negative) sub.getParameter1(); - if (neg.getParameter().equals(sub.getParameter2())) { - return true; - } - } - } else if (f instanceof SumSubtraction) { - final SumSubtraction sub = (SumSubtraction) f; - if (sub.getParameter1().equals(sub.getParameter2())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - if (f instanceof SumSubtraction) { - final Multiplication mul = new Multiplication(root, new Number(root, 2), ((SumSubtraction) f).getParameter1()); - result.add(mul); - } - result.add(new Number(root, 0)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule4.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule4.java deleted file mode 100755 index c90ffbb9..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule4.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; -import org.warp.picalculator.math.functions.SumSubtraction; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a ± b = {a+b, a-b} - * - * @author Andrea Cavalli - * - */ -public class NumberRule4 { - - public static boolean compare(Function f) { - if (f instanceof SumSubtraction) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final SumSubtraction ss = (SumSubtraction) f; - result.add(new Sum(root, ss.getParameter1(), ss.getParameter2())); - result.add(new Subtraction(root, ss.getParameter1(), ss.getParameter2())); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule5.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule5.java deleted file mode 100755 index 5874f46e..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule5.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionOperator; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a + 0 = a
- * 0 + a = a
- * a - 0 = a
- * 0 - a = a
- * a ± 0 = a
- * 0 ± a = a - * - * @author Andrea Cavalli - * - */ -public class NumberRule5 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final FunctionOperator fnc = (FunctionOperator) f; - if (fnc.getParameter1().equals(new Number(root, 0)) || fnc.getParameter2().equals(new Number(root, 0))) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final FunctionOperator fnc = (FunctionOperator) f; - Function a = fnc.getParameter1(); - if (a.equals(new Number(root, 0))) { - a = fnc.getParameter2(); - } - result.add(a); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule7.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule7.java deleted file mode 100755 index 3fc042a5..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule7.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a + a = 2a - * - * @author Andrea Cavalli - * - */ -public class NumberRule7 { - - public static boolean compare(Sum f) { - return f.getParameter1().equals(f.getParameter2()); - } - - public static ObjectArrayList execute(Sum f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication mult = new Multiplication(root, new Number(root, 2), f.getParameter1()); - result.add(mult); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/RuleType.java b/src/main/java/org/warp/picalculator/math/rules/RuleType.java index a3130b27..3a8db9a9 100644 --- a/src/main/java/org/warp/picalculator/math/rules/RuleType.java +++ b/src/main/java/org/warp/picalculator/math/rules/RuleType.java @@ -1,7 +1,20 @@ package org.warp.picalculator.math.rules; public enum RuleType { - EXPANSION, + /** + * A rule that tries to factorize and group a polynomial expression into a shorter expression + */ REDUCTION, - CALCULATION + /** + * A rule that tries to transform an expression to a simple polynomial expression + */ + EXPANSION, + /** + * Calculation + */ + CALCULATION, + /** + * Existence + */ + EXISTENCE } diff --git a/src/main/java/org/warp/picalculator/math/rules/RulesManager.java b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java index 418a01e4..377f60e7 100644 --- a/src/main/java/org/warp/picalculator/math/rules/RulesManager.java +++ b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java @@ -117,6 +117,6 @@ public class RulesManager { public static void addRule(Rule rule) { rules[rule.getRuleType().ordinal()].add(rule); - Utils.out.println(Utils.OUTPUTLEVEL_NODEBUG, "Loaded rule " + rule.getRuleName()); + Utils.out.println(Utils.OUTPUTLEVEL_NODEBUG, "Loaded rule " + rule.getRuleName() + " as " + rule.getRuleType() + " rule."); } } diff --git a/src/main/java/org/warp/picalculator/math/rules/UndefinedRule1.java b/src/main/java/org/warp/picalculator/math/rules/UndefinedRule1.java deleted file mode 100755 index 4444e571..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/UndefinedRule1.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; -import org.warp.picalculator.math.functions.Undefined; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Undefined rule
- * 0^0=undefined - * - * @author Andrea Cavalli - * - */ -public class UndefinedRule1 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Power fnc = (Power) f; - if (fnc.getParameter1().equals(new Number(root, 0)) && fnc.getParameter2().equals(new Number(root, 0))) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Undefined(root)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/UndefinedRule2.java b/src/main/java/org/warp/picalculator/math/rules/UndefinedRule2.java deleted file mode 100755 index 4222e728..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/UndefinedRule2.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Undefined; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Undefined rule
- * a / 0 = undefined - * - * @author Andrea Cavalli - * - */ -public class UndefinedRule2 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Division fnc = (Division) f; - if (fnc.getParameter2() instanceof Number) { - final Number numb = (Number) fnc.getParameter2(); - if (numb.equals(new Number(root, 0))) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Undefined(root)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/VariableRule1.java b/src/main/java/org/warp/picalculator/math/rules/VariableRule1.java deleted file mode 100755 index 97e13fdf..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/VariableRule1.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionOperator; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Variable rule
- * ax+bx=(a+b)*x (a,b NUMBER; x VARIABLE|MULTIPLICATION) - * - * @author Andrea Cavalli - * - */ -public class VariableRule1 { - - public static boolean compare(FunctionOperator fnc) { - if (fnc.getParameter1() instanceof Multiplication & fnc.getParameter2() instanceof Multiplication) { - final Multiplication m1 = (Multiplication) fnc.getParameter1(); - final Multiplication m2 = (Multiplication) fnc.getParameter2(); - if (m1.getParameter1().equals(m2.getParameter1()) || m1.getParameter2().equals(m2.getParameter2())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(FunctionOperator fnc) throws Error { - final MathContext root = fnc.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication m1 = (Multiplication) fnc.getParameter1(); - final Multiplication m2 = (Multiplication) fnc.getParameter2(); - final Function a; - final Function b; - final Function x; - if (m1.getParameter2().equals(m2.getParameter2())) { - x = m1.getParameter2(); - a = m1.getParameter1(); - b = m2.getParameter1(); - } else { - x = m1.getParameter1(); - a = m1.getParameter2(); - b = m2.getParameter2(); - } - - FunctionOperator rets; - if (fnc instanceof Sum) { - rets = new Sum(root, a, b); - } else { - rets = new Subtraction(root, a, b); - } - final Multiplication retm = new Multiplication(root, rets, x); - result.add(retm); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/VariableRule2.java b/src/main/java/org/warp/picalculator/math/rules/VariableRule2.java deleted file mode 100755 index 5409dbb6..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/VariableRule2.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionOperator; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Variable rule
- * ax+x=(a+1)*x (a,b NUMBER; x VARIABLES) - * - * @author Andrea Cavalli - * - */ -public class VariableRule2 { - - public static boolean compare(FunctionOperator fnc) { - if (fnc.getParameter1() instanceof Multiplication) { - final Multiplication m1 = (Multiplication) fnc.getParameter1(); - if (m1.getParameter2().equals(fnc.getParameter2())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(FunctionOperator fnc) throws Error { - final MathContext root = fnc.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication m1 = (Multiplication) fnc.getParameter1(); - final Function a = m1.getParameter1(); - final Function x = fnc.getParameter2(); - - FunctionOperator rets; - if (fnc instanceof Sum) { - rets = new Sum(root, a, new Number(root, 1)); - } else { - rets = new Subtraction(root, a, new Number(root, 1)); - } - final Multiplication retm = new Multiplication(root, rets, x); - result.add(retm); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/VariableRule3.java b/src/main/java/org/warp/picalculator/math/rules/VariableRule3.java deleted file mode 100755 index 6d378c3c..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/VariableRule3.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionOperator; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Variable rule
- * x+ax=(a+1)*x (a,b NUMBER; x VARIABLES) - * - * @author Andrea Cavalli - * - */ -public class VariableRule3 { - - public static boolean compare(FunctionOperator fnc) { - if (fnc.getParameter2() instanceof Multiplication) { - final Multiplication m2 = (Multiplication) fnc.getParameter2(); - if (m2.getParameter2().equals(fnc.getParameter1())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(FunctionOperator fnc) throws Error { - final MathContext root = fnc.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication m2 = (Multiplication) fnc.getParameter2(); - final Function a = m2.getParameter1(); - final Function x = fnc.getParameter1(); - - FunctionOperator rets; - if (fnc instanceof Sum) { - rets = new Sum(root, new Number(root, 1), a); - } else { - rets = new Subtraction(root, new Number(root, 1), a); - } - - final Multiplication retm = new Multiplication(root, rets, x); - result.add(retm); - return result; - } - -} diff --git a/src/main/resources/rules.csv b/src/main/resources/rules.csv index ae79e057..9dd05b34 100644 --- a/src/main/resources/rules.csv +++ b/src/main/resources/rules.csv @@ -29,3 +29,16 @@ FractionsRule3 FractionsRule4 FractionsRule5 FractionsRule11 +FractionsRule12 +FractionsRule14 +NumberRule1 +NumberRule2 +NumberRule3 +NumberRule4 +NumberRule5 +NumberRule7 +UndefinedRule1 +UndefinedRule2 +VariableRule1 +VariableRule2 +VariableRule3 diff --git a/src/main/resources/rules/FractionsRule12.js b/src/main/resources/rules/FractionsRule12.js new file mode 100644 index 00000000..a8261e9f --- /dev/null +++ b/src/main/resources/rules/FractionsRule12.js @@ -0,0 +1,68 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var Division = org.warp.picalculator.math.functions.Division; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Fractions rule + * (b / c) / a = b / (a * c) + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "FractionsRule12"; + }, + // Rule type + getRuleType: function() { + return RuleType.EXPANSION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Division.class)) { + var fnc = f; + var a; + var c; + if (ScriptUtils.instanceOf(fnc.getParameter1(), Division.class)) { + var div2 = fnc.getParameter1(); + a = fnc.getParameter1(); + c = div2.getParameter2(); + isExecutable = true; + } + } + + if (isExecutable) { + var result = new ObjectArrayList(); + var fnc = f; + var a; + var b; + var c; + + var div2 = fnc.getParameter1(); + a = fnc.getParameter2(); + b = div2.getParameter1(); + c = div2.getParameter2(); + result.add(new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), b)); + + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/FractionsRule14.js b/src/main/resources/rules/FractionsRule14.js new file mode 100644 index 00000000..e9cb0e42 --- /dev/null +++ b/src/main/resources/rules/FractionsRule14.js @@ -0,0 +1,104 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var Division = org.warp.picalculator.math.functions.Division; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Fractions rule + * (a / b) * (c / d) = (a * c) / (b * d) + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "FractionsRule14"; + }, + // Rule type + getRuleType: function() { + return RuleType.EXPANSION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Multiplication.class)) { + var fnc = f; + var a; + var b; + var c; + var d; + if (ScriptUtils.instanceOf(fnc.getParameter1(), Division.class) && ScriptUtils.instanceOf(fnc.getParameter2(), Division.class)) { + var div1 = fnc.getParameter1(); + var div2 = fnc.getParameter2(); + a = div1.getParameter1(); + b = div1.getParameter2(); + c = div2.getParameter1(); + d = div2.getParameter2(); + isExecutable = true; + } else if (ScriptUtils.instanceOf(fnc.getParameter1(), Division.class)) { + var div1 = fnc.getParameter1(); + a = div1.getParameter1(); + b = div1.getParameter2(); + c = fnc.getParameter2(); + isExecutable = true; + } else if (ScriptUtils.instanceOf(fnc.getParameter2(), Division.class)) { + var div2 = fnc.getParameter2(); + a = fnc.getParameter1(); + c = div2.getParameter1(); + d = div2.getParameter2(); + isExecutable = true; + } + } + + if (isExecutable) { + var result = new ObjectArrayList(); + var fnc = f; + var a; + var b; + var c; + var d; + + if (ScriptUtils.instanceOf(fnc.getParameter1(), Division.class) && ScriptUtils.instanceOf(fnc.getParameter2(), Division.class)) { + var div1 = fnc.getParameter1(); + var div2 = fnc.getParameter2(); + a = div1.getParameter1(); + b = div1.getParameter2(); + c = div2.getParameter1(); + d = div2.getParameter2(); + var div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), new Multiplication(fnc.getMathContext(), b, d)); + result.add(div); + } else if (ScriptUtils.instanceOf(fnc.getParameter1(), Division.class)) { + var div1 = fnc.getParameter1(); + a = div1.getParameter1(); + b = div1.getParameter2(); + c = fnc.getParameter2(); + var div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), b); + result.add(div); + } else if (ScriptUtils.instanceOf(fnc.getParameter2(), Division.class)) { + var div2 = fnc.getParameter2(); + a = fnc.getParameter1(); + c = div2.getParameter1(); + d = div2.getParameter2(); + var div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), d); + result.add(div); + } + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/NumberRule1.js b/src/main/resources/rules/NumberRule1.js new file mode 100644 index 00000000..f15979bf --- /dev/null +++ b/src/main/resources/rules/NumberRule1.js @@ -0,0 +1,64 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var MathContext = org.warp.picalculator.math.MathContext; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Number = org.warp.picalculator.math.functions.Number; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Number rule + * a * 0 = 0 + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "NumberRule1"; + }, + // Rule type + getRuleType: function() { + return RuleType.CALCULATION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Multiplication.class)) { + var root = f.getMathContext(); + var mult = f; + if (ScriptUtils.instanceOf(mult.getParameter1(), Number.class)) { + var numb = mult.getParameter1(); + if (numb.equals(new Number(root, 0))) { + isExecutable = true; + } + } + if (ScriptUtils.instanceOf(mult.getParameter2(), Number.class)) { + var numb = mult.getParameter2(); + if (numb.equals(new Number(root, 0))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + var result = new ObjectArrayList(); + result.add(new Number(f.getMathContext(), "0")); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/NumberRule2.js b/src/main/resources/rules/NumberRule2.js new file mode 100644 index 00000000..28500067 --- /dev/null +++ b/src/main/resources/rules/NumberRule2.js @@ -0,0 +1,83 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var MathContext = org.warp.picalculator.math.MathContext; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Number = org.warp.picalculator.math.functions.Number; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Number rule + * a * 1 = a + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "NumberRule2"; + }, + // Rule type + getRuleType: function() { + return RuleType.CALCULATION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Multiplication.class)) { + var root = f.getMathContext(); + var mult = f; + if (ScriptUtils.instanceOf(mult.getParameter1(), Number.class)) { + var numb = mult.getParameter1(); + if (numb.equals(new Number(root, 1))) { + isExecutable = true; + } + } + if (ScriptUtils.instanceOf(mult.getParameter2(), Number.class)) { + var numb = mult.getParameter2(); + if (numb.equals(new Number(root, 1))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + var root = f.getMathContext(); + var result = new ObjectArrayList(); + var a = null; + var aFound = false; + var mult = f; + if (aFound == false & ScriptUtils.instanceOf(mult.getParameter1(), Number.class)) { + var numb = mult.getParameter1(); + if (numb.equals(new Number(root, 1))) { + a = mult.getParameter2(); + aFound = true; + } + } + if (aFound == false && ScriptUtils.instanceOf(mult.getParameter2(), Number.class)) { + var numb = mult.getParameter2(); + if (numb.equals(new Number(root, 1))) { + a = mult.getParameter1(); + aFound = true; + } + } + + result.add(a); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/NumberRule3.js b/src/main/resources/rules/NumberRule3.js new file mode 100644 index 00000000..93acfaff --- /dev/null +++ b/src/main/resources/rules/NumberRule3.js @@ -0,0 +1,80 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var MathContext = org.warp.picalculator.math.MathContext; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Negative = org.warp.picalculator.math.functions.Negative; +var Number = org.warp.picalculator.math.functions.Number; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var Sum = org.warp.picalculator.math.functions.Sum; +var SumSubtraction = org.warp.picalculator.math.functions.SumSubtraction; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Number rule + * a - a = 0 + * -a + a = 0 + * a ± a = {0, 2a} + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "NumberRule3"; + }, + // Rule type + getRuleType: function() { + return RuleType.CALCULATION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Subtraction.class)) { + var sub = f; + if (sub.getParameter1().equals(sub.getParameter2())) { + isExecutable = true; + } + } else if (ScriptUtils.instanceOf(f, Sum.class)) { + var sub = f; + if (ScriptUtils.instanceOf(sub.getParameter1(), Multiplication.class)) { + if (ScriptUtils.instanceOf(sub.getParameter1().getParameter1(), Number.class) && sub.getParameter1().getParameter1().equals(new Number(f.getMathContext(), -1))) { + var neg = sub.getParameter1().getParameter2(); + if (neg.equals(sub.getParameter2())) { + isExecutable = true; + } + } + } + } else if (ScriptUtils.instanceOf(f, SumSubtraction.class)) { + var sub = f; + if (sub.getParameter1().equals(sub.getParameter2())) { + isExecutable = true; + } + } + + if (isExecutable) { + var root = f.getMathContext(); + var result = new ObjectArrayList(); + if (ScriptUtils.instanceOf(f, SumSubtraction.class)) { + var mul = new Multiplication(root, new Number(root, 2), f.getParameter1()); + result.add(mul); + } + result.add(new Number(root, 0)); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/NumberRule4.js b/src/main/resources/rules/NumberRule4.js new file mode 100644 index 00000000..6db37fe8 --- /dev/null +++ b/src/main/resources/rules/NumberRule4.js @@ -0,0 +1,55 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var MathContext = org.warp.picalculator.math.MathContext; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var Sum = org.warp.picalculator.math.functions.Sum; +var SumSubtraction = org.warp.picalculator.math.functions.SumSubtraction; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Number rule + * a ± b = {a+b, a-b} + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "NumberRule4"; + }, + // Rule type + getRuleType: function() { + return RuleType.EXPANSION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, SumSubtraction.class)) { + isExecutable = true; + } + + if (isExecutable) { + var root = f.getMathContext(); + var result = new ObjectArrayList(); + var ss = f; + result.add(new Sum(root, ss.getParameter1(), ss.getParameter2())); + result.add(new Subtraction(root, ss.getParameter1(), ss.getParameter2())); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/NumberRule5.js b/src/main/resources/rules/NumberRule5.js new file mode 100644 index 00000000..2e3d25aa --- /dev/null +++ b/src/main/resources/rules/NumberRule5.js @@ -0,0 +1,71 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var FunctionOperator = org.warp.picalculator.math.FunctionOperator; +var MathContext = org.warp.picalculator.math.MathContext; +var Number = org.warp.picalculator.math.functions.Number; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Number rule + * a + 0 = a + * 0 + a = a + * a - 0 = a + * 0 - a = -a + * a ± 0 = a + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "NumberRule5"; + }, + // Rule type + getRuleType: function() { + return RuleType.CALCULATION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Sum.class) || ScriptUtils.instanceOf(f, Subtraction.class) || ScriptUtils.instanceOf(f, SumSubtraction.class)) { + var root = f.getMathContext(); + var fnc = f; + if (fnc.getParameter1().equals(new Number(root, 0)) || fnc.getParameter2().equals(new Number(root, 0))) { + if (!(fnc.getParameter1().equals(new Number(root, 0)) && ScriptUtils.instanceOf(f, SumSubtraction.class))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + var root = f.getMathContext(); + var result = new ObjectArrayList(); + var fnc = f; + var a = fnc.getParameter1(); + if (a.equals(new Number(root, 0))) { + if (ScriptUtils.instanceOf(f, Subtraction.class)) { + a = new Multiplication(root, new Number(root, -1), fnc.getParameter2()); + } else { + a = fnc.getParameter2(); + } + } + result.add(a); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/NumberRule7.js b/src/main/resources/rules/NumberRule7.js new file mode 100644 index 00000000..2d431d69 --- /dev/null +++ b/src/main/resources/rules/NumberRule7.js @@ -0,0 +1,54 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var MathContext = org.warp.picalculator.math.MathContext; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Number = org.warp.picalculator.math.functions.Number; +var Sum = org.warp.picalculator.math.functions.Sum; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Number rule + * a + a = 2a + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "NumberRule7"; + }, + // Rule type + getRuleType: function() { + return RuleType.EXPANSION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Sum.class)) { + isExecutable = f.getParameter1().equals(f.getParameter2()); + } + + if (isExecutable) { + var root = f.getMathContext(); + var result = new ObjectArrayList(); + var mult = new Multiplication(root, new Number(root, 2), f.getParameter1()); + result.add(mult); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/UndefinedRule1.js b/src/main/resources/rules/UndefinedRule1.js new file mode 100644 index 00000000..c3db7625 --- /dev/null +++ b/src/main/resources/rules/UndefinedRule1.js @@ -0,0 +1,57 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var MathContext = org.warp.picalculator.math.MathContext; +var Number = org.warp.picalculator.math.functions.Number; +var Power = org.warp.picalculator.math.functions.Power; +var Undefined = org.warp.picalculator.math.functions.Undefined; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Undefined rule + * 0^0=undefined + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "UndefinedRule1"; + }, + // Rule type + getRuleType: function() { + return RuleType.EXISTENCE; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Power.class)) { + var root = f.getMathContext(); + var fnc = f; + if (fnc.getParameter1().equals(new Number(root, 0)) && fnc.getParameter2().equals(new Number(root, 0))) { + isExecutable = true; + } + } + + if (isExecutable) { + var root = f.getMathContext(); + var result = new ObjectArrayList(); + result.add(new Undefined(root)); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/UndefinedRule2.js b/src/main/resources/rules/UndefinedRule2.js new file mode 100644 index 00000000..fbecdb0c --- /dev/null +++ b/src/main/resources/rules/UndefinedRule2.js @@ -0,0 +1,60 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var MathContext = org.warp.picalculator.math.MathContext; +var Division = org.warp.picalculator.math.functions.Division; +var Number = org.warp.picalculator.math.functions.Number; +var Undefined = org.warp.picalculator.math.functions.Undefined; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Undefined rule + * a / 0 = undefined + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "UndefinedRule2"; + }, + // Rule type + getRuleType: function() { + return RuleType.EXISTENCE; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + if (ScriptUtils.instanceOf(f, Division.class)) { + var root = f.getMathContext(); + var fnc = f; + if (ScriptUtils.instanceOf(fnc.getParameter2(), Number.class)) { + var numb = fnc.getParameter2(); + if (numb.equals(new Number(root, 0))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + var root = f.getMathContext(); + var result = new ObjectArrayList(); + result.add(new Undefined(root)); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/VariableRule1.js b/src/main/resources/rules/VariableRule1.js new file mode 100644 index 00000000..d05f56f8 --- /dev/null +++ b/src/main/resources/rules/VariableRule1.js @@ -0,0 +1,83 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var FunctionOperator = org.warp.picalculator.math.FunctionOperator; +var MathContext = org.warp.picalculator.math.MathContext; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var Sum = org.warp.picalculator.math.functions.Sum; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Variable rule + * ax+bx=(a+b)*x (a,b NUMBER; x VARIABLE|MULTIPLICATION) + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "VariableRule1"; + }, + // Rule type + getRuleType: function() { + return RuleType.REDUCTION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + var fnc = f; + if (ScriptUtils.instanceOf(f, Subtraction.class) || ScriptUtils.instanceOf(f, Sum.class)) { + if (ScriptUtils.instanceOf(fnc.getParameter1(), Multiplication.class) & ScriptUtils.instanceOf(fnc.getParameter2(), Multiplication.class)) { + var m1 = fnc.getParameter1(); + var m2 = fnc.getParameter2(); + if (m1.getParameter1().equals(m2.getParameter1()) || m1.getParameter2().equals(m2.getParameter2())) { + isExecutable = true; + } + } + } + + if (isExecutable) { + var root = fnc.getMathContext(); + var result = new ObjectArrayList(); + var m1 = fnc.getParameter1(); + var m2 = fnc.getParameter2(); + var a; + var b; + var x; + if (m1.getParameter2().equals(m2.getParameter2())) { + x = m1.getParameter2(); + a = m1.getParameter1(); + b = m2.getParameter1(); + } else { + x = m1.getParameter1(); + a = m1.getParameter2(); + b = m2.getParameter2(); + } + + var rets; + if (ScriptUtils.instanceOf(fnc, Sum.class)) { + rets = new Sum(root, a, b); + } else { + rets = new Subtraction(root, a, b); + } + var retm = new Multiplication(root, rets, x); + result.add(retm); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/VariableRule2.js b/src/main/resources/rules/VariableRule2.js new file mode 100644 index 00000000..b96ff723 --- /dev/null +++ b/src/main/resources/rules/VariableRule2.js @@ -0,0 +1,72 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var FunctionOperator = org.warp.picalculator.math.FunctionOperator; +var MathContext = org.warp.picalculator.math.MathContext; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Number = org.warp.picalculator.math.functions.Number; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var Sum = org.warp.picalculator.math.functions.Sum; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Variable rule + * ax+x=(a+1)*x (a,b NUMBER; x VARIABLES) + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "VariableRule2"; + }, + // Rule type + getRuleType: function() { + return RuleType.REDUCTION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + var fnc = f; + if (ScriptUtils.instanceOf(f, Sum.class) || ScriptUtils.instanceOf(f, Subtraction.class)) { + if (ScriptUtils.instanceOf(fnc.getParameter1(), Multiplication.class)) { + var m1 = fnc.getParameter1(); + if (m1.getParameter2().equals(fnc.getParameter2())) { + isExecutable = true; + } + } + } + + if (isExecutable) { + var root = fnc.getMathContext(); + var result = new ObjectArrayList(); + var m1 = fnc.getParameter1(); + var a = m1.getParameter1(); + var x = fnc.getParameter2(); + + var rets; + if (ScriptUtils.instanceOf(fnc, Sum.class)) { + rets = new Sum(root, a, new Number(root, 1)); + } else { + rets = new Subtraction(root, a, new Number(root, 1)); + } + var retm = new Multiplication(root, rets, x); + result.add(retm); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file diff --git a/src/main/resources/rules/VariableRule3.js b/src/main/resources/rules/VariableRule3.js new file mode 100644 index 00000000..89bd7aa9 --- /dev/null +++ b/src/main/resources/rules/VariableRule3.js @@ -0,0 +1,73 @@ +//Imports + + +var Error = org.warp.picalculator.Error; +var Function = org.warp.picalculator.math.Function; +var FunctionOperator = org.warp.picalculator.math.FunctionOperator; +var MathContext = org.warp.picalculator.math.MathContext; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Number = org.warp.picalculator.math.functions.Number; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var Sum = org.warp.picalculator.math.functions.Sum; + +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); + +/** + * Variable rule + * x+ax=(a+1)*x (a,b NUMBER; x VARIABLES) + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "VariableRule3"; + }, + // Rule type + getRuleType: function() { + return RuleType.REDUCTION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + execute: function(f) { + var isExecutable; + var fnc = f; + if (ScriptUtils.instanceOf(f, Sum.class) || ScriptUtils.instanceOf(f, Subtraction.class)) { + if (ScriptUtils.instanceOf(fnc.getParameter2(), Multiplication.class)) { + var m2 = fnc.getParameter2(); + if (m2.getParameter2().equals(fnc.getParameter1())) { + isExecutable = true; + } + } + } + + if (isExecutable) { + var root = fnc.getMathContext(); + var result = new ObjectArrayList(); + var m2 = fnc.getParameter2(); + var a = m2.getParameter1(); + var x = fnc.getParameter1(); + + var rets; + if (ScriptUtils.instanceOf(fnc, Sum.class)) { + rets = new Sum(root, new Number(root, 1), a); + } else { + rets = new Subtraction(root, new Number(root, 1), a); + } + + var retm = new Multiplication(root, rets, x); + result.add(retm); + return result; + } else { + return null; + } + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file