Redefined Functions
This commit is contained in:
parent
45859b266a
commit
bc6609d7dd
@ -538,15 +538,6 @@ public class Utils {
|
||||
return realbytes;
|
||||
}
|
||||
|
||||
public static boolean allSolved(List<Function> expressions) throws Error, InterruptedException {
|
||||
for (final Function itm : expressions) {
|
||||
if (itm.isSimplified() == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Function[][] joinFunctionsResults(List<Function> l1, List<Function> l2) {
|
||||
final int size1 = l1.size();
|
||||
final int size2 = l2.size();
|
||||
@ -747,4 +738,10 @@ public class Utils {
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> ObjectArrayList<T> newArrayList(T o) {
|
||||
ObjectArrayList<T> t = new ObjectArrayList<T>();
|
||||
t.add(o);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
@ -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<Function> resultExpressions = new ObjectArrayList<>();
|
||||
resultExpressions.add(expr.getParameter());
|
||||
while (!done && stop < (step?currentStep:3000)) {
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
ObjectArrayList<Function> 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<Function> fncResult = ((Expression) f).solve();
|
||||
for (Function resultItem : fncResult) {
|
||||
newResultExpressions.add(resultItem);
|
||||
}
|
||||
} else {
|
||||
List<Function> 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<ObjectArrayList<Function>> resultSteps = ms.solveAllSteps();
|
||||
resultSteps.add(0, Utils.newArrayList(expr));
|
||||
ObjectArrayList<Function> resultExpressions = resultSteps.get(resultSteps.size() - 1);
|
||||
for (Function rr : resultExpressions) {
|
||||
Utils.out.println(1, "RESULT: " + rr.toString());
|
||||
}
|
||||
|
@ -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 <b>rule</b>
|
||||
* @param rule
|
||||
* @return A list of the resulting Functions if the rule is applicable and something changed, <b>null</b> otherwise
|
||||
* @throws Error
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public List<Function> 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<Function> simplify(Rule rule) throws Error, InterruptedException;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -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 <strong>true</strong> if this function can be solved, otherwise
|
||||
* <strong>false</strong>.
|
||||
*/
|
||||
protected abstract boolean isSolvable();
|
||||
|
||||
@Override
|
||||
public final ObjectArrayList<Function> simplify() throws Error, InterruptedException {
|
||||
boolean solved = true;
|
||||
public final ObjectArrayList<Function> 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<Function> result = solved ? solve() : null;
|
||||
ObjectArrayList<Function> result = new ObjectArrayList<>();
|
||||
|
||||
if (result == null || result.isEmpty()) {
|
||||
result = new ObjectArrayList<>();
|
||||
|
||||
final ObjectArrayList<ObjectArrayList<Function>> ln = new ObjectArrayList<>();
|
||||
for (final Function fnc : fncs) {
|
||||
final ObjectArrayList<Function> 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<ObjectArrayList<Function>> ln = new ObjectArrayList<>();
|
||||
boolean alreadySolved = true;
|
||||
for (final Function fnc : fncs) {
|
||||
final ObjectArrayList<Function> l = new ObjectArrayList<>();
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
ObjectArrayList<Function> 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<Function> solve() throws Error, InterruptedException;
|
||||
|
||||
@Override
|
||||
public MathContext getMathContext() {
|
||||
return root;
|
||||
|
@ -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<Function> 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 <strong>true</strong> if this function can be solved, otherwise
|
||||
* <strong>false</strong>.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
protected abstract boolean isSolvable() throws InterruptedException;
|
||||
|
||||
@Override
|
||||
public final ObjectArrayList<Function> simplify() throws Error, InterruptedException {
|
||||
ObjectArrayList<Function> simplifiedParam1 = parameter1.simplify(rule);
|
||||
ObjectArrayList<Function> 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<Function> result = new ObjectArrayList<>();
|
||||
|
||||
final ObjectArrayList<Function> l1 = new ObjectArrayList<>();
|
||||
final ObjectArrayList<Function> l2 = new ObjectArrayList<>();
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
ObjectArrayList<Function> result = solved ? solve() : null;;
|
||||
|
||||
if (result == null || result.isEmpty()) {
|
||||
result = new ObjectArrayList<>();
|
||||
|
||||
final ObjectArrayList<Function> l1 = new ObjectArrayList<>();
|
||||
final ObjectArrayList<Function> 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<Function> solve() throws Error, InterruptedException;
|
||||
|
||||
@Override
|
||||
public abstract FunctionOperator clone();
|
||||
|
||||
|
@ -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<Function> simplify() throws Error, InterruptedException {
|
||||
final boolean simplified = parameter.isSimplified();
|
||||
ObjectArrayList<Function> result = simplified ? solve() : null;
|
||||
|
||||
if (result == null || result.isEmpty()) {
|
||||
result = new ObjectArrayList<>();
|
||||
|
||||
final ObjectArrayList<Function> 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<Function> simplify(Rule rule) throws Error, InterruptedException {
|
||||
ObjectArrayList<Function> simplifiedParam = parameter.simplify(rule);
|
||||
if (simplifiedParam == null) return rule.execute(this);
|
||||
|
||||
ObjectArrayList<Function> 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<Function> 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 <strong>true</strong> if this function can be solved, otherwise
|
||||
* <strong>false</strong>.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
protected abstract boolean isSolvable() throws InterruptedException;
|
||||
|
||||
@Override
|
||||
public abstract FunctionSingle clone();
|
||||
|
||||
|
@ -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<Function>[] lastFunctions = new ObjectArrayList[stepStates.length];
|
||||
|
||||
public MathSolver(MathContext mathContext, Function initialFunction) {
|
||||
this.mathContext = mathContext;
|
||||
public MathSolver(Function initialFunction) {
|
||||
this.initialFunction = initialFunction;
|
||||
}
|
||||
|
||||
public ObjectArrayList<ObjectArrayList<Function>> solveAllSteps() {
|
||||
public ObjectArrayList<ObjectArrayList<Function>> solveAllSteps() throws InterruptedException, Error {
|
||||
ObjectArrayList<ObjectArrayList<Function>> steps = new ObjectArrayList<>();
|
||||
ObjectArrayList<Function> 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<Function> 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<Function> solveStep(Function fnc) {
|
||||
private ObjectArrayList<Function> solveStep(ObjectArrayList<Function> 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<Rule> rules = mathContext.getAcceptableRules(currentAcceptedRules);
|
||||
ObjectArrayList<Rule> rules = initialFunction.getMathContext().getAcceptableRules(currentAcceptedRules);
|
||||
ObjectArrayList<Function> results = null;
|
||||
for (Rule rule : rules) {
|
||||
ObjectArrayList<Function> ruleResults = rule.execute(fnc);
|
||||
if (ruleResults != null && !ruleResults.isEmpty()) {
|
||||
results = ruleResults;
|
||||
break;
|
||||
Rule appliedRule = null;
|
||||
for (Function fnc : fncs) {
|
||||
for (Rule rule : rules) {
|
||||
List<Function> ruleResults = fnc.simplify(rule);
|
||||
if (ruleResults != null && !ruleResults.isEmpty()) {
|
||||
if (results == null) results = new ObjectArrayList<Function>();
|
||||
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;
|
||||
}
|
||||
|
@ -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<BigInteger> factors1 = ((Number) variable1).getFactors();
|
||||
LinkedList<BigInteger> factors2 = ((Number) variable2).getFactors();
|
||||
LinkedList<BigInteger> 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<Function> solve() throws Error, InterruptedException {
|
||||
final Function variable1 = getParameter1();
|
||||
final Function variable2 = getParameter2();
|
||||
ObjectArrayList<Function> 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<BigInteger> factors1 = ((Number) variable1).getFactors();
|
||||
LinkedList<BigInteger> factors2 = ((Number) variable2).getFactors();
|
||||
LinkedList<BigInteger> 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) {
|
||||
|
@ -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<Function> simplify() throws Error {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimplified() {
|
||||
return false;
|
||||
public ObjectArrayList<Function> simplify(Rule rule) throws Error {
|
||||
return rule.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
final ObjectArrayList<Function> ret = new ObjectArrayList<>();
|
||||
if (getParameter().isSimplified() || !parenthesisNeeded()) {
|
||||
ret.add(getParameter());
|
||||
return ret;
|
||||
} else {
|
||||
final List<Function> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Function> simplify() throws Error {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimplified() {
|
||||
return true;
|
||||
public ObjectArrayList<Function> simplify(Rule rule) throws Error {
|
||||
return rule.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
ObjectArrayList<Function> 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) {
|
||||
|
@ -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<Function> solve() throws Error {
|
||||
if (parameter == null) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
ObjectArrayList<Function> 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) {
|
||||
|
@ -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<Function> simplify() throws Error {
|
||||
final List<Function> 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<Function> simplify(Rule rule) throws Error {
|
||||
return rule.execute(this);
|
||||
}
|
||||
|
||||
public int getNumberOfDecimalPlaces() {
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
final ObjectArrayList<Function> 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) {
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
final ObjectArrayList<Function> 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) {
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
final ObjectArrayList<Function> 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) {
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
ObjectArrayList<Function> 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) {
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
if (parameter1 == null || parameter2 == null) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
ObjectArrayList<Function> 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) {
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
if (parameter1 == null || parameter2 == null) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
ObjectArrayList<Function> 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) {
|
||||
|
@ -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<Function> simplify() throws Error {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimplified() {
|
||||
return true;
|
||||
public ObjectArrayList<Function> simplify(Rule rule) throws Error {
|
||||
return rule.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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<Function> simplify() throws Error {
|
||||
final List<Function> 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<Function> simplify(Rule rule) throws Error {
|
||||
return rule.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
if (parameter1 == null || parameter2 == null) {
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
}
|
||||
final ObjectArrayList<Function> 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<Function> solve(char variableCharacter) {
|
||||
@SuppressWarnings("unused")
|
||||
final ObjectArrayList<Equation> e;
|
||||
|
@ -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<Function> solve() throws Error, InterruptedException {
|
||||
final ObjectArrayList<Function> ret = new ObjectArrayList<>();
|
||||
if (functions.length == 1) {
|
||||
if (functions[0].isSimplified()) {
|
||||
ret.add(functions[0]);
|
||||
return ret;
|
||||
} else {
|
||||
final List<Function> 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<Function> 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);
|
||||
|
@ -14,18 +14,6 @@ public class EquationsSystemPart extends FunctionSingle {
|
||||
super(root, equazione);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectArrayList<Function> 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
|
||||
|
@ -15,18 +15,6 @@ public class ArcCosine extends FunctionSingle {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectArrayList<Function> 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
|
||||
|
@ -15,18 +15,6 @@ public class ArcSine extends FunctionSingle {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectArrayList<Function> 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
|
||||
|
@ -15,18 +15,6 @@ public class ArcTangent extends FunctionSingle {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectArrayList<Function> 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
|
||||
|
@ -15,18 +15,6 @@ public class Cosine extends FunctionSingle {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectArrayList<Function> 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
|
||||
|
@ -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<Function> solve() throws Error {
|
||||
final ObjectArrayList<Function> 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) {
|
||||
|
@ -14,18 +14,6 @@ public class Tangent extends FunctionSingle {
|
||||
super(root, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectArrayList<Function> 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
|
||||
|
@ -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<Function> execute(Function f) throws Error {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
functions/Expression
|
||||
ExpandRule1
|
||||
ExpandRule2
|
||||
ExpandRule5
|
|
@ -76,7 +76,7 @@ var rule = {
|
||||
}
|
||||
|
||||
if (f instanceof SumSubtraction) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
var fnc = expr;
|
||||
|
47
src/main/resources/rules/functions/Expression.js
Normal file
47
src/main/resources/rules/functions/Expression.js
Normal file
@ -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<Function> 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));
|
Loading…
Reference in New Issue
Block a user