Changed some rules and removed all the "SyntaxRule" ones

Added parentheses where needed in the output.
This commit is contained in:
Andrea Cavalli 2017-11-01 22:34:35 +01:00
parent 12478f1cb9
commit f24511ffd7
17 changed files with 130 additions and 235 deletions

View File

@ -39,6 +39,11 @@ public class BlockContainer implements GraphicalElement {
autoMinimums = true;
}
public BlockContainer(boolean small, ObjectArrayList<Block> content) {
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), content, true);
autoMinimums = true;
}
public BlockContainer(boolean small, boolean withBorder) {
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
autoMinimums = true;

View File

@ -6,11 +6,17 @@ import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.parser.features.FeatureParenthesis;
import org.warp.picalculator.math.parser.features.interfaces.Feature;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockParenthesis extends BlockParenthesisAbstract {
public BlockParenthesis() {
super();
}
public BlockParenthesis(ObjectArrayList<Block> blocks) {
super(blocks);
}
@Override
public Feature toFeature(MathContext context) throws Error {
final Function cont = getNumberContainer().toFunction(context);

View File

@ -7,6 +7,8 @@ import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.parser.features.interfaces.Feature;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public abstract class BlockParenthesisAbstract extends Block {
private final BlockContainer containerNumber;
@ -29,6 +31,12 @@ public abstract class BlockParenthesisAbstract extends Block {
recomputeDimensions();
}
public BlockParenthesisAbstract(ObjectArrayList<Block> blocks) {
containerNumber = new BlockContainer(false, blocks);
this.prefix = null;
recomputeDimensions();
}
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);

View File

@ -8,13 +8,12 @@ import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.rules.ExpandRule1;
import org.warp.picalculator.math.rules.ExponentRule15;
import org.warp.picalculator.math.rules.ExponentRule16;
import org.warp.picalculator.math.rules.FractionsRule14;
import org.warp.picalculator.math.rules.NumberRule1;
import org.warp.picalculator.math.rules.NumberRule2;
import org.warp.picalculator.math.rules.NumberRule6;
import org.warp.picalculator.math.rules.SyntaxRule1;
import org.warp.picalculator.math.rules.methods.MultiplicationMethod1;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@ -36,16 +35,13 @@ public class Multiplication extends FunctionOperator {
if (variable1 instanceof Number & variable2 instanceof Number) {
return true;
}
if (SyntaxRule1.compare(this)) {
return true;
}
if (NumberRule1.compare(this)) {
return true;
}
if (NumberRule2.compare(this)) {
return true;
}
if (NumberRule6.compare(this)) {
if (ExpandRule1.compare(this)) {
return true;
}
if (ExponentRule15.compare(this)) {
@ -66,14 +62,12 @@ public class Multiplication extends FunctionOperator {
@Override
public ObjectArrayList<Function> solve() throws Error {
ObjectArrayList<Function> result = new ObjectArrayList<>();
if (SyntaxRule1.compare(this)) {
result = SyntaxRule1.execute(this);
} else if (NumberRule1.compare(this)) {
if (NumberRule1.compare(this)) {
result = NumberRule1.execute(this);
} else if (NumberRule2.compare(this)) {
result = NumberRule2.execute(this);
} else if (NumberRule6.compare(this)) {
result = NumberRule6.execute(this);
} else if (ExpandRule1.compare(this)) {
result = ExpandRule1.execute(this);
} else if (ExponentRule15.compare(this)) {
result = ExponentRule15.execute(this);
} else if (ExponentRule16.compare(this)) {
@ -119,25 +113,33 @@ public class Multiplication extends FunctionOperator {
if (par1 instanceof Number && ((Number) par1).equals(new Number(context, -1))) {
result.add(new BlockChar(MathematicalSymbols.MINUS));
if (new Expression(context, par2).parenthesisNeeded()) {
BlockParenthesis par = new BlockParenthesis();
ObjectArrayList<Block> parBlocks = par2.toBlock(context);
for (Block b : parBlocks) {
par.getNumberContainer().appendBlockUnsafe(b); // Skips recomputeDimension
}
par.recomputeDimensions(); // Recompute dimensions after appendBlockUnsafe
BlockParenthesis par = new BlockParenthesis(parBlocks);
result.add(par);
} else {
result.addAll(par2.toBlock(context));
result.addAll(sub2);
}
return result;
} else {
result.addAll(sub1);
if (new Expression(context, par1).parenthesisNeeded()) {
ObjectArrayList<Block> parBlocks = par1.toBlock(context);
BlockParenthesis par = new BlockParenthesis(parBlocks);
result.add(par);
} else {
result.addAll(sub1);
}
if ((nearLeft instanceof BlockChar && nearRight instanceof BlockChar) && !(par2 instanceof Negative)) {
} else {
result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION));
}
result.addAll(sub2);
if (new Expression(context, par2).parenthesisNeeded()) {
ObjectArrayList<Block> parBlocks = par2.toBlock(context);
BlockParenthesis par = new BlockParenthesis(parBlocks);
result.add(par);
} else {
result.addAll(sub2);
}
return result;
}
}

View File

@ -13,7 +13,6 @@ import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.rules.NumberRule3;
import org.warp.picalculator.math.rules.NumberRule5;
import org.warp.picalculator.math.rules.NumberRule7;
import org.warp.picalculator.math.rules.SyntaxRule2;
import org.warp.picalculator.math.rules.VariableRule1;
import org.warp.picalculator.math.rules.VariableRule2;
import org.warp.picalculator.math.rules.VariableRule3;
@ -32,9 +31,6 @@ public class Sum extends FunctionOperator {
if (parameter1 instanceof Number & parameter2 instanceof Number) {
return true;
}
if (SyntaxRule2.compare(this)) {
return true;
}
if (VariableRule1.compare(this)) {
return true;
}
@ -65,9 +61,7 @@ public class Sum extends FunctionOperator {
throw new Error(Errors.SYNTAX_ERROR);
}
ObjectArrayList<Function> result = new ObjectArrayList<>();
if (SyntaxRule2.compare(this)) {
result = SyntaxRule2.execute(this);
} else if (VariableRule1.compare(this)) {
if (VariableRule1.compare(this)) {
result = VariableRule1.execute(this);
} else if (VariableRule2.compare(this)) {
result = VariableRule2.execute(this);

View File

@ -29,15 +29,15 @@ public class SumSubtraction extends FunctionOperator {
if (NumberRule3.compare(this)) {
return true;
}
if (NumberRule5.compare(this)) {
return true;
}
if (ExpandRule1.compare(this)) {
return true;
}
if (NumberRule4.compare(this)) {
return true;
}
if (NumberRule5.compare(this)) {
return true;
}
return false;
}
@ -49,12 +49,12 @@ public class SumSubtraction extends FunctionOperator {
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 (NumberRule5.compare(this)) {
result = NumberRule5.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"))));

View File

@ -28,6 +28,7 @@ import org.warp.picalculator.math.parser.steps.FixMultiplicationsAndDivisions;
import org.warp.picalculator.math.parser.steps.FixSingleFunctionArgs;
import org.warp.picalculator.math.parser.steps.FixSumsAndSubtractions;
import org.warp.picalculator.math.parser.steps.JoinNumberAndVariables;
import org.warp.picalculator.math.parser.steps.RemoveParentheses;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@ -77,7 +78,14 @@ public class MathParser {
private static ObjectArrayList<Function> fixStack(MathContext context, ObjectArrayList<Function> functionsList)
throws Error {
final MathParserStep[] steps = new MathParserStep[] { new JoinNumberAndVariables(context), new FixSingleFunctionArgs(), new FixMultiplicationsAndDivisions(), new FixSumsAndSubtractions(), new AddImplicitMultiplications(context), };
final MathParserStep[] steps = new MathParserStep[] {
new JoinNumberAndVariables(context),
new FixSingleFunctionArgs(),
new RemoveParentheses(context),
new FixMultiplicationsAndDivisions(),
new FixSumsAndSubtractions(),
new AddImplicitMultiplications(context),
};
boolean lastLoopDidSomething;
Function lastElement;

View File

@ -20,14 +20,14 @@ public class AddImplicitMultiplications implements MathParserStep {
@Override
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction,
ObjectArrayList<Function> functionsList) {
if (currentFunction instanceof FunctionSingle) {
if (currentFunction instanceof Function) {
if (lastFunction instanceof Function) {
functionsList.set(curIndex.i, new Multiplication(context, currentFunction, lastFunction));
functionsList.remove(curIndex.i + 1);
return true;
}
} else if (currentFunction instanceof Function) {
if (lastFunction instanceof FunctionSingle) {
if (lastFunction instanceof Function) {
functionsList.set(curIndex.i, new Multiplication(context, currentFunction, lastFunction));
functionsList.remove(curIndex.i + 1);
return true;
@ -43,7 +43,7 @@ public class AddImplicitMultiplications implements MathParserStep {
@Override
public String getStepName() {
return "Add implicit multiplications before and after Single Functions";
return "Add implicit multiplications before and after Functions";
}
}

View File

@ -20,8 +20,7 @@ public class JoinNumberAndVariables implements MathParserStep {
}
@Override
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction,
ObjectArrayList<Function> functionsList) {
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList<Function> functionsList) {
if (currentFunction instanceof Number | currentFunction instanceof Variable | currentFunction instanceof Division) {
if (lastFunction instanceof Variable | lastFunction instanceof Number | (lastFunction instanceof Multiplication && ((Multiplication) lastFunction).getParameter2() != null)) {
final Function a = currentFunction;

View File

@ -0,0 +1,42 @@
package org.warp.picalculator.math.parser.steps;
import org.warp.picalculator.IntegerObj;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.parser.MathParserStep;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class RemoveParentheses implements MathParserStep {
private MathContext context;
public RemoveParentheses(MathContext context) {
this.context = context;
}
@Override
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList<Function> functionsList) {
if (currentFunction instanceof Expression) {
if (((Expression)currentFunction).getParameter() == null) {
functionsList.remove(curIndex.i);
} else {
functionsList.set(curIndex.i, ((Expression)currentFunction).getParameter());
}
return true;
}
return false;
}
@Override
public boolean requiresReversedIteration() {
return false;
}
@Override
public String getStepName() {
return "Remove parentheses";
}
}

View File

@ -4,8 +4,8 @@ import org.warp.picalculator.Error;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.functions.Negative;
import org.warp.picalculator.math.functions.Multiplication;
import org.warp.picalculator.math.functions.Number;
import org.warp.picalculator.math.functions.Subtraction;
import org.warp.picalculator.math.functions.Sum;
import org.warp.picalculator.math.functions.SumSubtraction;
@ -23,29 +23,27 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class ExpandRule1 {
public static boolean compare(Function f) {
if (f instanceof Negative) {
final Negative fnc = (Negative) f;
if (fnc.getParameter() instanceof Expression) {
final Expression expr = (Expression) fnc.getParameter();
if (expr.getParameter() instanceof Sum) {
if (f instanceof Multiplication) {
final Multiplication fnc = (Multiplication) f;
if (fnc.getParameter1().equals(new Number(fnc.getMathContext(), -1))) {
final Function expr = fnc.getParameter2();
if (expr instanceof Sum) {
return true;
} else if (expr.getParameter() instanceof Subtraction) {
} else if (expr instanceof Subtraction) {
return true;
} else if (expr.getParameter() instanceof SumSubtraction) {
} else if (expr instanceof SumSubtraction) {
return true;
}
}
} else if (f instanceof Subtraction || f instanceof SumSubtraction) {
final FunctionOperator fnc = (FunctionOperator) f;
if (fnc.getParameter2() instanceof Expression) {
final Expression expr = (Expression) fnc.getParameter2();
if (expr.getParameter() instanceof Sum) {
return true;
} else if (expr.getParameter() instanceof Subtraction) {
return true;
} else if (expr.getParameter() instanceof SumSubtraction) {
return true;
}
final Function expr = fnc.getParameter2();
if (expr instanceof Sum) {
return true;
} else if (expr instanceof Subtraction) {
return true;
} else if (expr instanceof SumSubtraction) {
return true;
}
}
return false;
@ -55,13 +53,13 @@ public class ExpandRule1 {
final ObjectArrayList<Function> result = new ObjectArrayList<>();
final MathContext root = f.getMathContext();
Expression expr = null;
Function expr = null;
int fromSubtraction = 0;
FunctionOperator subtraction = null;
if (f instanceof Negative) {
expr = ((Expression) ((Negative) f).getParameter());
if (f instanceof Multiplication) {
expr = ((Multiplication) f).getParameter2();
} else if (f instanceof Subtraction || f instanceof SumSubtraction) {
expr = ((Expression) ((FunctionOperator) f).getParameter2());
expr = ((FunctionOperator) f).getParameter2();
if (f instanceof Subtraction) {
fromSubtraction = 1;
} else {
@ -73,11 +71,11 @@ public class ExpandRule1 {
}
final Function fnc = expr.getParameter();
final Function fnc = expr;
if (fnc instanceof Sum) {
final Function a = ((Sum) fnc).getParameter1();
final Function b = ((Sum) fnc).getParameter2();
final Subtraction fnc2 = new Subtraction(root, new Negative(root, a), b);
final Subtraction fnc2 = new Subtraction(root, new Multiplication(root, new Number(root, -1), a), b);
if (fromSubtraction > 0) {
subtraction = new Subtraction(root, ((FunctionOperator) f).getParameter1(), fnc2);
result.add(subtraction);
@ -87,7 +85,7 @@ public class ExpandRule1 {
} else if (fnc instanceof Subtraction) {
final Function a = ((Subtraction) fnc).getParameter1();
final Function b = ((Subtraction) fnc).getParameter2();
final Sum fnc2 = new Sum(root, new Negative(root, a), b);
final Sum fnc2 = new Sum(root, new Multiplication(root, new Number(root, -1), a), b);
if (fromSubtraction > 0) {
subtraction = new Subtraction(root, ((FunctionOperator) f).getParameter1(), fnc2);
result.add(subtraction);
@ -97,8 +95,8 @@ public class ExpandRule1 {
} else if (fnc instanceof SumSubtraction) {
final Function a = ((SumSubtraction) fnc).getParameter1();
final Function b = ((SumSubtraction) fnc).getParameter2();
final Sum fnc2 = new Sum(root, new Negative(root, a), b);
final Subtraction fnc3 = new Subtraction(root, new Negative(root, a), b);
final Sum fnc2 = new Sum(root, new Multiplication(root, new Number(root, -1), a), b);
final Subtraction fnc3 = new Subtraction(root, new Multiplication(root, new Number(root, -1), a), b);
if (fromSubtraction > 0) {
subtraction = new SumSubtraction(root, ((FunctionOperator) f).getParameter1(), fnc2);
result.add(subtraction);

View File

@ -39,9 +39,9 @@ public class ExponentRule16 {
if (fnc.getParameter1() instanceof Power && fnc.getParameter2() instanceof Power) {
result.add(new Power(root, ((Power) fnc.getParameter1()).getParameter1(), new Sum(root, new Expression(root, ((Power) fnc.getParameter1()).getParameter2()), new Expression(root, ((Power) fnc.getParameter2()).getParameter2()))));
} else if (fnc.getParameter1() instanceof Power) {
result.add(new Power(root, ((Power) fnc.getParameter1()).getParameter1(), new Sum(root, new Expression(root, ((Power) fnc.getParameter1()).getParameter2()), new Number(root, 1))));
result.add(new Power(root, fnc.getParameter2(), new Sum(root, new Expression(root, ((Power) fnc.getParameter1()).getParameter2()), new Number(root, 1))));
} else if (fnc.getParameter2() instanceof Power) {
result.add(new Power(root, ((Power) fnc.getParameter1()).getParameter1(), new Sum(root, new Number(root, 1), new Expression(root, ((Power) fnc.getParameter2()).getParameter2()))));
result.add(new Power(root, fnc.getParameter1(), new Sum(root, new Number(root, 1), new Expression(root, ((Power) fnc.getParameter2()).getParameter2()))));
}
return result;
}

View File

@ -50,7 +50,7 @@ public class NumberRule3 {
final MathContext root = f.getMathContext();
final ObjectArrayList<Function> result = new ObjectArrayList<>();
if (f instanceof SumSubtraction) {
final Multiplication mul = new Multiplication(root, new Number(root, 2), f);
final Multiplication mul = new Multiplication(root, new Number(root, 2), ((SumSubtraction) f).getParameter1());
result.add(mul);
}
result.add(new Number(root, 0));

View File

@ -1,66 +0,0 @@
package org.warp.picalculator.math.rules;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.functions.Multiplication;
import org.warp.picalculator.math.functions.Negative;
import org.warp.picalculator.math.functions.Number;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
/**
* Number rule<br>
* <b>a * -1 = -a</b>
*
* @author Andrea Cavalli
*
*/
public class NumberRule6 {
public static boolean compare(Function f) {
final MathContext root = f.getMathContext();
final Multiplication mult = (Multiplication) f;
if (mult.getParameter1() instanceof Number) {
final Number numb = (Number) mult.getParameter1();
if (numb.equals(new Number(root, -1))) {
return true;
}
}
if (mult.getParameter2() instanceof Number) {
final Number numb = (Number) mult.getParameter2();
if (numb.equals(new Number(root, -1))) {
return true;
}
}
return false;
}
public static ObjectArrayList<Function> execute(Function f) throws Error {
final MathContext root = f.getMathContext();
final ObjectArrayList<Function> result = new ObjectArrayList<>();
Function a = null;
boolean aFound = false;
final Multiplication mult = (Multiplication) f;
if (aFound == false & mult.getParameter1() instanceof Number) {
final Number numb = (Number) mult.getParameter1();
if (numb.equals(new Number(root, -1))) {
a = mult.getParameter2();
aFound = true;
}
}
if (aFound == false && mult.getParameter2() instanceof Number) {
final Number numb = (Number) mult.getParameter2();
if (numb.equals(new Number(root, -1))) {
a = mult.getParameter1();
aFound = true;
}
}
final Negative minus = new Negative(root, a);
result.add(minus);
return result;
}
}

View File

@ -19,6 +19,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class NumberRule7 {
public static boolean compare(Sum f) {
System.out.println(f);
return f.getParameter1().equals(f.getParameter2());
}

View File

@ -1,50 +0,0 @@
package org.warp.picalculator.math.rules;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.functions.Multiplication;
import org.warp.picalculator.math.functions.Sum;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
/**
* Syntax rule<br>
* <b>(a*b)*c=a*(b*c)</b>
*
* @author Andrea Cavalli
*
*/
public class SyntaxRule1 {
public static boolean compare(Function f) {
final FunctionOperator m = (FunctionOperator) f;
if (m instanceof Multiplication & m.getParameter1() instanceof Multiplication) {
return true;
} else if (m instanceof Sum & m.getParameter1() instanceof Sum) {
return true;
}
return false;
}
public static ObjectArrayList<Function> execute(Function f) throws Error {
final MathContext root = f.getMathContext();
final ObjectArrayList<Function> result = new ObjectArrayList<>();
FunctionOperator mOut = (FunctionOperator) f;
final Function a = ((FunctionOperator) mOut.getParameter1()).getParameter1();
final Function b = ((FunctionOperator) mOut.getParameter1()).getParameter2();
final Function c = mOut.getParameter2();
FunctionOperator mIn;
if (f instanceof Multiplication) {
mIn = new Multiplication(root, b, c);
} else {
mIn = new Sum(root, b, c);
}
mOut = mOut.setParameter1(a);
mOut = mOut.setParameter2(mIn);
result.add(mOut);
return result;
}
}

View File

@ -1,52 +0,0 @@
package org.warp.picalculator.math.rules;
import org.warp.picalculator.Error;
import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.functions.Sum;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
/**
* Syntax rule<br>
* <b>a+(b+c)=(a+b)+c</b>
*
* @author Andrea Cavalli
*
*/
public class SyntaxRule2 {
public static boolean compare(Sum f) {
if (f.getParameter2() instanceof Sum) {
return true;
}
if (f.getParameter2() instanceof Expression) {
final Expression e = (Expression) f.getParameter2();
if (e.getParameter() instanceof Sum) {
return true;
}
}
return false;
}
public static ObjectArrayList<Function> execute(Sum f) throws Error {
final MathContext root = f.getMathContext();
final ObjectArrayList<Function> result = new ObjectArrayList<>();
final Function a = f.getParameter1();
Function b, c;
if (f.getParameter2() instanceof Sum) {
b = ((Sum) f.getParameter2()).getParameter1();
c = ((Sum) f.getParameter2()).getParameter2();
} else {
b = ((Sum) ((Expression) f.getParameter2()).getParameter()).getParameter1();
c = ((Sum) ((Expression) f.getParameter2()).getParameter()).getParameter2();
}
final Sum mIn = new Sum(root, a, b);
f.setParameter1(mIn);
f.setParameter2(c);
result.add(f);
return result;
}
}