From 45859b266ace9da5d13f62ee233584f90f958d03 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Thu, 21 Dec 2017 23:21:29 +0100 Subject: [PATCH 1/7] new math rules --- .classpath | 2 +- src/main/java/org/warp/picalculator/Main.java | 3 +- .../org/warp/picalculator/ScriptUtils.java | 7 + .../org/warp/picalculator/StaticVars.java | 1 + .../java/org/warp/picalculator/Utils.java | 4 +- .../warp/picalculator/math/MathContext.java | 7 + .../warp/picalculator/math/MathSolver.java | 144 ++++++++++++++++++ .../warp/picalculator/math/rules/Rule.java | 33 ++++ .../picalculator/math/rules/RuleType.java | 7 + .../picalculator/math/rules/RulesManager.java | 74 +++++++++ src/main/resources/rules.csv | 3 + src/main/resources/rules/ExpandRule1.js | 128 ++++++++++++++++ src/main/resources/rules/ExpandRule2.js | 0 src/main/resources/rules/ExpandRule5.js | 0 src/main/resources/rules/_EXAMPLE RULE.js | 28 ++++ 15 files changed, 437 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/warp/picalculator/ScriptUtils.java create mode 100644 src/main/java/org/warp/picalculator/math/MathSolver.java create mode 100644 src/main/java/org/warp/picalculator/math/rules/Rule.java create mode 100644 src/main/java/org/warp/picalculator/math/rules/RuleType.java create mode 100644 src/main/java/org/warp/picalculator/math/rules/RulesManager.java create mode 100644 src/main/resources/rules.csv create mode 100644 src/main/resources/rules/ExpandRule1.js create mode 100644 src/main/resources/rules/ExpandRule2.js create mode 100644 src/main/resources/rules/ExpandRule5.js create mode 100644 src/main/resources/rules/_EXAMPLE RULE.js diff --git a/.classpath b/.classpath index e2cbd638..f227ca66 100644 --- a/.classpath +++ b/.classpath @@ -6,7 +6,7 @@ - + diff --git a/src/main/java/org/warp/picalculator/Main.java b/src/main/java/org/warp/picalculator/Main.java index 88385b02..20aae58b 100755 --- a/src/main/java/org/warp/picalculator/Main.java +++ b/src/main/java/org/warp/picalculator/Main.java @@ -1,10 +1,10 @@ package org.warp.picalculator; import org.warp.picalculator.device.Keyboard; -import org.warp.picalculator.device.Keyboard.Key; import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.screens.LoadingScreen; import org.warp.picalculator.gui.screens.Screen; +import org.warp.picalculator.math.rules.RulesManager; import com.pi4j.system.SystemInfo.BoardType; import com.pi4j.wiringpi.Gpio; @@ -81,6 +81,7 @@ public class Main { public void afterStart() { DisplayManager.INSTANCE.setBrightness(0.2f); + RulesManager.initialize(); } public void beforeShutdown() { diff --git a/src/main/java/org/warp/picalculator/ScriptUtils.java b/src/main/java/org/warp/picalculator/ScriptUtils.java new file mode 100644 index 00000000..b71e6b19 --- /dev/null +++ b/src/main/java/org/warp/picalculator/ScriptUtils.java @@ -0,0 +1,7 @@ +package org.warp.picalculator; + +public class ScriptUtils { + public static boolean instanceOf(Object a, Class b) { + return b.isInstance(a); + } +} diff --git a/src/main/java/org/warp/picalculator/StaticVars.java b/src/main/java/org/warp/picalculator/StaticVars.java index 33125c7a..f0ef99c6 100644 --- a/src/main/java/org/warp/picalculator/StaticVars.java +++ b/src/main/java/org/warp/picalculator/StaticVars.java @@ -12,6 +12,7 @@ public class StaticVars { public static boolean debugOn; public static int outputLevel = 5; public static final boolean debugWindow2x = true; + public static final ClassLoader classLoader = StaticVars.class.getClassLoader(); private StaticVars() { diff --git a/src/main/java/org/warp/picalculator/Utils.java b/src/main/java/org/warp/picalculator/Utils.java index 16c33cd3..ea284190 100755 --- a/src/main/java/org/warp/picalculator/Utils.java +++ b/src/main/java/org/warp/picalculator/Utils.java @@ -59,9 +59,9 @@ public class Utils { private static String OS = System.getProperty("os.name").toLowerCase(); public static String forceEngine; public static boolean msDosMode; - + public static final class AdvancedOutputStream extends StringWriter { - + public void println(String str) { println(0, str); } diff --git a/src/main/java/org/warp/picalculator/math/MathContext.java b/src/main/java/org/warp/picalculator/math/MathContext.java index cd03fd54..c9050545 100755 --- a/src/main/java/org/warp/picalculator/math/MathContext.java +++ b/src/main/java/org/warp/picalculator/math/MathContext.java @@ -2,6 +2,9 @@ package org.warp.picalculator.math; import org.warp.picalculator.Error; import org.warp.picalculator.math.functions.Variable.VariableValue; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -137,4 +140,8 @@ public class MathContext { // return mc; throw new UnsupportedOperationException(); } + + public ObjectArrayList getAcceptableRules(RuleType currentAcceptedRules) { + return RulesManager.rules[currentAcceptedRules.ordinal()]; + } } diff --git a/src/main/java/org/warp/picalculator/math/MathSolver.java b/src/main/java/org/warp/picalculator/math/MathSolver.java new file mode 100644 index 00000000..fd971c52 --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/MathSolver.java @@ -0,0 +1,144 @@ +package org.warp.picalculator.math; + +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +public class MathSolver { + + private final MathContext mathContext; + private final Function initialFunction; + private int stepState = 0; + private int currentStepStateN = 0; + private enum StepState { + _1_CALCULATION, + _2_REDUCTION, + _3_CALCULATION, + _4_EXPANSION + } + + public MathSolver(MathContext mathContext, Function initialFunction) { + this.mathContext = mathContext; + this.initialFunction = initialFunction; + } + + public ObjectArrayList> solveAllSteps() { + ObjectArrayList> steps = new ObjectArrayList<>(); + ObjectArrayList lastFnc = null, currFnc = new ObjectArrayList<>(); + currFnc.add(initialFunction); + do { + lastFnc = currFnc; + currFnc = new ObjectArrayList<>(); + for (Function fnc : lastFnc) { + currFnc.addAll(solveStep(fnc)); + } + steps.add(currFnc); + } while(checkEquals(currFnc, lastFnc)); + return steps; + } + + private boolean checkEquals(ObjectArrayList a, ObjectArrayList b) { + if (a == null && b == null) { + return true; + } else if (a != null && b != null) { + if (a.isEmpty() == b.isEmpty()) { + int size; + if ((size = a.size()) == b.size()) { + for (int i = 0; i < size; i++) { + if (a.get(i).equals(b.get(i)) == false) { + return false; + } + } + return true; + } + } + } + return false; + } + + private ObjectArrayList solveStep(Function fnc) { + RuleType currentAcceptedRules; + switch(StepState.values()[stepState]) { + case _1_CALCULATION: { + currentAcceptedRules = RuleType.CALCULATION; + break; + } + case _2_REDUCTION: { + currentAcceptedRules = RuleType.REDUCTION; + break; + } + case _3_CALCULATION: { + currentAcceptedRules = RuleType.CALCULATION; + break; + } + case _4_EXPANSION: { + currentAcceptedRules = RuleType.EXPANSION; + break; + } + default: + System.err.println("Unknown Step State"); + throw new NotImplementedException(); + } + ObjectArrayList rules = mathContext.getAcceptableRules(currentAcceptedRules); + ObjectArrayList results = null; + for (Rule rule : rules) { + ObjectArrayList ruleResults = rule.execute(fnc); + if (ruleResults != null && !ruleResults.isEmpty()) { + results = ruleResults; + break; + } + } + switch(StepState.values()[stepState]) { + case _1_CALCULATION: { + if (results == null) { + stepState++; + currentStepStateN = 0; + } else { + currentStepStateN++; + return results; + } + break; + } + case _2_REDUCTION: { + if (results == null) { + if (currentStepStateN == 0) { + stepState += 2; + } else { + stepState++; + } + currentStepStateN = 0; + } else { + currentStepStateN++; + return results; + } + break; + } + case _3_CALCULATION: { + if (results == null) { + stepState++; + currentStepStateN = 0; + } else { + currentStepStateN++; + return results; + } + break; + } + case _4_EXPANSION: { + if (results == null) { + stepState++; + currentStepStateN = 0; + } else { + currentStepStateN++; + return results; + } + break; + } + default: + System.err.println("Unknown Step State"); + throw new NotImplementedException(); + } + return null; + } +} diff --git a/src/main/java/org/warp/picalculator/math/rules/Rule.java b/src/main/java/org/warp/picalculator/math/rules/Rule.java new file mode 100644 index 00000000..ea1befd3 --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/rules/Rule.java @@ -0,0 +1,33 @@ +package org.warp.picalculator.math.rules; + +import org.warp.picalculator.math.Function; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Rule interface + * @author Andrea Cavalli + * + */ +public interface Rule { + /** + * Get rule name + * @return + */ + public default String getRuleName() { + return "UnnamedRule1"; + } + + /** + * Get rule type + * @return + */ + public RuleType getRuleType(); + + /** + * + * @param func + * @return
  • null if it's not executable on the function func
  • An ObjectArrayList<Function> if it did something
+ */ + public ObjectArrayList execute(Function func); +} \ No newline at end of file diff --git a/src/main/java/org/warp/picalculator/math/rules/RuleType.java b/src/main/java/org/warp/picalculator/math/rules/RuleType.java new file mode 100644 index 00000000..a3130b27 --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/rules/RuleType.java @@ -0,0 +1,7 @@ +package org.warp.picalculator.math.rules; + +public enum RuleType { + EXPANSION, + REDUCTION, + CALCULATION +} diff --git a/src/main/java/org/warp/picalculator/math/rules/RulesManager.java b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java new file mode 100644 index 00000000..f1f1be2b --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java @@ -0,0 +1,74 @@ +package org.warp.picalculator.math.rules; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + +import org.warp.picalculator.StaticVars; +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 org.warp.picalculator.math.functions.Variable; +import org.warp.picalculator.math.functions.Variable.V_TYPE; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +public class RulesManager { + + public static ObjectArrayList[] rules; + + private RulesManager() { + } + + @SuppressWarnings("unchecked") + public static void initialize() { + rules = new ObjectArrayList[RuleType.values().length]; + for (RuleType val : RuleType.values()) { + rules[val.ordinal()] = new ObjectArrayList(); + } + try { + final Path rulesPath = Paths.get(StaticVars.classLoader.getResource("rules.csv").toURI()); + if (!Files.exists(rulesPath)) { + throw new FileNotFoundException("rules.csv not found!"); + } + ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); + List ruleLines = Files.readAllLines(rulesPath); + for (String rulesLine : ruleLines) { + String[] ruleDetails = rulesLine.split(",", 1); + String ruleName = ruleDetails[0]; + URL resourceURL = StaticVars.classLoader.getResource("rules" + File.separator + ruleName.replace("/", "_") + ".js"); + if (resourceURL == null) { + throw new FileNotFoundException("rules/" + ruleName + ".js not found!"); + } + Path rulePath = Paths.get(resourceURL.toURI()); + engine.eval(new FileReader(rulePath.toString())); + } + } catch (URISyntaxException | IOException e) { + e.printStackTrace(); + System.exit(1); + } catch (ScriptException e) { + e.printStackTrace(); + } + System.exit(0); + } + + public static void addRule(Rule rule) { + MathContext mc = new MathContext(); + System.out.println(rule.execute(new SumSubtraction(mc, null, new Sum(mc, new Variable(mc, 'x', V_TYPE.VARIABLE), new Variable(mc, 'y', V_TYPE.VARIABLE))))); + System.out.println(rule.getRuleName()); + } +} diff --git a/src/main/resources/rules.csv b/src/main/resources/rules.csv new file mode 100644 index 00000000..9c440a45 --- /dev/null +++ b/src/main/resources/rules.csv @@ -0,0 +1,3 @@ +ExpandRule1 +ExpandRule2 +ExpandRule5 \ No newline at end of file diff --git a/src/main/resources/rules/ExpandRule1.js b/src/main/resources/rules/ExpandRule1.js new file mode 100644 index 00000000..42209a07 --- /dev/null +++ b/src/main/resources/rules/ExpandRule1.js @@ -0,0 +1,128 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Sum = org.warp.picalculator.math.functions.Sum; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var SumSubtraction = org.warp.picalculator.math.functions.SumSubtraction; +var Number = org.warp.picalculator.math.functions.Number; + +/** + * Expand rule + * -(+a+b) = -a-b + * -(+a-b) = -a+b + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "ExpandRule1"; + }, + // 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; + if (fnc.getParameter1().equals(new Number(fnc.getMathContext(), -1))) { + var expr = fnc.getParameter2(); + if (expr instanceof Sum) { + isExecutable = true; + } else if (expr instanceof Subtraction) { + isExecutable = true; + } else if (expr instanceof SumSubtraction) { + isExecutable = true; + } + } + } else if (ScriptUtils.instanceOf(f,Subtraction.class) || ScriptUtils.instanceOf(f,SumSubtraction.class)) { + var fnc = f; + var expr = fnc.getParameter2(); + if (ScriptUtils.instanceOf(expr,Sum.class)) { + isExecutable = true; + } else if (ScriptUtils.instanceOf(expr,Subtraction.class)) { + isExecutable = true; + } else if (ScriptUtils.instanceOf(expr,SumSubtraction.class)) { + isExecutable = true; + } + } + if (isExecutable) { + var result = new ObjectArrayList(); + var root = f.getMathContext(); + + var expr = null; + var fromSubtraction = 0; + var subtraction = null; + if (ScriptUtils.instanceOf(f,Multiplication.class)) { + expr = f.getParameter2(); + } else if (f instanceof Subtraction || f instanceof SumSubtraction) { + expr = f.getParameter2(); + if (f instanceof Subtraction) { + fromSubtraction = 1; + } else { + fromSubtraction = 2; + } + } + + if (f instanceof SumSubtraction) { + + } + + var fnc = expr; + if (fnc instanceof Sum) { + var a = fnc.getParameter1(); + var b = fnc.getParameter2(); + var fnc2 = new Subtraction(root, new Multiplication(root, new Number(root, -1), a), b); + if (fromSubtraction > 0) { + subtraction = new Subtraction(root, f.getParameter1(), fnc2); + result.add(subtraction); + } else { + result.add(fnc2); + } + } else if (fnc instanceof Subtraction) { + var a = fnc.getParameter1(); + var b = fnc.getParameter2(); + var fnc2 = new Sum(root, new Multiplication(root, new Number(root, -1), a), b); + if (fromSubtraction > 0) { + subtraction = new Subtraction(root, f.getParameter1(), fnc2); + result.add(subtraction); + } else { + result.add(fnc2); + } + } else if (fnc instanceof SumSubtraction) { + var a = fnc.getParameter1(); + var b = fnc.getParameter2(); + var fnc2 = new Sum(root, new Multiplication(root, new Number(root, -1), a), b); + var fnc3 = new Subtraction(root, new Multiplication(root, new Number(root, -1), a), b); + if (fromSubtraction > 0) { + subtraction = new SumSubtraction(root, f.getParameter1(), fnc2); + result.add(subtraction); + subtraction = new SumSubtraction(root, f.getParameter1(), fnc3); + result.add(subtraction); + result.add(subtraction); + } else { + result.add(fnc2); + result.add(fnc2); + } + } + 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/ExpandRule2.js b/src/main/resources/rules/ExpandRule2.js new file mode 100644 index 00000000..e69de29b diff --git a/src/main/resources/rules/ExpandRule5.js b/src/main/resources/rules/ExpandRule5.js new file mode 100644 index 00000000..e69de29b diff --git a/src/main/resources/rules/_EXAMPLE RULE.js b/src/main/resources/rules/_EXAMPLE RULE.js new file mode 100644 index 00000000..e95b2934 --- /dev/null +++ b/src/main/resources/rules/_EXAMPLE RULE.js @@ -0,0 +1,28 @@ + +// Imports +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; + +// Rule class +var rule = { + // Rule name + getRuleName: function() { + return "ExampleRule1"; + }, + // Rule type + getRuleType: function() { + return RuleType.CALCULATION; + }, + /* Rule function + Returns: + - null if it's not executable on the function "func" + - An ObjectArrayList if it did something + */ + execute: function(func) { + return null; + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file From bc6609d7dd8fcc82b2e6cac363fb3ed2eeb4b7b6 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Fri, 22 Dec 2017 22:39:58 +0100 Subject: [PATCH 2/7] Redefined Functions --- .../java/org/warp/picalculator/Utils.java | 15 ++-- .../gui/screens/MathInputScreen.java | 44 ++-------- .../org/warp/picalculator/math/Function.java | 20 ++--- .../picalculator/math/FunctionDynamic.java | 79 +++++------------ .../picalculator/math/FunctionOperator.java | 78 ++++++---------- .../picalculator/math/FunctionSingle.java | 51 ++--------- .../warp/picalculator/math/MathSolver.java | 72 ++++++++++----- .../picalculator/math/functions/Division.java | 88 +------------------ .../math/functions/EmptyNumber.java | 11 +-- .../math/functions/Expression.java | 38 ++------ .../picalculator/math/functions/Joke.java | 10 +-- .../math/functions/Multiplication.java | 59 ------------- .../picalculator/math/functions/Negative.java | 41 --------- .../picalculator/math/functions/Number.java | 23 +---- .../picalculator/math/functions/Power.java | 57 ------------ .../picalculator/math/functions/Root.java | 44 ---------- .../math/functions/RootSquare.java | 37 -------- .../math/functions/Subtraction.java | 57 ------------ .../warp/picalculator/math/functions/Sum.java | 67 -------------- .../math/functions/SumSubtraction.java | 41 --------- .../math/functions/Undefined.java | 10 +-- .../picalculator/math/functions/Variable.java | 25 +----- .../math/functions/equations/Equation.java | 27 ------ .../functions/equations/EquationsSystem.java | 39 -------- .../equations/EquationsSystemPart.java | 12 --- .../functions/trigonometry/ArcCosine.java | 12 --- .../math/functions/trigonometry/ArcSine.java | 12 --- .../functions/trigonometry/ArcTangent.java | 12 --- .../math/functions/trigonometry/Cosine.java | 12 --- .../math/functions/trigonometry/Sine.java | 25 ------ .../math/functions/trigonometry/Tangent.java | 12 --- .../math/rules/FractionsRule11.java | 2 +- .../math/rules/FractionsRule12.java | 2 +- .../math/rules/FractionsRule14.java | 6 +- .../picalculator/math/rules/RulesManager.java | 8 +- src/main/resources/rules.csv | 1 + src/main/resources/rules/ExpandRule1.js | 2 +- .../resources/rules/functions/Expression.js | 47 ++++++++++ 38 files changed, 206 insertions(+), 992 deletions(-) create mode 100644 src/main/resources/rules/functions/Expression.js diff --git a/src/main/java/org/warp/picalculator/Utils.java b/src/main/java/org/warp/picalculator/Utils.java index ea284190..f4f99374 100755 --- a/src/main/java/org/warp/picalculator/Utils.java +++ b/src/main/java/org/warp/picalculator/Utils.java @@ -538,15 +538,6 @@ public class Utils { return realbytes; } - public static boolean allSolved(List expressions) throws Error, InterruptedException { - for (final Function itm : expressions) { - if (itm.isSimplified() == false) { - return false; - } - } - return true; - } - public static Function[][] joinFunctionsResults(List l1, List l2) { final int size1 = l1.size(); final int size2 = l2.size(); @@ -747,4 +738,10 @@ public class Utils { System.gc(); } } + + public static ObjectArrayList newArrayList(T o) { + ObjectArrayList t = new ObjectArrayList(); + t.add(o); + return t; + } } diff --git a/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java b/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java index 95ea8ea4..8a8057b3 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java @@ -27,6 +27,7 @@ import org.warp.picalculator.math.FunctionDynamic; import org.warp.picalculator.math.FunctionOperator; import org.warp.picalculator.math.FunctionSingle; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.MathSolver; import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.functions.Expression; import org.warp.picalculator.math.functions.Number; @@ -218,45 +219,10 @@ public class MathInputScreen extends Screen { } calc.f.add(expr); Utils.out.println(2, "INPUT: " + expr); - int stop = 0; - boolean done = false; - ObjectArrayList resultExpressions = new ObjectArrayList<>(); - resultExpressions.add(expr.getParameter()); - while (!done && stop < (step?currentStep:3000)) { - if (Thread.interrupted()) throw new InterruptedException(); - ObjectArrayList newResultExpressions = new ObjectArrayList<>(); - done = true; - for (Function f : resultExpressions) { - if (Thread.interrupted()) throw new InterruptedException(); - Function newResult = null; - if (f.isSimplified() == false) { - done = false; - if (f instanceof Expression) { - ObjectArrayList fncResult = ((Expression) f).solve(); - for (Function resultItem : fncResult) { - newResultExpressions.add(resultItem); - } - } else { - List fncResult = f.simplify(); - for (Function resultItem : fncResult) { - newResultExpressions.add(resultItem); - } - } - } else { - newResult = f; - } - if (newResult != null) { - newResultExpressions.add(newResult); - } - } - if (StaticVars.debugOn) { - Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MIN, "STEP: "+newResultExpressions); } - resultExpressions = newResultExpressions; - stop++; - } - if (stop >= 3000) { - Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MIN, "Too much steps! Stopped."); - } + MathSolver ms = new MathSolver(expr); + ObjectArrayList> resultSteps = ms.solveAllSteps(); + resultSteps.add(0, Utils.newArrayList(expr)); + ObjectArrayList resultExpressions = resultSteps.get(resultSteps.size() - 1); for (Function rr : resultExpressions) { Utils.out.println(1, "RESULT: " + rr.toString()); } diff --git a/src/main/java/org/warp/picalculator/math/Function.java b/src/main/java/org/warp/picalculator/math/Function.java index c9ca8a5e..7bfeac41 100755 --- a/src/main/java/org/warp/picalculator/math/Function.java +++ b/src/main/java/org/warp/picalculator/math/Function.java @@ -4,6 +4,7 @@ import java.util.List; import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -53,20 +54,15 @@ public interface Function { * @return Calculator mathContext */ public MathContext getMathContext(); - + /** - * Simplify the current function or it's children - * @throws InterruptedException + * Simplify the current function or it's children using the specified rule + * @param rule + * @return A list of the resulting Functions if the rule is applicable and something changed, null otherwise + * @throws Error + * @throws InterruptedException */ - public List simplify() throws Error, InterruptedException; - - /** - * The current simplification status of this function and it's childrens - * - * @return boolean - * @throws InterruptedException - */ - public boolean isSimplified() throws InterruptedException; + public ObjectArrayList simplify(Rule rule) throws Error, InterruptedException; /** * diff --git a/src/main/java/org/warp/picalculator/math/FunctionDynamic.java b/src/main/java/org/warp/picalculator/math/FunctionDynamic.java index 5be3a61a..9b18857a 100755 --- a/src/main/java/org/warp/picalculator/math/FunctionDynamic.java +++ b/src/main/java/org/warp/picalculator/math/FunctionDynamic.java @@ -5,6 +5,7 @@ import java.util.List; import org.warp.picalculator.Error; import org.warp.picalculator.Utils; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -87,75 +88,37 @@ public abstract class FunctionDynamic implements Function { } @Override - public boolean isSimplified() throws InterruptedException { - for (final Function variable : functions) { - if (Thread.interrupted()) throw new InterruptedException(); - if (variable.isSimplified() == false) { - return false; - } - } - return !isSolvable(); - } - - /** - * The current simplification status of this function, assuming that its - * children are already simplified. - * - * @return true if this function can be solved, otherwise - * false. - */ - protected abstract boolean isSolvable(); - - @Override - public final ObjectArrayList simplify() throws Error, InterruptedException { - boolean solved = true; + public final ObjectArrayList simplify(Rule rule) throws Error, InterruptedException { final Function[] fncs = getParameters(); - for (final Function f : fncs) { - if (Thread.interrupted()) throw new InterruptedException(); - if (f.isSimplified() == false) { - solved = false; - break; - } - } if (Thread.interrupted()) throw new InterruptedException(); - ObjectArrayList result = solved ? solve() : null; + ObjectArrayList result = new ObjectArrayList<>(); - if (result == null || result.isEmpty()) { - result = new ObjectArrayList<>(); - - final ObjectArrayList> ln = new ObjectArrayList<>(); - for (final Function fnc : fncs) { - final ObjectArrayList l = new ObjectArrayList<>(); - if (Thread.interrupted()) throw new InterruptedException(); - if (fnc.isSimplified()) { - l.add(fnc); - } else { - l.addAll(fnc.simplify()); - } - ln.add(l); + final ObjectArrayList> ln = new ObjectArrayList<>(); + boolean alreadySolved = true; + for (final Function fnc : fncs) { + final ObjectArrayList l = new ObjectArrayList<>(); + if (Thread.interrupted()) throw new InterruptedException(); + ObjectArrayList simplifiedFnc = fnc.simplify(rule); + if (simplifiedFnc == null) { + l.add(fnc); + } else { + l.addAll(simplifiedFnc); + alreadySolved = false; } + ln.add(l); + } + + if (alreadySolved) return rule.execute(this); - final Function[][] results = Utils.joinFunctionsResults(ln); + final Function[][] results = Utils.joinFunctionsResults(ln); - for (final Function[] f : results) { - result.add(this.setParameters(f)); - } + for (final Function[] f : results) { + result.add(this.setParameters(f)); } return result; } - /** - * Solves only this function, assuming that its children are already - * simplified and it can be solved. - * - * @return The solved function. - * @throws Error - * Errors during computation, like a/0 or similar. - * @throws InterruptedException - */ - protected abstract ObjectArrayList solve() throws Error, InterruptedException; - @Override public MathContext getMathContext() { return root; diff --git a/src/main/java/org/warp/picalculator/math/FunctionOperator.java b/src/main/java/org/warp/picalculator/math/FunctionOperator.java index 4bacd5a9..8c69d4d3 100755 --- a/src/main/java/org/warp/picalculator/math/FunctionOperator.java +++ b/src/main/java/org/warp/picalculator/math/FunctionOperator.java @@ -2,6 +2,7 @@ package org.warp.picalculator.math; import org.warp.picalculator.Error; import org.warp.picalculator.Utils; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -113,69 +114,42 @@ public abstract class FunctionOperator implements Function { } @Override - public boolean isSimplified() throws InterruptedException { + public final ObjectArrayList simplify(Rule rule) throws Error, InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); - return (parameter1.isSimplified() & parameter2.isSimplified()) ? !isSolvable() : false; - } - /** - * The current simplification status of this function, assuming that its - * children are already simplified. - * - * @return true if this function can be solved, otherwise - * false. - * @throws InterruptedException - */ - protected abstract boolean isSolvable() throws InterruptedException; - - @Override - public final ObjectArrayList simplify() throws Error, InterruptedException { + ObjectArrayList simplifiedParam1 = parameter1.simplify(rule); + ObjectArrayList simplifiedParam2 = parameter2.simplify(rule); + if (simplifiedParam1 == null & simplifiedParam2 == null) return rule.execute(this); + if (Thread.interrupted()) throw new InterruptedException(); - final boolean solved = parameter1.isSimplified() & parameter2.isSimplified(); + ObjectArrayList result = new ObjectArrayList<>(); + + final ObjectArrayList l1 = new ObjectArrayList<>(); + final ObjectArrayList l2 = new ObjectArrayList<>(); if (Thread.interrupted()) throw new InterruptedException(); - ObjectArrayList result = solved ? solve() : null;; - - if (result == null || result.isEmpty()) { - result = new ObjectArrayList<>(); - - final ObjectArrayList l1 = new ObjectArrayList<>(); - final ObjectArrayList l2 = new ObjectArrayList<>(); + if (simplifiedParam1 == null) { + l1.add(parameter1); + } else { if (Thread.interrupted()) throw new InterruptedException(); - if (parameter1.isSimplified()) { - l1.add(parameter1); - } else { - if (Thread.interrupted()) throw new InterruptedException(); - l1.addAll(parameter1.simplify()); - } + l1.addAll(simplifiedParam1); + } + if (Thread.interrupted()) throw new InterruptedException(); + if (simplifiedParam2 == null) { + l2.add(parameter2); + } else { if (Thread.interrupted()) throw new InterruptedException(); - if (parameter2.isSimplified()) { - l2.add(parameter2); - } else { - if (Thread.interrupted()) throw new InterruptedException(); - l2.addAll(parameter2.simplify()); - } - - final Function[][] results = Utils.joinFunctionsResults(l1, l2); - - for (final Function[] f : results) { - result.add(setParameter1(f[0]).setParameter2(f[1])); - } + l2.addAll(simplifiedParam2); } + final Function[][] results = Utils.joinFunctionsResults(l1, l2); + + for (final Function[] f : results) { + result.add(setParameter1(f[0]).setParameter2(f[1])); + } + return result; } - /** - * Solves only this function, assuming that its children are already - * simplified and it can be solved. - * - * @return The solved function. - * @throws Error - * Errors during computation, like a/0 or similar. - * @throws InterruptedException - */ - protected abstract ObjectArrayList solve() throws Error, InterruptedException; - @Override public abstract FunctionOperator clone(); diff --git a/src/main/java/org/warp/picalculator/math/FunctionSingle.java b/src/main/java/org/warp/picalculator/math/FunctionSingle.java index 9a0a5550..2206d623 100755 --- a/src/main/java/org/warp/picalculator/math/FunctionSingle.java +++ b/src/main/java/org/warp/picalculator/math/FunctionSingle.java @@ -1,6 +1,7 @@ package org.warp.picalculator.math; import org.warp.picalculator.Error; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -96,54 +97,18 @@ public abstract class FunctionSingle implements Function { } @Override - public final ObjectArrayList simplify() throws Error, InterruptedException { - final boolean simplified = parameter.isSimplified(); - ObjectArrayList result = simplified ? solve() : null; - - if (result == null || result.isEmpty()) { - result = new ObjectArrayList<>(); - - final ObjectArrayList l1 = new ObjectArrayList<>(); - if (parameter.isSimplified()) { - l1.add(parameter); - } else { - l1.addAll(parameter.simplify()); - } - - for (final Function f : l1) { - result.add(this.setParameter(f)); - } + public final ObjectArrayList simplify(Rule rule) throws Error, InterruptedException { + ObjectArrayList simplifiedParam = parameter.simplify(rule); + if (simplifiedParam == null) return rule.execute(this); + + ObjectArrayList result = new ObjectArrayList<>(); + for (final Function f : simplifiedParam) { + result.add(this.setParameter(f)); } return result; } - /** - * Solves only this function, assuming that its children are already - * simplified and it can be solved. - * - * @return The solved function. - * @throws Error - * Errors during computation, like a/0 or similar. - * @throws InterruptedException - */ - protected abstract ObjectArrayList solve() throws Error, InterruptedException; - - @Override - public boolean isSimplified() throws InterruptedException { - return parameter.isSimplified() ? !isSolvable() : false; - } - - /** - * The current simplification status of this function, assuming that its - * children are already simplified. - * - * @return true if this function can be solved, otherwise - * false. - * @throws InterruptedException - */ - protected abstract boolean isSolvable() throws InterruptedException; - @Override public abstract FunctionSingle clone(); diff --git a/src/main/java/org/warp/picalculator/math/MathSolver.java b/src/main/java/org/warp/picalculator/math/MathSolver.java index fd971c52..33edb497 100644 --- a/src/main/java/org/warp/picalculator/math/MathSolver.java +++ b/src/main/java/org/warp/picalculator/math/MathSolver.java @@ -1,5 +1,10 @@ package org.warp.picalculator.math; +import java.util.List; + +import org.warp.picalculator.Error; +import org.warp.picalculator.StaticVars; +import org.warp.picalculator.Utils; import org.warp.picalculator.math.rules.Rule; import org.warp.picalculator.math.rules.RuleType; @@ -8,34 +13,43 @@ import sun.reflect.generics.reflectiveObjects.NotImplementedException; public class MathSolver { - private final MathContext mathContext; private final Function initialFunction; private int stepState = 0; private int currentStepStateN = 0; + private int consecutiveNullSteps = 0; private enum StepState { _1_CALCULATION, _2_REDUCTION, _3_CALCULATION, _4_EXPANSION } + private final StepState[] stepStates = StepState.values(); + @SuppressWarnings("unchecked") + private final ObjectArrayList[] lastFunctions = new ObjectArrayList[stepStates.length]; - public MathSolver(MathContext mathContext, Function initialFunction) { - this.mathContext = mathContext; + public MathSolver(Function initialFunction) { this.initialFunction = initialFunction; } - public ObjectArrayList> solveAllSteps() { + public ObjectArrayList> solveAllSteps() throws InterruptedException, Error { ObjectArrayList> steps = new ObjectArrayList<>(); ObjectArrayList lastFnc = null, currFnc = new ObjectArrayList<>(); currFnc.add(initialFunction); + int stepBefore = 0, stepAfter = 0; do { - lastFnc = currFnc; - currFnc = new ObjectArrayList<>(); - for (Function fnc : lastFnc) { - currFnc.addAll(solveStep(fnc)); + for (int i = stepBefore; i <= stepAfter; i++) { + lastFnc = lastFunctions[i] = currFnc; } - steps.add(currFnc); - } while(checkEquals(currFnc, lastFnc)); + stepBefore = stepState; + ObjectArrayList stepResult = solveStep(lastFnc); + if (stepResult == null) { + currFnc = lastFnc; + } else { + currFnc = stepResult; + steps.add(currFnc); + } + stepAfter = stepState; + } while(consecutiveNullSteps < stepStates.length && !checkEquals(currFnc, lastFunctions[stepState])); return steps; } @@ -58,9 +72,9 @@ public class MathSolver { return false; } - private ObjectArrayList solveStep(Function fnc) { + private ObjectArrayList solveStep(ObjectArrayList fncs) throws InterruptedException, Error { RuleType currentAcceptedRules; - switch(StepState.values()[stepState]) { + switch(stepStates[stepState]) { case _1_CALCULATION: { currentAcceptedRules = RuleType.CALCULATION; break; @@ -81,21 +95,31 @@ public class MathSolver { System.err.println("Unknown Step State"); throw new NotImplementedException(); } - ObjectArrayList rules = mathContext.getAcceptableRules(currentAcceptedRules); + ObjectArrayList rules = initialFunction.getMathContext().getAcceptableRules(currentAcceptedRules); ObjectArrayList results = null; - for (Rule rule : rules) { - ObjectArrayList ruleResults = rule.execute(fnc); - if (ruleResults != null && !ruleResults.isEmpty()) { - results = ruleResults; - break; + 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; + } } } - switch(StepState.values()[stepState]) { + if (StaticVars.debugOn & results != null & appliedRule != null) { + Utils.out.println(Utils.OUTPUTLEVEL_NODEBUG, stepStates[stepState].toString().substring(3) + ": " + appliedRule.getRuleName()); + } + switch(stepStates[stepState]) { case _1_CALCULATION: { if (results == null) { stepState++; + consecutiveNullSteps++; currentStepStateN = 0; } else { + consecutiveNullSteps = 0; currentStepStateN++; return results; } @@ -105,11 +129,14 @@ public class MathSolver { if (results == null) { if (currentStepStateN == 0) { stepState += 2; + consecutiveNullSteps += 2; } else { stepState++; + consecutiveNullSteps++; } currentStepStateN = 0; } else { + consecutiveNullSteps = 0; currentStepStateN++; return results; } @@ -118,8 +145,10 @@ public class MathSolver { case _3_CALCULATION: { if (results == null) { stepState++; + consecutiveNullSteps++; currentStepStateN = 0; } else { + consecutiveNullSteps = 0; currentStepStateN++; return results; } @@ -127,9 +156,12 @@ public class MathSolver { } case _4_EXPANSION: { if (results == null) { - stepState++; + stepState = 1; + consecutiveNullSteps++; currentStepStateN = 0; } else { + stepState = 0; + consecutiveNullSteps = 0; currentStepStateN++; return results; } diff --git a/src/main/java/org/warp/picalculator/math/functions/Division.java b/src/main/java/org/warp/picalculator/math/functions/Division.java index 4515fef9..1b72c8d7 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Division.java +++ b/src/main/java/org/warp/picalculator/math/functions/Division.java @@ -27,93 +27,7 @@ public class Division extends FunctionOperator { public Division(MathContext root, Function value1, Function value2) { super(root, value1, value2); } - - @Override - protected boolean isSolvable() throws InterruptedException { - final Function variable1 = getParameter1(); - final Function variable2 = getParameter2(); - if (FractionsRule1.compare(this)) { - return true; - } - if (FractionsRule2.compare(this)) { - return true; - } - if (FractionsRule3.compare(this)) { - return true; - } - if (FractionsRule11.compare(this)) { - return true; - } - if (FractionsRule12.compare(this)) { - return true; - } - if (UndefinedRule2.compare(this)) { - return true; - } - if (DivisionRule1.compare(this)) { - return true; - } - if (variable1 instanceof Number && variable2 instanceof Number) { - if (getMathContext().exactMode) { - try { - if (((Number) variable1).isInteger() && ((Number) variable2).isInteger()) { - LinkedList factors1 = ((Number) variable1).getFactors(); - LinkedList factors2 = ((Number) variable2).getFactors(); - LinkedList mcm = Utils.mcm(factors1, factors2); - return mcm.size() > 0 /* true if there is at least one common factor */; - } else if (((Number) variable1).divide((Number) variable2).isInteger()) { - return true; - } else { - return false; - } - } catch (final Error e) { - return false; - } - } else { - return true; - } - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - final Function variable1 = getParameter1(); - final Function variable2 = getParameter2(); - ObjectArrayList result = new ObjectArrayList<>(); - if (FractionsRule1.compare(this)) { - result = FractionsRule1.execute(this); - } else if (FractionsRule2.compare(this)) { - result = FractionsRule2.execute(this); - } else if (FractionsRule3.compare(this)) { - result = FractionsRule3.execute(this); - } else if (FractionsRule11.compare(this)) { - result = FractionsRule11.execute(this); - } else if (FractionsRule12.compare(this)) { - result = FractionsRule12.execute(this); - } else if (UndefinedRule2.compare(this)) { - result = UndefinedRule2.execute(this); - } else if (DivisionRule1.compare(this)) { - result = DivisionRule1.execute(this); - } else if (variable1 instanceof Number && variable2 instanceof Number) { - if (getMathContext().exactMode && (((Number) variable1).isInteger() && ((Number) variable2).isInteger())) { - LinkedList factors1 = ((Number) variable1).getFactors(); - LinkedList factors2 = ((Number) variable2).getFactors(); - LinkedList mcm = Utils.mcm(factors1, factors2); - BigInteger nmb1 = ((Number) this.getParameter1()).term.toBigIntegerExact(); - BigInteger nmb2 = ((Number) this.getParameter2()).term.toBigIntegerExact(); - for (BigInteger i : mcm) { - nmb1 = nmb1.divide(i); - nmb2 = nmb2.divide(i); - } - result.add(new Division(mathContext, new Number(mathContext, nmb1), new Number(mathContext, nmb2))); - } else { - result.add(((Number) variable1).divide((Number) variable2)); - } - } - return result; - } - + @Override public boolean equals(Object o) { if (o instanceof Division) { diff --git a/src/main/java/org/warp/picalculator/math/functions/EmptyNumber.java b/src/main/java/org/warp/picalculator/math/functions/EmptyNumber.java index 55e88661..884107c2 100755 --- a/src/main/java/org/warp/picalculator/math/functions/EmptyNumber.java +++ b/src/main/java/org/warp/picalculator/math/functions/EmptyNumber.java @@ -4,6 +4,7 @@ import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -16,14 +17,8 @@ public class EmptyNumber implements Function { private final MathContext root; @Override - public ObjectArrayList simplify() throws Error { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isSimplified() { - return false; + public ObjectArrayList simplify(Rule rule) throws Error { + return rule.execute(this); } @Override diff --git a/src/main/java/org/warp/picalculator/math/functions/Expression.java b/src/main/java/org/warp/picalculator/math/functions/Expression.java index b5dff36f..97b2a099 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Expression.java +++ b/src/main/java/org/warp/picalculator/math/functions/Expression.java @@ -548,37 +548,6 @@ public class Expression extends FunctionSingle { */ } - @Override - protected boolean isSolvable() throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - final Function f = getParameter(); - if (f.isSimplified() == false) { - return true; - } else { - return !parenthesisNeeded(); - } - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - final ObjectArrayList ret = new ObjectArrayList<>(); - if (getParameter().isSimplified() || !parenthesisNeeded()) { - ret.add(getParameter()); - return ret; - } else { - final List l = getParameter().simplify(); - for (final Function f : l) { - if (f instanceof Number || f instanceof Variable) { - ret.add(f); - } else { - ret.add(new Expression(mathContext, f)); - } - } - return ret; - } - } - public boolean parenthesisNeeded() { boolean parenthesisneeded = true; if (initialParenthesis) { @@ -624,7 +593,6 @@ public class Expression extends FunctionSingle { } else { s += parameter.toString(); } - s = s.substring(0, s.length() - 1); s += ")"; return s; } @@ -635,7 +603,11 @@ public class Expression extends FunctionSingle { return parameter == o; } else { final Function f = (Function) o; - return (getParameter(0).equals(f)); + if (f instanceof Expression) { + return (getParameter(0).equals(((Expression)f).getParameter(0))); + } else { + return (getParameter(0).equals(f)); + } } } diff --git a/src/main/java/org/warp/picalculator/math/functions/Joke.java b/src/main/java/org/warp/picalculator/math/functions/Joke.java index 1bf3f935..e8e192f0 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Joke.java +++ b/src/main/java/org/warp/picalculator/math/functions/Joke.java @@ -5,6 +5,7 @@ import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -26,13 +27,8 @@ public class Joke implements Function { } @Override - public ObjectArrayList simplify() throws Error { - return null; - } - - @Override - public boolean isSimplified() { - return true; + public ObjectArrayList simplify(Rule rule) throws Error { + return rule.execute(this); } @Override diff --git a/src/main/java/org/warp/picalculator/math/functions/Multiplication.java b/src/main/java/org/warp/picalculator/math/functions/Multiplication.java index b68e1d5f..e8ecccaa 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Multiplication.java +++ b/src/main/java/org/warp/picalculator/math/functions/Multiplication.java @@ -29,65 +29,6 @@ public class Multiplication extends FunctionOperator { }*/ } - @Override - protected boolean isSolvable() throws InterruptedException { - final Function variable1 = getParameter1(); - final Function variable2 = getParameter2(); - if (variable1 instanceof Number & variable2 instanceof Number) { - return true; - } - if (NumberRule1.compare(this)) { - return true; - } - if (NumberRule2.compare(this)) { - return true; - } - if (ExpandRule1.compare(this)) { - return true; - } - if (ExpandRule2.compare(this)) { - return true; - } - if (ExponentRule15.compare(this)) { - return true; - } - if (ExponentRule16.compare(this)) { - return true; - } - if (FractionsRule14.compare(this)) { - return true; - } - if (MultiplicationMethod1.compare(this)) { - return true; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - ObjectArrayList result = new ObjectArrayList<>(); - if (NumberRule1.compare(this)) { - result = NumberRule1.execute(this); - } else if (NumberRule2.compare(this)) { - result = NumberRule2.execute(this); - } else if (ExpandRule1.compare(this)) { - result = ExpandRule1.execute(this); - } else if (ExpandRule2.compare(this)) { - result = ExpandRule2.execute(this); - } else if (ExponentRule15.compare(this)) { - result = ExponentRule15.execute(this); - } else if (ExponentRule16.compare(this)) { - result = ExponentRule16.execute(this); - } else if (FractionsRule14.compare(this)) { - result = FractionsRule14.execute(this); - } else if (MultiplicationMethod1.compare(this)) { - result = MultiplicationMethod1.execute(this); - } else if (parameter1.isSimplified() & parameter2.isSimplified()) { - result.add(((Number) parameter1).multiply((Number) parameter2)); - } - return result; - } - @Override public boolean equals(Object o) { if (o instanceof Multiplication) { diff --git a/src/main/java/org/warp/picalculator/math/functions/Negative.java b/src/main/java/org/warp/picalculator/math/functions/Negative.java index 0fb966f9..893c63cb 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Negative.java +++ b/src/main/java/org/warp/picalculator/math/functions/Negative.java @@ -20,47 +20,6 @@ public class Negative extends FunctionSingle { super(root, value); } - @Override - protected boolean isSolvable() { - if (ExpandRule1.compare(this)) { - return true; - } - if (ExpandRule5.compare(this)) { - return true; - } - if (parameter instanceof Number) { - return true; - } - return true; - } - - @Override - public ObjectArrayList solve() throws Error { - if (parameter == null) { - throw new Error(Errors.SYNTAX_ERROR); - } - ObjectArrayList result = new ObjectArrayList<>(); - if (ExpandRule1.compare(this)) { - result = ExpandRule1.execute(this); - } else if (ExpandRule5.compare(this)) { - result = ExpandRule5.execute(this); - } else if (parameter instanceof Number) { - try { - final Number var = (Number) getParameter(); - result.add(var.multiply(new Number(mathContext, -1))); - } catch (final NullPointerException ex) { - throw new Error(Errors.ERROR); - } catch (final NumberFormatException ex) { - throw new Error(Errors.SYNTAX_ERROR); - } catch (final ArithmeticException ex) { - throw new Error(Errors.NUMBER_TOO_SMALL); - } - } else { - result.add(new Multiplication(parameter.getMathContext(), new Number(parameter.getMathContext(), -1), parameter)); - } - return result; - } - @Override public boolean equals(Object o) { if (o instanceof Negative) { diff --git a/src/main/java/org/warp/picalculator/math/functions/Number.java b/src/main/java/org/warp/picalculator/math/functions/Number.java index a5d914ab..7e040a96 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Number.java +++ b/src/main/java/org/warp/picalculator/math/functions/Number.java @@ -15,6 +15,7 @@ import org.warp.picalculator.gui.expression.blocks.BlockExponentialNotation; import org.warp.picalculator.gui.expression.blocks.BlockPower; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -116,26 +117,8 @@ public class Number implements Function { } @Override - public boolean isSimplified() { - if (root.exactMode) { - return isInteger(); - } else { - return true; - } - } - - @Override - public List simplify() throws Error { - final List result = new ObjectArrayList<>(); - if (root.exactMode) { - final Number divisor = new Number(root, BigInteger.TEN.pow(getNumberOfDecimalPlaces())); - final Number numb = new Number(root, term.multiply(divisor.term)); - final Division div = new Division(root, numb, divisor); - result.add(div); - } else { - result.add(this); - } - return result; + public ObjectArrayList simplify(Rule rule) throws Error { + return rule.execute(this); } public int getNumberOfDecimalPlaces() { diff --git a/src/main/java/org/warp/picalculator/math/functions/Power.java b/src/main/java/org/warp/picalculator/math/functions/Power.java index 2f8cefd0..c5ba3f2f 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Power.java +++ b/src/main/java/org/warp/picalculator/math/functions/Power.java @@ -24,63 +24,6 @@ public class Power extends FunctionOperator { super(root, value1, value2); } - @Override - protected boolean isSolvable() { - if (parameter1 instanceof Number & parameter2 instanceof Number) { - return true; - } - if (UndefinedRule1.compare(this)) { - return true; - } - if (ExponentRule1.compare(this)) { - return true; - } - if (ExponentRule2.compare(this)) { - return true; - } - if (ExponentRule3.compare(this)) { - return true; - } - if (ExponentRule4.compare(this)) { - return true; - } - if (ExponentRule9.compare(this)) { - return true; - } - if (FractionsRule4.compare(this)) { - return true; - } - if (FractionsRule5.compare(this)) { - return true; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - final ObjectArrayList result = new ObjectArrayList<>(); - if (UndefinedRule1.compare(this)) { - result.addAll(UndefinedRule1.execute(this)); - } else if (ExponentRule1.compare(this)) { - result.addAll(ExponentRule1.execute(this)); - } else if (ExponentRule2.compare(this)) { - result.addAll(ExponentRule2.execute(this)); - } else if (ExponentRule3.compare(this)) { - result.addAll(ExponentRule3.execute(this)); - } else if (ExponentRule4.compare(this)) { - result.addAll(ExponentRule4.execute(this)); - } else if (ExponentRule9.compare(this)) { - result.addAll(ExponentRule9.execute(this)); - } else if (FractionsRule4.compare(this)) { - result.addAll(FractionsRule4.execute(this)); - } else if (FractionsRule5.compare(this)) { - result.addAll(FractionsRule5.execute(this)); - } else if (parameter1 instanceof Number & parameter2 instanceof Number) { - result.add(((Number) parameter1).pow((Number) parameter2)); - } - return result; - } - @Override public boolean equals(Object o) { if (o instanceof Power) { diff --git a/src/main/java/org/warp/picalculator/math/functions/Root.java b/src/main/java/org/warp/picalculator/math/functions/Root.java index accc4178..be896ad7 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Root.java +++ b/src/main/java/org/warp/picalculator/math/functions/Root.java @@ -18,50 +18,6 @@ public class Root extends FunctionOperator { super(root, value1, value2); } - @Override - protected boolean isSolvable() { - if (parameter1 instanceof Number & parameter2 instanceof Number) { - if (mathContext.exactMode == false) { - return true; - } - try { - Number exponent = new Number(mathContext, BigDecimal.ONE); - exponent = exponent.divide((Number) parameter1); - final Number resultVal = ((Number) parameter2).pow(exponent); - final Number originalVariable = resultVal.pow(new Number(mathContext, 2)); - if (originalVariable.equals(parameter2)) { - return true; - } - } catch (Exception | Error ex) { - ex.printStackTrace(); - } - } - if (parameter1 instanceof Number && ((Number) parameter1).equals(new Number(mathContext, 2))) { - return true; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - final ObjectArrayList result = new ObjectArrayList<>(); - if (mathContext.exactMode) { - if (parameter1 instanceof Number && ((Number) parameter1).equals(new Number(mathContext, 2))) { - result.add(new RootSquare(mathContext, parameter2)); - } else { - Number exponent = new Number(mathContext, BigInteger.ONE); - exponent = exponent.divide((Number) parameter1); - result.add(((Number) parameter2).pow(exponent)); - } - } else { - final Number exp = (Number) parameter1; - final Number numb = (Number) parameter2; - - result.add(numb.pow(new Number(mathContext, 1).divide(exp))); - } - return result; - } - @Override public boolean equals(Object o) { if (o instanceof Root) { diff --git a/src/main/java/org/warp/picalculator/math/functions/RootSquare.java b/src/main/java/org/warp/picalculator/math/functions/RootSquare.java index e6a8ac0b..d423b743 100755 --- a/src/main/java/org/warp/picalculator/math/functions/RootSquare.java +++ b/src/main/java/org/warp/picalculator/math/functions/RootSquare.java @@ -18,43 +18,6 @@ public class RootSquare extends FunctionSingle { super(root, value); } - @Override - protected boolean isSolvable() { - if (parameter instanceof Number) { - if (mathContext.exactMode == false) { - return true; - } - try { - Number exponent = new Number(mathContext, BigInteger.ONE); - exponent = exponent.divide(new Number(mathContext, 2)); - final Number resultVal = ((Number) parameter).pow(exponent); - final Number originalVariable = resultVal.pow(new Number(mathContext, 2)); - if (originalVariable.equals(parameter)) { - return true; - } - } catch (Exception | Error ex) { - - } - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - final ObjectArrayList result = new ObjectArrayList<>(); - if (mathContext.exactMode) { - Number exponent = new Number(mathContext, BigInteger.ONE); - exponent = exponent.divide(new Number(mathContext, 2)); - result.add(((Number) parameter).pow(exponent)); - } else { - final Number exp = new Number(mathContext, 2); - final Number numb = (Number) parameter; - - result.add(numb.pow(new Number(mathContext, 1).divide(exp))); - } - return result; - } - @Override public boolean equals(Object o) { if (o instanceof RootSquare) { diff --git a/src/main/java/org/warp/picalculator/math/functions/Subtraction.java b/src/main/java/org/warp/picalculator/math/functions/Subtraction.java index c8d688b9..3e407d5a 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Subtraction.java +++ b/src/main/java/org/warp/picalculator/math/functions/Subtraction.java @@ -24,63 +24,6 @@ public class Subtraction extends FunctionOperator { super(root, value1, value2); } - @Override - protected boolean isSolvable() throws InterruptedException { - if (parameter1 instanceof Number & parameter2 instanceof Number) { - return true; - } - if (VariableRule1.compare(this)) { - return true; - } - if (VariableRule2.compare(this)) { - return true; - } - if (VariableRule3.compare(this)) { - return true; - } - if (NumberRule3.compare(this)) { - return true; - } - if (ExpandRule1.compare(this)) { - return true; - } - if (ExpandRule5.compare(this)) { - return true; - } - if (NumberRule5.compare(this)) { - return true; - } - if (SumMethod1.compare(this)) { - return true; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - ObjectArrayList result = new ObjectArrayList<>(); - if (VariableRule1.compare(this)) { - result = VariableRule1.execute(this); - } else if (VariableRule2.compare(this)) { - result = VariableRule2.execute(this); - } else if (VariableRule3.compare(this)) { - result = VariableRule3.execute(this); - } else if (NumberRule3.compare(this)) { - result = NumberRule3.execute(this); - } else if (ExpandRule1.compare(this)) { - result = ExpandRule1.execute(this); - } else if (ExpandRule5.compare(this)) { - result = ExpandRule5.execute(this); - } else if (NumberRule5.compare(this)) { - result = NumberRule5.execute(this); - } else if (SumMethod1.compare(this)) { - result = SumMethod1.execute(this); - } else if (parameter1.isSimplified() & parameter2.isSimplified()) { - result.add(((Number) parameter1).add(((Number) parameter2).multiply(new Number(mathContext, "-1")))); - } - return result; - } - @Override public boolean equals(Object o) { if (o instanceof Subtraction) { diff --git a/src/main/java/org/warp/picalculator/math/functions/Sum.java b/src/main/java/org/warp/picalculator/math/functions/Sum.java index 65188a43..b6cc3f07 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Sum.java +++ b/src/main/java/org/warp/picalculator/math/functions/Sum.java @@ -26,73 +26,6 @@ public class Sum extends FunctionOperator { super(root, value1, value2); } - @Override - protected boolean isSolvable() throws InterruptedException { - if (parameter1 instanceof Number & parameter2 instanceof Number) { - return true; - } - if (VariableRule1.compare(this)) { - return true; - } - if (VariableRule2.compare(this)) { - return true; - } - if (VariableRule3.compare(this)) { - return true; - } - if (NumberRule3.compare(this)) { - return true; - } - if (NumberRule5.compare(this)) { - return true; - } - if (NumberRule7.compare(this)) { - return true; - } - if (SumMethod1.compare(this)) { - return true; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - if (parameter1 == null || parameter2 == null) { - throw new Error(Errors.SYNTAX_ERROR); - } - ObjectArrayList result = new ObjectArrayList<>(); - if (VariableRule1.compare(this)) { - result = VariableRule1.execute(this); - } else if (VariableRule2.compare(this)) { - result = VariableRule2.execute(this); - } else if (VariableRule3.compare(this)) { - result = VariableRule3.execute(this); - } else if (NumberRule3.compare(this)) { - result = NumberRule3.execute(this); - } else if (NumberRule5.compare(this)) { - result = NumberRule5.execute(this); - } else if (NumberRule7.compare(this)) { - result = NumberRule7.execute(this); - } else if (SumMethod1.compare(this)) { - result = SumMethod1.execute(this); - } else if (parameter1.isSimplified() & parameter2.isSimplified()) { - if ((mathContext.getChild().equals(this))) { - if (((Number) parameter1).term.compareTo(new BigDecimal(2)) == 0 && ((Number) parameter2).term.compareTo(new BigDecimal(2)) == 0) { - result.add(new Joke(mathContext, Joke.FISH)); - return result; - } else if (((Number) parameter1).term.compareTo(new BigDecimal(20)) == 0 && ((Number) parameter2).term.compareTo(new BigDecimal(20)) == 0) { - result.add(new Joke(mathContext, Joke.TORNADO)); - return result; - } else if (((Number) parameter1).term.compareTo(new BigDecimal(29)) == 0 && ((Number) parameter2).term.compareTo(new BigDecimal(29)) == 0) { - result.add(new Joke(mathContext, Joke.SHARKNADO)); - return result; - } - } - result.add(((Number) parameter1).add((Number) parameter2)); - } - return result; - } - @Override public boolean equals(Object o) { if (o instanceof Sum) { diff --git a/src/main/java/org/warp/picalculator/math/functions/SumSubtraction.java b/src/main/java/org/warp/picalculator/math/functions/SumSubtraction.java index 1babd1c5..a3da6cc5 100755 --- a/src/main/java/org/warp/picalculator/math/functions/SumSubtraction.java +++ b/src/main/java/org/warp/picalculator/math/functions/SumSubtraction.java @@ -21,47 +21,6 @@ public class SumSubtraction extends FunctionOperator { super(root, value1, value2); } - @Override - protected boolean isSolvable() { - if (parameter1 instanceof Number & parameter2 instanceof Number) { - return true; - } - if (NumberRule3.compare(this)) { - return true; - } - if (NumberRule5.compare(this)) { - return true; - } - if (ExpandRule1.compare(this)) { - return true; - } - if (NumberRule4.compare(this)) { - return true; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - if (parameter1 == null || parameter2 == null) { - throw new Error(Errors.SYNTAX_ERROR); - } - ObjectArrayList result = new ObjectArrayList<>(); - if (NumberRule3.compare(this)) { - result = NumberRule3.execute(this); - } else if (NumberRule5.compare(this)) { - result = NumberRule5.execute(this); - } else if (ExpandRule1.compare(this)) { - result = ExpandRule1.execute(this); - } else if (NumberRule4.compare(this)) { - result = NumberRule4.execute(this); - } else if (parameter1.isSimplified() & parameter2.isSimplified()) { - result.add(((Number) parameter1).add((Number) parameter2)); - result.add(((Number) parameter1).add(((Number) parameter2).multiply(new Number(mathContext, "-1")))); - } - return result; - } - @Override public boolean equals(Object o) { if (o instanceof SumSubtraction) { 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 5a8b449d..4f8153a3 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Undefined.java +++ b/src/main/java/org/warp/picalculator/math/functions/Undefined.java @@ -7,6 +7,7 @@ import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -19,13 +20,8 @@ public class Undefined implements Function { } @Override - public List simplify() throws Error { - return null; - } - - @Override - public boolean isSimplified() { - return true; + public ObjectArrayList simplify(Rule rule) throws Error { + return rule.execute(this); } @Override diff --git a/src/main/java/org/warp/picalculator/math/functions/Variable.java b/src/main/java/org/warp/picalculator/math/functions/Variable.java index 5b2df76f..908a9218 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Variable.java +++ b/src/main/java/org/warp/picalculator/math/functions/Variable.java @@ -10,6 +10,7 @@ import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; import org.warp.picalculator.Utils; import org.warp.picalculator.math.MathematicalSymbols; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -59,28 +60,10 @@ public class Variable implements Function { this.n = n; } } - + @Override - public boolean isSimplified() { - if (root.exactMode == false) { - if (var == MathematicalSymbols.PI) { - return false; - } - } - return true; - } - - @Override - public List simplify() throws Error { - final List result = new ObjectArrayList<>(); - if (root.exactMode == false) { - if (var == MathematicalSymbols.PI) { - result.add(new Number(root, BigDecimalMath.pi(new java.math.MathContext(Utils.scale, Utils.scaleMode2)))); - } - } else { - result.add(this); - } - return result; + public ObjectArrayList simplify(Rule rule) throws Error { + return rule.execute(this); } @Override diff --git a/src/main/java/org/warp/picalculator/math/functions/equations/Equation.java b/src/main/java/org/warp/picalculator/math/functions/equations/Equation.java index aa3f7ae8..169d5341 100755 --- a/src/main/java/org/warp/picalculator/math/functions/equations/Equation.java +++ b/src/main/java/org/warp/picalculator/math/functions/equations/Equation.java @@ -23,33 +23,6 @@ public class Equation extends FunctionOperator { super(root, value1, value2); } - @Override - protected boolean isSolvable() { - if (parameter1 instanceof Number & parameter2 instanceof Number) { - return true; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - if (parameter1 == null || parameter2 == null) { - throw new Error(Errors.SYNTAX_ERROR); - } - final ObjectArrayList result = new ObjectArrayList<>(); - if (parameter1.isSimplified() & parameter2.isSimplified()) { - if (((Number) parameter2).getTerm().compareTo(new BigDecimal(0)) == 0) { - result.add(this); - } else { - final Equation e = new Equation(mathContext, null, null); - e.setParameter1(new Subtraction(mathContext, parameter1, parameter2)); - e.setParameter2(new Number(mathContext, "0")); - result.add(e); - } - } - return result; - } - public List solve(char variableCharacter) { @SuppressWarnings("unused") final ObjectArrayList e; diff --git a/src/main/java/org/warp/picalculator/math/functions/equations/EquationsSystem.java b/src/main/java/org/warp/picalculator/math/functions/equations/EquationsSystem.java index 63a48152..52ef5522 100755 --- a/src/main/java/org/warp/picalculator/math/functions/equations/EquationsSystem.java +++ b/src/main/java/org/warp/picalculator/math/functions/equations/EquationsSystem.java @@ -27,45 +27,6 @@ public class EquationsSystem extends FunctionDynamic { super(root, value); } - @Override - protected boolean isSolvable() { - if (functions.length >= 1) { - return true; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error, InterruptedException { - final ObjectArrayList ret = new ObjectArrayList<>(); - if (functions.length == 1) { - if (functions[0].isSimplified()) { - ret.add(functions[0]); - return ret; - } else { - final List l = functions[0].simplify(); - for (final Function f : l) { - if (f instanceof Number) { - ret.add(f); - } else { - ret.add(new Expression(root, f)); - } - } - return ret; - } - } else { - for (final Function f : functions) { - if (f.isSimplified() == false) { - final List partial = f.simplify(); - for (final Function fnc : partial) { - ret.add(new Expression(root, fnc)); - } - } - } - return ret; - } - } - @Override public EquationsSystem clone() { return new EquationsSystem(root, functions); diff --git a/src/main/java/org/warp/picalculator/math/functions/equations/EquationsSystemPart.java b/src/main/java/org/warp/picalculator/math/functions/equations/EquationsSystemPart.java index 867ededc..b13fd468 100755 --- a/src/main/java/org/warp/picalculator/math/functions/equations/EquationsSystemPart.java +++ b/src/main/java/org/warp/picalculator/math/functions/equations/EquationsSystemPart.java @@ -14,18 +14,6 @@ public class EquationsSystemPart extends FunctionSingle { super(root, equazione); } - @Override - protected ObjectArrayList solve() throws Error { - // TODO Auto-generated method stub - return null; - } - - @Override - protected boolean isSolvable() { - // TODO Auto-generated method stub - return false; - } - @Override public boolean equals(Object o) { // TODO Auto-generated method stub diff --git a/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcCosine.java b/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcCosine.java index 0f0ad6d5..839bcf43 100755 --- a/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcCosine.java +++ b/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcCosine.java @@ -15,18 +15,6 @@ public class ArcCosine extends FunctionSingle { super(root, value); } - @Override - public ObjectArrayList solve() throws Error { - // TODO Auto-generated method stub - return null; - } - - @Override - protected boolean isSolvable() { - // TODO Auto-generated method stub - return false; - } - @Override public boolean equals(Object o) { // TODO Auto-generated method stub diff --git a/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcSine.java b/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcSine.java index 9cf07e64..c21b8e52 100755 --- a/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcSine.java +++ b/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcSine.java @@ -15,18 +15,6 @@ public class ArcSine extends FunctionSingle { super(root, value); } - @Override - public ObjectArrayList solve() throws Error { - // TODO Auto-generated method stub - return null; - } - - @Override - protected boolean isSolvable() { - // TODO Auto-generated method stub - return false; - } - @Override public boolean equals(Object o) { // TODO Auto-generated method stub diff --git a/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcTangent.java b/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcTangent.java index d4a3884d..0f6923e4 100755 --- a/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcTangent.java +++ b/src/main/java/org/warp/picalculator/math/functions/trigonometry/ArcTangent.java @@ -15,18 +15,6 @@ public class ArcTangent extends FunctionSingle { super(root, value); } - @Override - public ObjectArrayList solve() throws Error { - // TODO Auto-generated method stub - return null; - } - - @Override - protected boolean isSolvable() { - // TODO Auto-generated method stub - return false; - } - @Override public boolean equals(Object o) { // TODO Auto-generated method stub diff --git a/src/main/java/org/warp/picalculator/math/functions/trigonometry/Cosine.java b/src/main/java/org/warp/picalculator/math/functions/trigonometry/Cosine.java index 4e6bcca6..e8cce9cb 100755 --- a/src/main/java/org/warp/picalculator/math/functions/trigonometry/Cosine.java +++ b/src/main/java/org/warp/picalculator/math/functions/trigonometry/Cosine.java @@ -15,18 +15,6 @@ public class Cosine extends FunctionSingle { super(root, value); } - @Override - public ObjectArrayList solve() throws Error { - // TODO Auto-generated method stub - return null; - } - - @Override - protected boolean isSolvable() { - // TODO Auto-generated method stub - return false; - } - @Override public boolean equals(Object o) { // TODO Auto-generated method stub diff --git a/src/main/java/org/warp/picalculator/math/functions/trigonometry/Sine.java b/src/main/java/org/warp/picalculator/math/functions/trigonometry/Sine.java index 6e159630..914b1014 100755 --- a/src/main/java/org/warp/picalculator/math/functions/trigonometry/Sine.java +++ b/src/main/java/org/warp/picalculator/math/functions/trigonometry/Sine.java @@ -19,31 +19,6 @@ public class Sine extends FunctionSingle { super(root, value); } - @SuppressWarnings("unused") - @Override - protected boolean isSolvable() { - if (parameter instanceof Number) { - if (mathContext.exactMode == false) { - return true; - } - } - if (mathContext.angleMode == AngleMode.DEG) { - final Function[] solvableValues = new Function[] { new Number(mathContext, 0), new Number(mathContext, 30), new Number(mathContext, 90), }; - } - return false; - } - - @Override - public ObjectArrayList solve() throws Error { - final ObjectArrayList results = new ObjectArrayList<>(); - if (parameter instanceof Number) { - if (mathContext.exactMode == false) { - results.add(new Number(mathContext, BigDecimalMath.sin(((Number) parameter).getTerm()))); - } - } - return results; - } - @Override public boolean equals(Object o) { if (o instanceof Sine) { diff --git a/src/main/java/org/warp/picalculator/math/functions/trigonometry/Tangent.java b/src/main/java/org/warp/picalculator/math/functions/trigonometry/Tangent.java index d9822e51..181a0e1d 100755 --- a/src/main/java/org/warp/picalculator/math/functions/trigonometry/Tangent.java +++ b/src/main/java/org/warp/picalculator/math/functions/trigonometry/Tangent.java @@ -14,18 +14,6 @@ public class Tangent extends FunctionSingle { super(root, value); } - @Override - public ObjectArrayList solve() throws Error { - // TODO Auto-generated method stub - return null; - } - - @Override - protected boolean isSolvable() { - // TODO Auto-generated method stub - return false; - } - @Override public boolean equals(Object o) { // TODO Auto-generated method stub diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule11.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule11.java index f827f0f6..ebe63b76 100755 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule11.java +++ b/src/main/java/org/warp/picalculator/math/rules/FractionsRule11.java @@ -29,7 +29,7 @@ public class FractionsRule11 { } a = fnc.getParameter1(); c = div2.getParameter2(); - return new Multiplication(fnc.getMathContext(), a, c).isSimplified() == false; + return new Multiplication(fnc.getMathContext(), a, c).simplify(this) != null; } public static ObjectArrayList execute(Function f) throws Error { diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java index 3426b5ed..f6a623e5 100755 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java +++ b/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java @@ -25,7 +25,7 @@ public class FractionsRule12 { final Division div2 = (Division) fnc.getParameter1(); a = fnc.getParameter1(); c = div2.getParameter2(); - return new Multiplication(fnc.getMathContext(), a, c).isSimplified() == false; + return new Multiplication(fnc.getMathContext(), a, c).simplify(this) != null; } return false; } diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java index 49ad6bfc..42d15aaf 100755 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java +++ b/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java @@ -29,19 +29,19 @@ public class FractionsRule14 { b = div1.getParameter2(); c = div2.getParameter1(); d = div2.getParameter2(); - return new Multiplication(f.getMathContext(), a, c).isSimplified() == false || new Multiplication(f.getMathContext(), b, d).isSimplified() == false; + 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).isSimplified() == false; + 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).isSimplified() == false; + return new Multiplication(f.getMathContext(), a, c).simplify(this) != null; } return false; } 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 f1f1be2b..7c4a52ab 100644 --- a/src/main/java/org/warp/picalculator/math/rules/RulesManager.java +++ b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java @@ -18,6 +18,7 @@ import javax.script.ScriptEngineManager; import javax.script.ScriptException; import org.warp.picalculator.StaticVars; +import org.warp.picalculator.Utils; import org.warp.picalculator.math.MathContext; import org.warp.picalculator.math.functions.Subtraction; import org.warp.picalculator.math.functions.Sum; @@ -50,7 +51,7 @@ public class RulesManager { for (String rulesLine : ruleLines) { String[] ruleDetails = rulesLine.split(",", 1); String ruleName = ruleDetails[0]; - URL resourceURL = StaticVars.classLoader.getResource("rules" + File.separator + ruleName.replace("/", "_") + ".js"); + URL resourceURL = StaticVars.classLoader.getResource("rules" + File.separator + ruleName.replace(".", "_").replace('/', File.separatorChar) + ".js"); if (resourceURL == null) { throw new FileNotFoundException("rules/" + ruleName + ".js not found!"); } @@ -63,12 +64,11 @@ public class RulesManager { } catch (ScriptException e) { e.printStackTrace(); } - System.exit(0); } public static void addRule(Rule rule) { MathContext mc = new MathContext(); - System.out.println(rule.execute(new SumSubtraction(mc, null, new Sum(mc, new Variable(mc, 'x', V_TYPE.VARIABLE), new Variable(mc, 'y', V_TYPE.VARIABLE))))); - System.out.println(rule.getRuleName()); + rules[rule.getRuleType().ordinal()].add(rule); + Utils.out.println(Utils.OUTPUTLEVEL_NODEBUG, "Loaded rule " + rule.getRuleName()); } } diff --git a/src/main/resources/rules.csv b/src/main/resources/rules.csv index 9c440a45..850d45d0 100644 --- a/src/main/resources/rules.csv +++ b/src/main/resources/rules.csv @@ -1,3 +1,4 @@ +functions/Expression ExpandRule1 ExpandRule2 ExpandRule5 \ No newline at end of file diff --git a/src/main/resources/rules/ExpandRule1.js b/src/main/resources/rules/ExpandRule1.js index 42209a07..683ae7a9 100644 --- a/src/main/resources/rules/ExpandRule1.js +++ b/src/main/resources/rules/ExpandRule1.js @@ -76,7 +76,7 @@ var rule = { } if (f instanceof SumSubtraction) { - + } var fnc = expr; diff --git a/src/main/resources/rules/functions/Expression.js b/src/main/resources/rules/functions/Expression.js new file mode 100644 index 00000000..7c85ffff --- /dev/null +++ b/src/main/resources/rules/functions/Expression.js @@ -0,0 +1,47 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Sum = org.warp.picalculator.math.functions.Sum; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var SumSubtraction = org.warp.picalculator.math.functions.SumSubtraction; +var Number = org.warp.picalculator.math.functions.Number; +var Expression = org.warp.picalculator.math.functions.Expression; + +/** + * Expand rule + * -(+a+b) = -a-b + * -(+a-b) = -a+b + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "Expression"; + }, + // 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) { + if (ScriptUtils.instanceOf(f, Expression.class)) { + var result = new ObjectArrayList(); + result.add(f.getParameter(0)); + return result; + } + return null; + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file From 8329b096013bcbe489010fbc25cc433ae77495d5 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Sat, 23 Dec 2017 01:14:38 +0100 Subject: [PATCH 3/7] Fixed rules loading --- .../org/warp/picalculator/StaticVars.java | 2 +- .../java/org/warp/picalculator/Utils.java | 67 +++++++++++++++++++ .../picalculator/math/rules/RulesManager.java | 21 ++++-- 3 files changed, 82 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/warp/picalculator/StaticVars.java b/src/main/java/org/warp/picalculator/StaticVars.java index f0ef99c6..0ab7be8c 100644 --- a/src/main/java/org/warp/picalculator/StaticVars.java +++ b/src/main/java/org/warp/picalculator/StaticVars.java @@ -12,7 +12,7 @@ public class StaticVars { public static boolean debugOn; public static int outputLevel = 5; public static final boolean debugWindow2x = true; - public static final ClassLoader classLoader = StaticVars.class.getClassLoader(); + public static final Class classLoader = Main.instance.getClass(); private StaticVars() { diff --git a/src/main/java/org/warp/picalculator/Utils.java b/src/main/java/org/warp/picalculator/Utils.java index f4f99374..5bef4fe5 100755 --- a/src/main/java/org/warp/picalculator/Utils.java +++ b/src/main/java/org/warp/picalculator/Utils.java @@ -4,6 +4,8 @@ import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -16,9 +18,22 @@ import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.FileSystemAlreadyExistsException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import org.nevec.rjm.BigDecimalMath; import org.nevec.rjm.Rational; @@ -39,6 +54,8 @@ import org.warp.picalculator.math.functions.Variable; import org.warp.picalculator.math.functions.equations.Equation; import org.warp.picalculator.math.functions.equations.EquationsSystemPart; +import com.jogamp.common.util.IOUtil; + import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class Utils { @@ -744,4 +761,54 @@ public class Utils { t.add(o); return t; } + + public static Path getResource(String string) throws IOException, URISyntaxException { + URL res = Main.instance.getClass().getResource(string); + boolean isResource = res != null; + if (isResource) { + try { + final URI uri = res.toURI(); + if (res.getProtocol().equalsIgnoreCase("jar")) { + try { + FileSystems.newFileSystem(uri, Collections.emptyMap()); + } catch (FileSystemAlreadyExistsException e) { + FileSystems.getFileSystem(uri); + } + Path myFolderPath = Paths.get(uri); + return myFolderPath; + } else { + return Paths.get(uri); + } + } catch (java.lang.IllegalArgumentException e) { + throw e; + } + } else { + return Paths.get(string.substring(1)); + } + } + + public static InputStream getResourceStream(String string) throws IOException, URISyntaxException { + URL res = Main.instance.getClass().getResource(string); + boolean isResource = res != null; + if (isResource) { + try { + final URI uri = res.toURI(); + if (res.getProtocol().equalsIgnoreCase("jar")) { + try { + FileSystems.newFileSystem(uri, Collections.emptyMap()); + } catch (FileSystemAlreadyExistsException e) { + FileSystems.getFileSystem(uri); + } + Path myFolderPath = Paths.get(uri); + return Files.newInputStream(myFolderPath); + } else { + return Files.newInputStream(Paths.get(uri)); + } + } catch (java.lang.IllegalArgumentException e) { + throw e; + } + } else { + return Files.newInputStream(Paths.get(string.substring(1))); + } + } } 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 7c4a52ab..a8288ce5 100644 --- a/src/main/java/org/warp/picalculator/math/rules/RulesManager.java +++ b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java @@ -4,6 +4,11 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; +import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; @@ -13,6 +18,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.script.Bindings; +import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; @@ -42,7 +49,7 @@ public class RulesManager { rules[val.ordinal()] = new ObjectArrayList(); } try { - final Path rulesPath = Paths.get(StaticVars.classLoader.getResource("rules.csv").toURI()); + final Path rulesPath = Utils.getResource("/rules.csv"); if (!Files.exists(rulesPath)) { throw new FileNotFoundException("rules.csv not found!"); } @@ -51,12 +58,13 @@ public class RulesManager { for (String rulesLine : ruleLines) { String[] ruleDetails = rulesLine.split(",", 1); String ruleName = ruleDetails[0]; - URL resourceURL = StaticVars.classLoader.getResource("rules" + File.separator + ruleName.replace(".", "_").replace('/', File.separatorChar) + ".js"); - if (resourceURL == null) { - throw new FileNotFoundException("rules/" + ruleName + ".js not found!"); + Utils.out.println("Evaluating /rules/" + ruleName + ".js"); + InputStream resourcePath = Utils.getResourceStream("/rules/" + ruleName.replace(".", "_") + ".js"); + if (resourcePath == null) { + System.err.println(new FileNotFoundException("/rules/" + ruleName + ".js not found!")); + } else { + engine.eval(new InputStreamReader(resourcePath)); } - Path rulePath = Paths.get(resourceURL.toURI()); - engine.eval(new FileReader(rulePath.toString())); } } catch (URISyntaxException | IOException e) { e.printStackTrace(); @@ -67,7 +75,6 @@ public class RulesManager { } public static void addRule(Rule rule) { - MathContext mc = new MathContext(); rules[rule.getRuleType().ordinal()].add(rule); Utils.out.println(Utils.OUTPUTLEVEL_NODEBUG, "Loaded rule " + rule.getRuleName()); } From c18596661f554783ebc9c6986b58aeafda757f75 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Sat, 23 Dec 2017 14:09:42 +0100 Subject: [PATCH 4/7] Added division rule removed also some old and unused resources --- .../org/warp/picalculator/ScriptUtils.java | 23 ++++++ .../java/org/warp/picalculator/Utils.java | 21 ----- .../warp/picalculator/math/rules/Rule.java | 2 + .../draft unknown variable choice.png | Bin 6019 -> 0 bytes src/main/resources/palettetmp.bmp | Bin 4234 -> 0 bytes src/main/resources/rules.csv | 1 + .../resources/rules/functions/Division.js | 74 ++++++++++++++++++ .../resources/rules/functions/Expression.js | 7 +- 8 files changed, 103 insertions(+), 25 deletions(-) delete mode 100755 src/main/resources/draft unknown variable choice.png delete mode 100755 src/main/resources/palettetmp.bmp create mode 100644 src/main/resources/rules/functions/Division.js diff --git a/src/main/java/org/warp/picalculator/ScriptUtils.java b/src/main/java/org/warp/picalculator/ScriptUtils.java index b71e6b19..e4fbe35c 100644 --- a/src/main/java/org/warp/picalculator/ScriptUtils.java +++ b/src/main/java/org/warp/picalculator/ScriptUtils.java @@ -1,7 +1,30 @@ package org.warp.picalculator; +import java.math.BigInteger; +import java.util.Iterator; +import java.util.LinkedList; + public class ScriptUtils { public static boolean instanceOf(Object a, Class b) { return b.isInstance(a); } + + public static LinkedList mcm(LinkedList factors1, LinkedList factors2) { + LinkedList mcm = new LinkedList<>(); + Iterator i1 = factors1.iterator(); + while(i1.hasNext()) { + BigInteger int1 = i1.next(); + Iterator i2 = factors2.iterator(); + while(i2.hasNext()) { + BigInteger int2 = i2.next(); + if (int1.equals(int2)) { + i1.remove(); + i2.remove(); + mcm.add(int1); + break; + } + } + } + return mcm; + } } diff --git a/src/main/java/org/warp/picalculator/Utils.java b/src/main/java/org/warp/picalculator/Utils.java index 5bef4fe5..2cb57243 100755 --- a/src/main/java/org/warp/picalculator/Utils.java +++ b/src/main/java/org/warp/picalculator/Utils.java @@ -30,8 +30,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -728,25 +726,6 @@ public class Utils { return (OS.indexOf("win") >= 0); } - public static LinkedList mcm(LinkedList factors1, LinkedList factors2) { - LinkedList mcm = new LinkedList<>(); - Iterator i1 = factors1.iterator(); - while(i1.hasNext()) { - BigInteger int1 = i1.next(); - Iterator i2 = factors2.iterator(); - while(i2.hasNext()) { - BigInteger int2 = i2.next(); - if (int1.equals(int2)) { - i1.remove(); - i2.remove(); - mcm.add(int1); - break; - } - } - } - return mcm; - } - public static void gc() { Object obj = new Object(); final WeakReference ref = new WeakReference<>(obj); diff --git a/src/main/java/org/warp/picalculator/math/rules/Rule.java b/src/main/java/org/warp/picalculator/math/rules/Rule.java index ea1befd3..821bd3b3 100644 --- a/src/main/java/org/warp/picalculator/math/rules/Rule.java +++ b/src/main/java/org/warp/picalculator/math/rules/Rule.java @@ -3,6 +3,7 @@ package org.warp.picalculator.math.rules; import org.warp.picalculator.math.Function; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import jdk.nashorn.internal.objects.annotations.SpecializedFunction; /** * Rule interface @@ -22,6 +23,7 @@ public interface Rule { * Get rule type * @return */ + @SpecializedFunction public RuleType getRuleType(); /** diff --git a/src/main/resources/draft unknown variable choice.png b/src/main/resources/draft unknown variable choice.png deleted file mode 100755 index 973440c9c479ed6694ec4cd3e9b543b7a5af45ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6019 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 diff --git a/src/main/resources/palettetmp.bmp b/src/main/resources/palettetmp.bmp deleted file mode 100755 index db22ad4f58d6074a246c9c282cc785c7b23d245e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4234 zcmZ?r?Gj)BgDxOh1H=kY%m`#L1KA8fd0}n{25}+aKLY~Xeyt- z{r`UeF~b1bJ&^t$wR>RG-Dvm^jqv|`?#5?QFs1QIid~edg}Iedb12dOpTzK`#4c=l z2iksYZWERZbJun(*H^_csFfo27 z#vEid|B194Sr3Sf>=tynQ9g0;ITFI@UEiX2FibE1!tBFElj06sW>7;M><*;xp@x|# qW`q{Kdxs4p+4%~IjiMJOj; if it did something + */ + execute: function(f) { + if (ScriptUtils.instanceOf(f, Division.class)) { + var result = new ObjectArrayList(); + var variable1 = f.getParameter1(); + var variable2 = f.getParameter2(); + var mathContext = f.getMathContext(); + if (ScriptUtils.instanceOf(variable1, Number.class) && ScriptUtils.instanceOf(variable2, Number.class)) { + if (mathContext.exactMode) { + if (variable1.isInteger() && variable2.isInteger()) { + var factors1, factors2, mcm; + try { + factors1 = variable1.getFactors(); + factors2 = variable2.getFactors(); + mcm = ScriptUtils.mcm(factors1, factors2); + } catch (error) { + return null; + } + if (mcm.size() > 0) { //true if there is at least one common factor + //divide by the common factor (ab/cb = a/c) + var nmb1 = variable1.term.toBigIntegerExact(); + var nmb2 = variable2.term.toBigIntegerExact(); + mcm.forEach(function(integerNumber) { + nmb1 = nmb1.divide(integerNumber); + nmb2 = nmb2.divide(integerNumber); + }); + result.add(new Division(mathContext, new Number(mathContext, nmb1), new Number(mathContext, nmb2))); + } + } + } else { + //divide a by b (a/b = c) + result.add(variable1.divide(variable2)); + } + } + } + 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/functions/Expression.js b/src/main/resources/rules/functions/Expression.js index 7c85ffff..62457c39 100644 --- a/src/main/resources/rules/functions/Expression.js +++ b/src/main/resources/rules/functions/Expression.js @@ -12,9 +12,8 @@ var Number = org.warp.picalculator.math.functions.Number; var Expression = org.warp.picalculator.math.functions.Expression; /** - * Expand rule - * -(+a+b) = -a-b - * -(+a-b) = -a+b + * Expression + * (x) = x * * @author Andrea Cavalli * @@ -26,7 +25,7 @@ var rule = { }, // Rule type getRuleType: function() { - return RuleType.EXPANSION; + return RuleType.CALCULATION; }, /* Rule function Returns: From aa9e36d72cf8fa5a1b662d8e0e2427a9c09e39ed Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Sat, 23 Dec 2017 15:04:30 +0100 Subject: [PATCH 5/7] Updated Division.js --- src/main/resources/rules/functions/Division.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/rules/functions/Division.js b/src/main/resources/rules/functions/Division.js index f25e9f36..486d7e6a 100644 --- a/src/main/resources/rules/functions/Division.js +++ b/src/main/resources/rules/functions/Division.js @@ -58,11 +58,13 @@ var rule = { nmb2 = nmb2.divide(integerNumber); }); result.add(new Division(mathContext, new Number(mathContext, nmb1), new Number(mathContext, nmb2))); + return result; } } } else { //divide a by b (a/b = c) result.add(variable1.divide(variable2)); + return result; } } } From 86c5fa28186292aa22e8a29abad0d0f1f776510b Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Sat, 23 Dec 2017 15:20:42 +0100 Subject: [PATCH 6/7] Added JIT warp-up phase --- src/main/java/org/warp/picalculator/Main.java | 4 +++ .../gui/screens/LoadingScreen.java | 3 +- .../picalculator/math/rules/RulesManager.java | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/warp/picalculator/Main.java b/src/main/java/org/warp/picalculator/Main.java index 20aae58b..6a8d4f8e 100755 --- a/src/main/java/org/warp/picalculator/Main.java +++ b/src/main/java/org/warp/picalculator/Main.java @@ -25,6 +25,9 @@ public class Main { beforeStart(); new DisplayManager(screen); afterStart(); + if (screen instanceof LoadingScreen) { + ((LoadingScreen) screen).loaded = true; + } DisplayManager.INSTANCE.waitForExit(); Utils.out.println(1, "Shutdown..."); beforeShutdown(); @@ -82,6 +85,7 @@ public class Main { public void afterStart() { DisplayManager.INSTANCE.setBrightness(0.2f); RulesManager.initialize(); + RulesManager.warmUp(); } public void beforeShutdown() { diff --git a/src/main/java/org/warp/picalculator/gui/screens/LoadingScreen.java b/src/main/java/org/warp/picalculator/gui/screens/LoadingScreen.java index f9f086c8..bb807602 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/LoadingScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/LoadingScreen.java @@ -10,6 +10,7 @@ public class LoadingScreen extends Screen { public float endLoading; boolean mustRefresh = true; public float loadingTextTranslation = 0.0f; + public boolean loaded = false; public LoadingScreen() { super(); @@ -29,7 +30,7 @@ public class LoadingScreen extends Screen { loadingTextTranslation = GraphicUtils.sinDeg(endLoading * 90f) * 10f; endLoading += dt; - if (StaticVars.debugOn || endLoading >= 5f) { + if (loaded && (StaticVars.debugOn || endLoading >= 3.5f)) { DisplayManager.INSTANCE.setScreen(new MathInputScreen()); } mustRefresh = true; 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 a8288ce5..90ae94b8 100644 --- a/src/main/java/org/warp/picalculator/math/rules/RulesManager.java +++ b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java @@ -24,9 +24,13 @@ import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; +import org.warp.picalculator.Error; import org.warp.picalculator.StaticVars; import org.warp.picalculator.Utils; +import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.MathSolver; +import org.warp.picalculator.math.functions.Expression; import org.warp.picalculator.math.functions.Subtraction; import org.warp.picalculator.math.functions.Sum; import org.warp.picalculator.math.functions.SumSubtraction; @@ -73,6 +77,31 @@ public class RulesManager { e.printStackTrace(); } } + + public static void warmUp() { + ObjectArrayList uselessResult = null; + boolean uselessVariable; + for (RuleType val : RuleType.values()) { + final ObjectArrayList ruleList = rules[val.ordinal()]; + for (final Rule rule : ruleList) { + ObjectArrayList uselessResult2 = rule.execute(generateUselessExpression()); + uselessVariable = (uselessResult == null ? new ObjectArrayList<>() : uselessResult).equals(uselessResult2); + uselessResult = uselessResult2; + } + } + try { + new MathSolver(generateUselessExpression()).solveAllSteps(); + } catch (InterruptedException | Error e) { + e.printStackTrace(); + } + } + + private static Expression generateUselessExpression() { + MathContext mc = new MathContext(); + Expression expr = new Expression(mc); + expr = (Expression) expr.setParameter(new Variable(mc, 'x', V_TYPE.VARIABLE)); + return expr; + } public static void addRule(Rule rule) { rules[rule.getRuleType().ordinal()].add(rule); From 04555e77a4c00b10f4907972900261b19c75d557 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Sun, 24 Dec 2017 11:59:09 +0100 Subject: [PATCH 7/7] Updated rules --- .../gui/graphicengine/cpu/CPUFont.java | 4 - .../picalculator/math/rules/RulesManager.java | 25 +++--- src/main/resources/rules.csv | 16 +++- .../resources/rules/functions/EmptyNumber.js | 35 +++++++++ src/main/resources/rules/functions/Joke.js | 35 +++++++++ .../rules/functions/Multiplication.js | 52 +++++++++++++ .../resources/rules/functions/Negative.js | 62 +++++++++++++++ src/main/resources/rules/functions/Number.js | 49 ++++++++++++ src/main/resources/rules/functions/Power.js | 53 +++++++++++++ src/main/resources/rules/functions/Root.js | 78 +++++++++++++++++++ 10 files changed, 390 insertions(+), 19 deletions(-) create mode 100644 src/main/resources/rules/functions/EmptyNumber.js create mode 100644 src/main/resources/rules/functions/Joke.js create mode 100644 src/main/resources/rules/functions/Multiplication.js create mode 100644 src/main/resources/rules/functions/Negative.js create mode 100644 src/main/resources/rules/functions/Number.js create mode 100644 src/main/resources/rules/functions/Power.js create mode 100644 src/main/resources/rules/functions/Root.js diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/cpu/CPUFont.java b/src/main/java/org/warp/picalculator/gui/graphicengine/cpu/CPUFont.java index 699965a4..f87fbb0b 100755 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/cpu/CPUFont.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/cpu/CPUFont.java @@ -4,9 +4,7 @@ import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.io.File; import java.io.IOException; -import java.lang.ref.WeakReference; import java.net.URL; -import java.util.Arrays; import java.util.LinkedList; import java.util.logging.Level; import java.util.logging.Logger; @@ -17,8 +15,6 @@ import org.warp.picalculator.Utils; import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.GraphicEngine; -import com.sun.xml.internal.bind.v2.model.util.ArrayInfoUtil; - public class CPUFont implements BinaryFont { public boolean[][] rawchars; 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 90ae94b8..5ab7dc67 100644 --- a/src/main/java/org/warp/picalculator/math/rules/RulesManager.java +++ b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java @@ -59,15 +59,18 @@ public class RulesManager { } ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); List ruleLines = Files.readAllLines(rulesPath); + ruleLines.remove(0); //Remove the headers for (String rulesLine : ruleLines) { - String[] ruleDetails = rulesLine.split(",", 1); - String ruleName = ruleDetails[0]; - Utils.out.println("Evaluating /rules/" + ruleName + ".js"); - InputStream resourcePath = Utils.getResourceStream("/rules/" + ruleName.replace(".", "_") + ".js"); - if (resourcePath == null) { - System.err.println(new FileNotFoundException("/rules/" + ruleName + ".js not found!")); - } else { - engine.eval(new InputStreamReader(resourcePath)); + if (rulesLine.length() > 0) { + String[] ruleDetails = rulesLine.split(",", 1); + String ruleName = ruleDetails[0]; + Utils.out.println("Evaluating /rules/" + ruleName + ".js"); + InputStream resourcePath = Utils.getResourceStream("/rules/" + ruleName.replace(".", "_") + ".js"); + if (resourcePath == null) { + System.err.println(new FileNotFoundException("/rules/" + ruleName + ".js not found!")); + } else { + engine.eval(new InputStreamReader(resourcePath)); + } } } } catch (URISyntaxException | IOException e) { @@ -96,10 +99,10 @@ public class RulesManager { } } - private static Expression generateUselessExpression() { + private static Function generateUselessExpression() { MathContext mc = new MathContext(); - Expression expr = new Expression(mc); - expr = (Expression) expr.setParameter(new Variable(mc, 'x', V_TYPE.VARIABLE)); + Function expr = new Expression(mc); + expr = expr.setParameter(0, new Variable(mc, 'x', V_TYPE.VARIABLE)); return expr; } diff --git a/src/main/resources/rules.csv b/src/main/resources/rules.csv index dd5be13a..9145d4ca 100644 --- a/src/main/resources/rules.csv +++ b/src/main/resources/rules.csv @@ -1,5 +1,13 @@ -functions/Expression -functions/Division -ExpandRule1 -ExpandRule2 +Rule file +functions/Division +functions/EmptyNumber +functions/Expression +functions/Joke +functions/Multiplication +functions/Negative +functions/Number +functions/Power +functions/Root +ExpandRule1 +ExpandRule2 ExpandRule5 \ No newline at end of file diff --git a/src/main/resources/rules/functions/EmptyNumber.js b/src/main/resources/rules/functions/EmptyNumber.js new file mode 100644 index 00000000..3c1eaf1e --- /dev/null +++ b/src/main/resources/rules/functions/EmptyNumber.js @@ -0,0 +1,35 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; + +/** + * EmptyNumber + * + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "EmptyNumber"; + }, + // 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) { + 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/functions/Joke.js b/src/main/resources/rules/functions/Joke.js new file mode 100644 index 00000000..8f12f600 --- /dev/null +++ b/src/main/resources/rules/functions/Joke.js @@ -0,0 +1,35 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; + +/** + * Joke + * + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "Joke"; + }, + // 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) { + 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/functions/Multiplication.js b/src/main/resources/rules/functions/Multiplication.js new file mode 100644 index 00000000..58be484b --- /dev/null +++ b/src/main/resources/rules/functions/Multiplication.js @@ -0,0 +1,52 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Sum = org.warp.picalculator.math.functions.Sum; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var SumSubtraction = org.warp.picalculator.math.functions.SumSubtraction; +var Number = org.warp.picalculator.math.functions.Number; +var Division = org.warp.picalculator.math.functions.Division; + +/** + * Multiplication + * a*b = c + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "Multiplication"; + }, + // 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) { + if (ScriptUtils.instanceOf(f, Multiplication.class)) { + var result = new ObjectArrayList(); + var variable1 = f.getParameter1(); + var variable2 = f.getParameter2(); + var mathContext = f.getMathContext(); + if (ScriptUtils.instanceOf(variable1, Number.class) && ScriptUtils.instanceOf(variable2, Number.class)) { + //multiply a by b (a*b = c) + result.add(variable1.multiply(variable2)); + return result; + } + } + 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/functions/Negative.js b/src/main/resources/rules/functions/Negative.js new file mode 100644 index 00000000..f2523cd0 --- /dev/null +++ b/src/main/resources/rules/functions/Negative.js @@ -0,0 +1,62 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; +var Number = org.warp.picalculator.math.functions.Number; +var Negative = org.warp.picalculator.math.functions.Negative; +var Error = org.warp.picalculator.Error; +var Errors = org.warp.picalculator.Errors; +var NullPointerException = java.lang.NullPointerException; +var NumberFormatException = java.lang.NumberFormatException; +var ArithmeticException = java.lang.ArithmeticException; + +/** + * Negative + * -a = b + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "Negative"; + }, + // 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) { + if (ScriptUtils.instanceOf(f, Negative.class)) { + var result = new ObjectArrayList(); + var variable = f.getParameter(); + var mathContext = f.getMathContext(); + if (ScriptUtils.instanceOf(variable, Number.class)) { + //-a = a*-1 = b + try { + result.add(variable.multiply(new Number(mathContext, -1))); + } catch (ex) { + if (ScriptUtils.instanceOf(ex, NullPointerException.class)) { + throw new Error(Errors.ERROR); + } else if (ScriptUtils.instanceOf(ex, NumberFormatException.class)) { + throw new Error(Errors.SYNTAX_ERROR); + } else if (ScriptUtils.instanceOf(ex, ArithmeticException.class)) { + throw new Error(Errors.NUMBER_TOO_SMALL); + } + } + return result; + } + } + 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/functions/Number.js b/src/main/resources/rules/functions/Number.js new file mode 100644 index 00000000..b2c2bdfe --- /dev/null +++ b/src/main/resources/rules/functions/Number.js @@ -0,0 +1,49 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; +var BigInteger = java.math.BigInteger; + +/** + * Number + * + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "Number"; + }, + // 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) { + if (ScriptUtils.instanceOf(f, Number.class)) { + var result = new ObjectArrayList(); + var mathContext = f.getMathContext(); + if (mathContext.exactMode) { + if (f.isInteger() == false) { + var divisor = new Number(mathContext, BigInteger.TEN.pow(f.getNumberOfDecimalPlaces())); + var number = new Number(mathContext, f.getTerm().multiply(divisor.term)); + var div = new Division(mathContext, number, divisor); + result.add(div); + return result; + } + } + } + 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/functions/Power.js b/src/main/resources/rules/functions/Power.js new file mode 100644 index 00000000..c7feccef --- /dev/null +++ b/src/main/resources/rules/functions/Power.js @@ -0,0 +1,53 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Sum = org.warp.picalculator.math.functions.Sum; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var SumSubtraction = org.warp.picalculator.math.functions.SumSubtraction; +var Number = org.warp.picalculator.math.functions.Number; +var Division = org.warp.picalculator.math.functions.Division; +var Power = org.warp.picalculator.math.functions.Power; + +/** + * Power + * a^b = c + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "Power"; + }, + // 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) { + if (ScriptUtils.instanceOf(f, Power.class)) { + var result = new ObjectArrayList(); + var variable1 = f.getParameter1(); + var variable2 = f.getParameter2(); + var mathContext = f.getMathContext(); + if (ScriptUtils.instanceOf(variable1, Number.class) && ScriptUtils.instanceOf(variable2, Number.class)) { + //a^b = c + result.add(variable1.pow(variable2)); + return result; + } + } + 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/functions/Root.js b/src/main/resources/rules/functions/Root.js new file mode 100644 index 00000000..5f9f8f73 --- /dev/null +++ b/src/main/resources/rules/functions/Root.js @@ -0,0 +1,78 @@ +// Imports +var ObjectArrayList = Java.type("it.unimi.dsi.fastutil.objects.ObjectArrayList"); +var ScriptUtils = org.warp.picalculator.ScriptUtils; +var Rule = org.warp.picalculator.math.rules.Rule; +var RuleType = org.warp.picalculator.math.rules.RuleType; +var RulesManager = org.warp.picalculator.math.rules.RulesManager; +var Multiplication = org.warp.picalculator.math.functions.Multiplication; +var Sum = org.warp.picalculator.math.functions.Sum; +var Subtraction = org.warp.picalculator.math.functions.Subtraction; +var SumSubtraction = org.warp.picalculator.math.functions.SumSubtraction; +var Number = org.warp.picalculator.math.functions.Number; +var Division = org.warp.picalculator.math.functions.Division; +var Root = org.warp.picalculator.math.functions.Root; +var RootSquare = org.warp.picalculator.math.functions.RootSquare; +var BigDecimal = java.math.BigDecimal; + +/** + * Root + * a√b = c + * + * @author Andrea Cavalli + * + */ +var rule = { + // Rule name + getRuleName: function() { + return "Power"; + }, + // 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 isSquare = false; + if (ScriptUtils.instanceOf(f, Root.class) || (isSquare = ScriptUtils.instanceOf(f, RootSquare.class))) { + var result = new ObjectArrayList(); + var mathContext = f.getMathContext(); + var variable1 = isSquare?new Number(mathContext, 2):f.getParameter1(); + var variable2 = isSquare?f.getParameter():f.getParameter2(); + var isSolvable = false; + var canBePorted = false; + if (ScriptUtils.instanceOf(variable1, Number.class) && ScriptUtils.instanceOf(variable2, Number.class)) { + isSolvable = isSolvable|!mathContext.exactMode; + if (!isSolvable) { + try { + var resultVar = variable2.pow(new Number(mathContext, BigDecimal.ONE).divide(variable1)); + var originalVariable = resultVar.pow(new Number(mathContext, 2)); + if (originalVariable.equals(parameter2)) { + isSolvable = true; + } + } catch (ex) { + ex.printStackTrace(); + } + } + } + if (!isSquare && !isSolvable && ScriptUtils.instanceOf(variable1, Number.class) && variable1.equals(new Number(mathContext, 2))) { + canBePorted = true; + } + + if (isSolvable) { + result.add(variable2.pow(new Number(mathContext, BigInteger.ONE).divide(variable1))); + return result; + } + if (canBePorted) { + result.add(new RootSquare(mathContext, variable2)); + } + } + return null; + } +} + +//Add this rule to the list of rules +RulesManager.addRule(engine.getInterface(rule, Rule.class)); \ No newline at end of file