diff --git a/.classpath b/.classpath index e2cbd638..7f11a3cd 100644 --- a/.classpath +++ b/.classpath @@ -1,17 +1,6 @@ - - - - - - - - - - - - + @@ -19,6 +8,7 @@ + @@ -28,5 +18,17 @@ + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore index dc7674c0..5a49e12b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,18 +4,25 @@ .mtj.tmp/ # Package Files # -*.jar +!/target/*.jar *.war +*.jar *.ear -Thumbs.db -font_easter.png -font_easter.rft -font_fu32.rft +*Thumbs.db +font_gputest1.rft +font_gputest12.rft +font_gputest2.rft +font_gputest3.png +font_gputest4.png +font_gputest4.xcf +manager2/ +VBO_Example.java /target/ +!/target/*.jar /backups/ /Resources_and_Videos/ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* -/bin/ +/bin/ \ No newline at end of file diff --git a/.project b/.project index fe92fe4f..1a550173 100644 --- a/.project +++ b/.project @@ -17,13 +17,13 @@ - org.eclipse.m2e.core.maven2Builder + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, + org.eclipse.m2e.core.maven2Builder diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index b6a3c7a1..ca06868c 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,4 +1,8 @@ eclipse.preferences.version=1 +encoding//src/jar-specific/java=UTF-8 +encoding//src/js-specific/java=UTF-8 +encoding//src/main/java=UTF-8 encoding//src/main/java/org/warp/picalculator/gui/expression/blocks/BlockParenthesis.java=UTF-8 encoding//src/main/java/org/warp/picalculator/math/MathematicalSymbols.java=UTF-8 -encoding/=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 02433e90..96cf561c 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,14 +1,6 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs index 14b697b7..c679d9b2 100644 --- a/.settings/org.eclipse.m2e.core.prefs +++ b/.settings/org.eclipse.m2e.core.prefs @@ -1,4 +1,4 @@ -activeProfiles= +activeProfiles=jarprofile eclipse.preferences.version=1 resolveWorkspaceProjects=true version=1 diff --git a/Algebra Cheat Sheet.rtf b/Algebra Cheat Sheet.rtf index c8989cd1..ecc15e26 100644 Binary files a/Algebra Cheat Sheet.rtf and b/Algebra Cheat Sheet.rtf differ diff --git a/README.md b/README.md index 8cd15ef4..8ae0bcdc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # WarpPI Calculator -Step-by-step algebraic calculator for Raspberry PI. +Step-by-step algebra calculator for Raspberry PI. **This project is experimental and strictly related to my calculator, designed to run on an embedded hardware. It works but many fundamental features aren't complete.**
diff --git a/libs/raspi2fb b/libs/raspi2fb new file mode 100644 index 00000000..fe7e2345 Binary files /dev/null and b/libs/raspi2fb differ diff --git a/math-rules-cache.zip b/math-rules-cache.zip new file mode 100644 index 00000000..c242a2f9 Binary files /dev/null and b/math-rules-cache.zip differ diff --git a/pom.xml b/pom.xml index 905b1d43..765b460d 100755 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,5 @@ - 4.0.0 org.warp.picalculator @@ -7,7 +8,16 @@ 1.0-SNAPSHOT WarpPI Calculator http://warp.ovh + + 1.8 + 1.8 + src/main/java + + + teavm-dev + https://dl.bintray.com/konsoletyper/teavm + oss-snapshots-repo Sonatype OSS Maven Repository @@ -18,51 +28,171 @@ + + + jarprofile + + jar-specific + + + true + + + + org.jogamp.jogl + jogl-all-main + 2.3.2 + + + org.jogamp.gluegen + gluegen-rt-main + 2.3.2 + + + com.pi4j + pi4j-core + 1.2-SNAPSHOT + + + org.fusesource.jansi + jansi + 1.15 + + + net.lingala.zip4j + zip4j + 1.3.2 + + + org.eclipse.jdt.core.compiler + ecj + 4.6.1 + + + ar.com.hjg + pngj + 2.1.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.8 + 1.8 + UTF-8 + + + + + + + jsprofile + + js-specific + + + false + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + + org/warp/picalculator/gui/graphicengine/cpu/* + org/warp/picalculator/gui/graphicengine/gpu/* + org/warp/picalculator/gui/graphicengine/headless24bit/* + org/warp/picalculator/gui/graphicengine/headless256/* + org/warp/picalculator/gui/graphicengine/headless8/* + org/warp/picalculator/gui/graphicengine/framebuffer/* + + 1.8 + 1.8 + UTF-8 + + + + org.teavm + teavm-maven-plugin + 0.5.1 + + + + org.teavm + teavm-classlib + 0.5.1 + + + + + + compile + + process-classes + + org.warp.picalculator.Main + true + true + true + + + + + + + + + + - - junit - junit - 4.12 - test - + it.unimi.dsi fastutil 7.2.0 - org.jogamp.jogl - jogl-all-main - 2.3.2 - - - org.jogamp.gluegen - gluegen-rt-main - 2.3.2 - - - com.pi4j - pi4j-core - 1.2-SNAPSHOT - - - org.fusesource.jansi - jansi - 1.15 - - - ar.com.hjg - pngj - 2.1.0 + com.google.code.gson + gson + 2.8.2 - - 1.8 - 1.8 - WarpPICalculator + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + add-source + generate-sources + + add-source + + + + + ${basedir}/src/main/java + + + ${basedir}/src/${src.dir}/java + + + + + + @@ -75,14 +205,12 @@ - org.apache.maven.plugins - maven-compiler-plugin - 2.3.2 + maven-resources-plugin + 3.0.2 - 1.8 - 1.8 + UTF-8 @@ -115,7 +243,6 @@ - " + w + " * " + h); - - File f = Files.createTempFile("texture-font-", ".png").toFile(); + System.out.println(((int) Math.ceil(Math.sqrt(totalChars) * charW)) + " * " + ((int) Math.ceil(Math.sqrt(totalChars) * charH)) + " --> " + w + " * " + h); + + final File f = Files.createTempFile("texture-font-", ".png").toFile(); + f.deleteOnExit(); final FileOutputStream outputStream = new FileOutputStream(f); final ImageInfo imi = new ImageInfo(w, h, 8, true); // 8 bits per channel, alpha // open image for writing to a output stream final PngWriter png = new PngWriter(outputStream, imi); for (int y = 0; y < png.imgInfo.rows; y++) { - ImageLineInt iline = new ImageLineInt(imi); - int[] xValues = new int[imi.cols]; + final ImageLineInt iline = new ImageLineInt(imi); + final int[] xValues = new int[imi.cols]; for (int indexX = 0; indexX <= maxIndexW; indexX++) {// this line will be written to all rows final int charY = (y % charH); - final int indexY = (y - charY)/charH; - final int i = indexY * (maxIndexW+1) + indexX - this.minCharIndex; + final int indexY = (y - charY) / charH; + final int i = indexY * (maxIndexW + 1) + indexX - minCharIndex; boolean[] currentChar; - if (i < totalChars && (currentChar=chars[i]) != null) { + if (i < totalChars && (currentChar = chars[i]) != null) { for (int charX = 0; charX < charW; charX++) { if (i >= 0 & i < totalChars && currentChar != null && currentChar[charX + charY * charW]) { xValues[indexX * charW + charX] = 0xFFFFFFFF; @@ -172,7 +163,7 @@ public class GPUFont implements BinaryFont { chars = null; png.end(); Utils.gc(); - + try { memoryWidth = w; memoryHeight = h; @@ -182,7 +173,7 @@ public class GPUFont implements BinaryFont { outputStream.flush(); outputStream.close(); Utils.gc(); - this.tmpFont = f; + tmpFont = f; } catch (GLException | IOException e) { e.printStackTrace(); } @@ -198,7 +189,7 @@ public class GPUFont implements BinaryFont { } private int powerOf2(int i) { - return i >1 ? Integer.highestOneBit(i-1)<<1 : 1; + return i > 1 ? Integer.highestOneBit(i - 1) << 1 : 1; } @Override @@ -242,4 +233,14 @@ public class GPUFont implements BinaryFont { public boolean isInitialized() { return initialized; } + + @Override + public int getSkinWidth() { + return memoryWidth; + } + + @Override + public int getSkinHeight() { + return memoryHeight; + } } \ No newline at end of file diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPURenderer.java b/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPURenderer.java index c79096b8..546d4fd0 100755 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPURenderer.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPURenderer.java @@ -1,17 +1,12 @@ package org.warp.picalculator.gui.graphicengine.gpu; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.Buffer; import java.nio.FloatBuffer; import java.nio.file.Files; -import java.nio.file.Paths; - import javax.imageio.ImageIO; import org.warp.picalculator.StaticVars; @@ -31,13 +26,17 @@ public class GPURenderer implements Renderer { public static GL2ES1 gl; - private static final int ELEMENT_VERTICES_COUNT = 6; private static final int ELEMENTS_MAX_COUNT_PER_BUFFER = StaticVars.enableVBO ? 128 : 1; + private static final int ELEMENT_VERTICES_COUNT = 6, vertSize = 3, texSize = 2, colSize = 4, vertBuffer = 0, + texBuffer = 1, colBuffer = 2, vertMax = vertSize * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER, + texMax = texSize * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER, + colMax = colSize * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER; + private int[] handlers; private final DeallocationHelper deallocationHelper = new DeallocationHelper(); FloatBuffer fbVertices; - FloatBuffer txVertices; - FloatBuffer colVertices; + FloatBuffer fbTextures; + FloatBuffer fbColors; int fbElements; float[] currentColor = new float[24]; @@ -156,8 +155,8 @@ public class GPURenderer implements Renderer { final float[] tex_vertices = { uvX, uvY, uvX + uvWidth, uvY, uvX, uvY + uvHeight, uvX, uvY + uvHeight, uvX + uvWidth, uvY, uvX + uvWidth, uvY + uvHeight }; fbElements++; fbVertices.put(vertices); - txVertices.put(tex_vertices); - colVertices.put(currentColor); + fbTextures.put(tex_vertices); + fbColors.put(currentColor); } @Override @@ -182,8 +181,8 @@ public class GPURenderer implements Renderer { final float[] tex_vertices = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, }; fbElements++; fbVertices.put(vertices); - txVertices.put(tex_vertices); - colVertices.put(currentColor); + fbTextures.put(tex_vertices); + fbColors.put(currentColor); } @Override @@ -249,23 +248,24 @@ public class GPURenderer implements Renderer { File f; if (isResource) { f = Files.createTempFile("texture-", ".png").toFile(); + f.deleteOnExit(); ImageIO.write(img, "png", f); } else { f = new File(file); } - int imgW = img.getWidth(); - int imgH = img.getHeight(); + final int imgW = img.getWidth(); + final int imgH = img.getHeight(); img = null; Utils.gc(); return new OpenedTextureData(imgW, imgH, f, isResource); } - + public static class OpenedTextureData { public final int w; public final int h; public final File f; public final boolean deleteOnExit; - + /** * @param w * @param h @@ -278,16 +278,18 @@ public class GPURenderer implements Renderer { this.f = f; this.deleteOnExit = deleteOnExit; } - + } static Texture importTexture(File f, boolean deleteOnExit) throws GLException, IOException { final Texture tex = TextureIO.newTexture(f, false); if (deleteOnExit && f.exists()) { try { - if (StaticVars.debugOn) throw new IOException("Delete on exit!"); + if (StaticVars.debugOn) { + throw new IOException("Delete on exit!"); + } f.delete(); - }catch (Exception ex) { + } catch (final Exception ex) { f.deleteOnExit(); } } @@ -297,13 +299,49 @@ public class GPURenderer implements Renderer { return tex; } - public void startDrawCycle(boolean first) { + public void initDrawCycle() { + final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex; if (fbVertices == null) { - fbVertices = Buffers.newDirectFloatBuffer(3 * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER); - txVertices = Buffers.newDirectFloatBuffer(2 * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER); - colVertices = Buffers.newDirectFloatBuffer(4 * ELEMENT_VERTICES_COUNT * ELEMENTS_MAX_COUNT_PER_BUFFER); + fbVertices = Buffers.newDirectFloatBuffer(vertMax); + fbTextures = Buffers.newDirectFloatBuffer(texMax); + fbColors = Buffers.newDirectFloatBuffer(colMax); + handlers = new int[3]; + gl.glGenBuffers(3, handlers, 0); } - if (first || fbVertices == null || cycleEnded) { + startDrawSegment(false); + if (textureChange) { + changeTexture(); + } + } + + public void endDrawCycle() { + final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex; + if (textureChange) { + if (fbElements > 0) { + endDrawSegment(); + } + changeTexture(); + } else { + if (fbElements > 0) { + endDrawSegment(); + } + } + } + + private void changeTexture() { + precTexEnabled = currentTexEnabled; + precTex = currentTex; + if (currentTexEnabled) { + gl.glEnable(GL.GL_TEXTURE_2D); + currentTex.bind(gl); + } else { + gl.glDisable(GL.GL_TEXTURE_2D); + } + firstBufferTexDataCall = true; + } + + public void startDrawSegment(boolean continuation) { + if (!continuation || cycleEnded) { fbElements = 0; } cycleEnded = false; @@ -313,58 +351,63 @@ public class GPURenderer implements Renderer { private Texture precTex; private boolean cycleEnded = true; - public void updateDrawCycle() { - updateDrawCycle(false, false); - } - - public void updateDrawCycle(boolean first, boolean last) { + public void doDrawSegment() { final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex; - final boolean changeRequired = last || fbElements >= ELEMENTS_MAX_COUNT_PER_BUFFER; - if (first) { - startDrawCycle(true); - } + final boolean changeRequired = fbElements >= ELEMENTS_MAX_COUNT_PER_BUFFER; if (textureChange) { - if (!first && fbElements > 0) { - endDrawCycle(); - if (!last) { - startDrawCycle(true); - } + if (fbElements > 0) { + endDrawSegment(); + startDrawSegment(false); } - precTexEnabled = currentTexEnabled; - precTex = currentTex; - if (currentTexEnabled) { - gl.glEnable(GL.GL_TEXTURE_2D); - currentTex.bind(gl); - } else { - gl.glDisable(GL.GL_TEXTURE_2D); - } - } else if (!first) { + changeTexture(); + } else { if (fbElements > 0 && changeRequired) { - endDrawCycle(); - if (!last) { - startDrawCycle(false); - } + endDrawSegment(); + startDrawSegment(true); } } } - public void endDrawCycle() { - fbVertices.limit(fbVertices.position()); - txVertices.limit(txVertices.position()); - colVertices.limit(colVertices.position()); - fbVertices.rewind(); - txVertices.rewind(); - colVertices.rewind(); + boolean firstBufferDataCall = true; + boolean firstBufferTexDataCall = true; - gl.glVertexPointer(3, GL.GL_FLOAT, 0, fbVertices); - gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, txVertices); - gl.glColorPointer(4, GL.GL_FLOAT, 0, colVertices); - fbVertices.limit(fbVertices.capacity()); - txVertices.limit(txVertices.capacity()); - colVertices.limit(colVertices.capacity()); + public void endDrawSegment() { + fbVertices.flip(); + fbTextures.flip(); + fbColors.flip(); +// gl.glVertexPointer(vertSize, GL.GL_FLOAT, 0, fbVertices); + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[vertBuffer]); + if (firstBufferTexDataCall) { + gl.glBufferData(GL.GL_ARRAY_BUFFER, fbVertices.limit() * Buffers.SIZEOF_FLOAT, fbVertices, GL.GL_STATIC_DRAW); + } else { + gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbVertices.limit() * Buffers.SIZEOF_FLOAT, fbVertices); + } + gl.glVertexPointer(vertSize, GL.GL_FLOAT, 0, 0l); +// gl.glTexCoordPointer(texSize, GL.GL_FLOAT, 0, fbTextures); + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[texBuffer]); + if (firstBufferTexDataCall) { + gl.glBufferData(GL.GL_ARRAY_BUFFER, fbTextures.limit() * Buffers.SIZEOF_FLOAT, fbTextures, GL.GL_STATIC_DRAW); + } else { + gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbTextures.limit() * Buffers.SIZEOF_FLOAT, fbTextures); + } + gl.glTexCoordPointer(texSize, GL.GL_FLOAT, 0, 0l); +// gl.glColorPointer(colSize, GL.GL_FLOAT, 0, fbColors); + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[colBuffer]); + if (firstBufferTexDataCall) { + gl.glBufferData(GL.GL_ARRAY_BUFFER, fbColors.limit() * Buffers.SIZEOF_FLOAT, fbColors, GL.GL_STATIC_DRAW); + } else { + gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbColors.limit() * Buffers.SIZEOF_FLOAT, fbColors); + } + gl.glColorPointer(colSize, GL.GL_FLOAT, 0, 0l); + + fbVertices.limit(vertMax); + fbTextures.limit(texMax); + fbColors.limit(colMax); gl.glDrawArrays(GL.GL_TRIANGLES, 0, fbElements * ELEMENT_VERTICES_COUNT); //gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, fbElements * ELEMENT_VERTICES_COUNT); + firstBufferDataCall = false; + firstBufferTexDataCall = false; cycleEnded = true; // deleteBuffer(fbVertices); @@ -385,18 +428,18 @@ public class GPURenderer implements Renderer { public void glClearSkin() { if (currentTex != null) { currentTex = null; - updateDrawCycle(); + doDrawSegment(); } } void disableTexture() { currentTexEnabled = false; - updateDrawCycle(); + doDrawSegment(); } void enableTexture() { currentTexEnabled = true; - updateDrawCycle(); + doDrawSegment(); } void useTexture(Texture t, float w, float h) { @@ -405,4 +448,4 @@ public class GPURenderer implements Renderer { currentTexHeight = h; enableTexture(); } -} +} \ No newline at end of file diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPUSkin.java b/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPUSkin.java index 30d1dac3..d5575110 100755 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPUSkin.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPUSkin.java @@ -1,7 +1,5 @@ package org.warp.picalculator.gui.graphicengine.gpu; -import java.awt.image.BufferedImage; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; @@ -10,7 +8,6 @@ import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.Skin; import org.warp.picalculator.gui.graphicengine.gpu.GPURenderer.OpenedTextureData; -import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES1; import com.jogamp.opengl.GLException; import com.jogamp.opengl.util.texture.Texture; @@ -24,14 +21,14 @@ public class GPUSkin implements Skin { private String texturePath; private boolean initialized = false; private boolean isResource; - + GPUSkin(GraphicEngine d, String file) throws IOException { load(file); } @Override public void load(String file) throws IOException { - boolean isResource = !Files.exists(Paths.get(file)); + final boolean isResource = !Files.exists(Paths.get(file)); if (isResource && (this.getClass().getClassLoader().getResource(file)) == null) { throw new IOException("File '" + file + "' not found!"); } @@ -47,7 +44,7 @@ public class GPUSkin implements Skin { t = GPURenderer.importTexture(i.f, i.deleteOnExit); w = i.w; h = i.h; - t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + ((GPUEngine) d).registerTexture(t); initialized = true; } catch (GLException | IOException e) { e.printStackTrace(); @@ -69,4 +66,14 @@ public class GPUSkin implements Skin { return initialized; } + @Override + public int getSkinWidth() { + return w; + } + + @Override + public int getSkinHeight() { + return h; + } + } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java b/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java index 9aebc0b5..e065827b 100755 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/NEWTWindow.java @@ -29,8 +29,8 @@ package org.warp.picalculator.gui.graphicengine.gpu; import org.warp.picalculator.StaticVars; +import org.warp.picalculator.device.Key; import org.warp.picalculator.device.Keyboard; -import org.warp.picalculator.device.Keyboard.Key; import org.warp.picalculator.gui.DisplayManager; import com.jogamp.newt.event.KeyEvent; @@ -49,22 +49,26 @@ import com.jogamp.opengl.fixedfunc.GLLightingFunc; import com.jogamp.opengl.fixedfunc.GLMatrixFunc; import com.jogamp.opengl.fixedfunc.GLPointerFunc; import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.texture.Texture; /** * * @author Xerxes Rånby (xranby) - * @author Andrea Cavalli (XDRake99) + * @author Andrea Cavalli (@Cavallium) */ class NEWTWindow implements GLEventListener { private final GPUEngine disp; private final GPURenderer renderer; + public float windowZoom; + public int[] realWindowSize; public Runnable onInitialized; public NEWTWindow(GPUEngine disp) { this.disp = disp; renderer = disp.getRenderer(); + realWindowSize = new int[] { 1, 1 }; } public GLWindow window; @@ -82,12 +86,14 @@ class NEWTWindow implements GLEventListener { final GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2ES1)); System.out.println("Loaded OpenGL"); // We may at this point tweak the caps and request a translucent drawable + caps.setHardwareAccelerated(true); caps.setBackgroundOpaque(true); //transparency window - caps.setSampleBuffers(false); +// caps.setSampleBuffers(true); +// caps.setNumSamples(4); final GLWindow glWindow = GLWindow.create(caps); window = glWindow; - glWindow.setTitle("WarpPI Calculator by Andrea Cavalli (XDrake99)"); + glWindow.setTitle("WarpPI Calculator by Andrea Cavalli (@Cavallium)"); glWindow.addWindowListener(new WindowListener() { @@ -142,7 +148,7 @@ class NEWTWindow implements GLEventListener { public void keyReleased(KeyEvent arg0) { switch (arg0.getKeyCode()) { case KeyEvent.VK_ESCAPE: - Keyboard.keyReleased(Key.POWER); + Keyboard.keyReleased(Key.POWEROFF); break; case KeyEvent.VK_D: Keyboard.keyReleased(Key.debug_DEG); @@ -173,7 +179,7 @@ class NEWTWindow implements GLEventListener { } else if (!Keyboard.shift && !Keyboard.alpha) { Keyboard.keyReleased(Key.BRIGHTNESS_CYCLE); } else { - Keyboard.keyReleased(Key.NONE); + Keyboard.keyReleased(Key.ZOOM_MODE); } break; case KeyEvent.VK_ENTER: @@ -283,8 +289,13 @@ class NEWTWindow implements GLEventListener { public void init(GLAutoDrawable drawable) { final GL2ES1 gl = drawable.getGL().getGL2ES1(); - //Vsync - gl.setSwapInterval(2); + if (StaticVars.debugOn) { + //Vsync + gl.setSwapInterval(1); + } else { + //Vsync + gl.setSwapInterval(2); + } //Textures gl.glEnable(GL.GL_TEXTURE_2D); @@ -294,6 +305,9 @@ class NEWTWindow implements GLEventListener { gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); gl.glShadeModel(GLLightingFunc.GL_FLAT); + //Multisampling + //gl.glEnable(GL.GL_MULTISAMPLE); + if (onInitialized != null) { onInitialized.run(); onInitialized = null; @@ -313,22 +327,40 @@ class NEWTWindow implements GLEventListener { @Override public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) { - disp.size[0] = (StaticVars.debugOn & StaticVars.debugWindow2x) ? width / 2 : width; - disp.size[1] = (StaticVars.debugOn & StaticVars.debugWindow2x) ? height / 2 : height; + realWindowSize[0] = width; + realWindowSize[1] = height; + disp.size[0] = width; + disp.size[1] = height; final GL2ES1 gl = glad.getGL().getGL2ES1(); - if (width == 0) { - width = 1; - } - if (height == 0) { - height = 1; + + onZoomChanged(gl, true); + } + + private void onZoomChanged(GL2ES1 gl, boolean sizeChanged) { + final float precWindowZoom = windowZoom; + windowZoom = StaticVars.getCurrentZoomValue(); + + if (((precWindowZoom % ((int) precWindowZoom)) != 0f) != ((windowZoom % ((int) windowZoom)) != 0f)) { + final boolean linear = (windowZoom % ((int) windowZoom)) != 0f; + + for (final Texture t : disp.registeredTextures) { + t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, linear ? GL.GL_LINEAR : GL.GL_NEAREST); + t.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); + } } + final int width = realWindowSize[0]; + final int height = realWindowSize[1]; + + disp.size[0] = (int) (realWindowSize[0] / windowZoom); + disp.size[1] = (int) (realWindowSize[1] / windowZoom); + gl.glViewport(0, 0, width, height); gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); gl.glLoadIdentity(); - gl.glOrtho(0.0, (StaticVars.debugOn & StaticVars.debugWindow2x) ? width / 2 : width, (StaticVars.debugOn & StaticVars.debugWindow2x) ? height / 2 : height, 0.0, -1, 1); + gl.glOrtho(0.0, disp.size[0], disp.size[1], 0.0, -1, 1); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); gl.glLoadIdentity(); @@ -339,16 +371,31 @@ class NEWTWindow implements GLEventListener { final GL2ES1 gl = glad.getGL().getGL2ES1(); GPURenderer.gl = gl; - + + if (windowZoom != StaticVars.getCurrentZoomValue()) { + onZoomChanged(gl, false); + } + + Boolean linear = null; + while (!disp.unregisteredTextures.isEmpty()) { + if (linear == null) { + linear = (windowZoom % ((int) windowZoom)) != 0f; + } + final Texture t = disp.unregisteredTextures.pop(); + t.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + t.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); + disp.registeredTextures.addLast(t); + } + gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY); gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY); gl.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY); - - renderer.updateDrawCycle(true, false); + + renderer.initDrawCycle(); disp.repaint(); - renderer.updateDrawCycle(false, true); + renderer.endDrawCycle(); GPURenderer.gl = null; diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitEngine.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitEngine.java index 52f362eb..489fa0ea 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitEngine.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitEngine.java @@ -7,14 +7,14 @@ import org.fusesource.jansi.AnsiConsole; import org.fusesource.jansi.internal.WindowsSupport; import org.warp.picalculator.StaticVars; import org.warp.picalculator.Utils; +import org.warp.picalculator.device.Key; import org.warp.picalculator.device.Keyboard; -import org.warp.picalculator.device.Keyboard.Key; import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.RenderingLoop; public class Headless24bitEngine implements org.warp.picalculator.gui.graphicengine.GraphicEngine { - private Headless24bitRenderer r = new Headless24bitRenderer(); + private final Headless24bitRenderer r = new Headless24bitRenderer(); private boolean stopped = true; private RenderingLoop renderLoop; public static final int C_MUL_X = 4;//8; @@ -67,7 +67,7 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng if (Utils.isWindows() && !Utils.msDosMode) { win = true; WindowsSupport.setConsoleMode(0x0200); - Thread t = new Thread(() -> { + final Thread t = new Thread(() -> { int ch = -1; while (true) { if (precKey != null) { @@ -132,8 +132,9 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng t.start(); } stopped = false; - if (onInitialized != null) + if (onInitialized != null) { onInitialized.run(); + } } @Override @@ -158,7 +159,7 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng @Override public void start(RenderingLoop d) { - this.renderLoop = d; + renderLoop = d; final Thread th = new Thread(() -> { try { double extratime = 0; @@ -215,10 +216,10 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng } } int[] newpix = new int[3]; - for (int i = 0; i < pixs.length; i++) { - newpix[0] += pixs[i][0]; - newpix[1] += pixs[i][1]; - newpix[2] += pixs[i][2]; + for (final int[] pix : pixs) { + newpix[0] += pix[0]; + newpix[1] += pix[1]; + newpix[2] += pix[2]; } newpix[0] /= pixs.length; newpix[1] /= pixs.length; @@ -233,10 +234,10 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng } } newpix = new int[3]; - for (int i = 0; i < pixs.length; i++) { - newpix[0] += pixs[i][0]; - newpix[1] += pixs[i][1]; - newpix[2] += pixs[i][2]; + for (final int[] pix : pixs) { + newpix[0] += pix[0]; + newpix[1] += pix[1]; + newpix[2] += pix[2]; } newpix[0] /= pixs.length; newpix[1] /= pixs.length; @@ -318,8 +319,9 @@ public class Headless24bitEngine implements org.warp.picalculator.gui.graphiceng @Override public boolean isSupported() { - if (Utils.msDosMode || (Utils.forceEngine != null && Utils.forceEngine != "console-24bit")) + if (Utils.msDosMode || (Utils.forceEngine != null && Utils.forceEngine != "console-24bit")) { return false; + } return true; } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitFont.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitFont.java index 856cae0e..3ac0587e 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitFont.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitFont.java @@ -44,4 +44,14 @@ public class Headless24bitFont implements BinaryFont { return true; } + @Override + public int getSkinWidth() { + return 0; + } + + @Override + public int getSkinHeight() { + return 0; + } + } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitRenderer.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitRenderer.java index 83cdcf76..b00e1fe7 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitRenderer.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitRenderer.java @@ -82,11 +82,11 @@ public class Headless24bitRenderer implements Renderer { @Override public void glDrawLine(float x1, float y1, float x2, float y2) { - int dx = (int) Math.abs(x2 - x1); - int dy = (int) Math.abs(y2 - y1); + final int dx = (int) Math.abs(x2 - x1); + final int dy = (int) Math.abs(y2 - y1); - int sx = (x1 < x2) ? 1 : -1; - int sy = (y1 < y2) ? 1 : -1; + final int sx = (x1 < x2) ? 1 : -1; + final int sy = (y1 < y2) ? 1 : -1; int err = dx - dy; @@ -101,7 +101,7 @@ public class Headless24bitRenderer implements Renderer { break; } - int e2 = 2 * err; + final int e2 = 2 * err; if (e2 > -dy) { err = err - dy; @@ -185,7 +185,7 @@ public class Headless24bitRenderer implements Renderer { final int cx = (int) x; final int cy = (int) y; int i = 0; - for (char c : text.toCharArray()) { + for (final char c : text.toCharArray()) { if (cx + i >= size[0] || cy >= size[1]) { break; } @@ -200,7 +200,7 @@ public class Headless24bitRenderer implements Renderer { final int cx = ((int) x) - (text.length() / 2) * Headless24bitEngine.C_MUL_X; final int cy = ((int) y); int i = 0; - for (char c : text.toCharArray()) { + for (final char c : text.toCharArray()) { if (cx + i >= size[0] || cy >= size[1]) { break; } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitSkin.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitSkin.java index 33b1aa9a..5ecfea99 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitSkin.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless24bit/Headless24bitSkin.java @@ -31,12 +31,12 @@ public class Headless24bitSkin implements Skin { final int[][] pixels = new int[width * height][]; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { - int rgb = bufferedImage.getRGB(i, j); - int r = (rgb >> 16) & 0xFF; - int g = (rgb >> 8) & 0xFF; - int b = rgb & 0xFF; - boolean transparent = ((rgb >> 24) & 0xFF) <= 128; - int[] curCol = Headless24bitRenderer.rgbToIntArray(r, g, b); + final int rgb = bufferedImage.getRGB(i, j); + final int r = (rgb >> 16) & 0xFF; + final int g = (rgb >> 8) & 0xFF; + final int b = rgb & 0xFF; + final boolean transparent = ((rgb >> 24) & 0xFF) <= 128; + final int[] curCol = Headless24bitRenderer.rgbToIntArray(r, g, b); pixels[i + j * width] = new int[] { curCol[0], curCol[1], curCol[2], transparent ? 1 : 0 }; } } @@ -59,4 +59,14 @@ public class Headless24bitSkin implements Skin { return true; } + @Override + public int getSkinWidth() { + return 0; + } + + @Override + public int getSkinHeight() { + return 0; + } + } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Engine.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Engine.java index fa739c44..dddb493b 100755 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Engine.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Engine.java @@ -7,15 +7,15 @@ import org.fusesource.jansi.AnsiConsole; import org.fusesource.jansi.internal.WindowsSupport; import org.warp.picalculator.StaticVars; import org.warp.picalculator.Utils; +import org.warp.picalculator.device.Key; import org.warp.picalculator.device.Keyboard; -import org.warp.picalculator.device.Keyboard.Key; import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.headless24bit.Headless24bitRenderer; public class Headless256Engine implements org.warp.picalculator.gui.graphicengine.GraphicEngine { - private Headless256Renderer r = new Headless256Renderer(); + private final Headless256Renderer r = new Headless256Renderer(); private boolean stopped = true; private RenderingLoop renderLoop; public static final int C_MUL_X = 4;//8; @@ -66,7 +66,7 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin if (Utils.isWindows() && !Utils.msDosMode) { win = true; WindowsSupport.setConsoleMode(0x0200); - Thread t = new Thread(() -> { + final Thread t = new Thread(() -> { int ch = -1; while (true) { if (precKey != null) { @@ -131,8 +131,9 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin t.start(); } stopped = false; - if (onInitialized != null) + if (onInitialized != null) { onInitialized.run(); + } } @Override @@ -157,7 +158,7 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin @Override public void start(RenderingLoop d) { - this.renderLoop = d; + renderLoop = d; final Thread th = new Thread(() -> { try { double extratime = 0; @@ -207,7 +208,7 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin curBgColor = r.bgColorMatrix[x + y * C_WIDTH]; curFgColor = r.fgColorMatrix[x + y * C_WIDTH]; if (precBgColor != curBgColor) { - String str = Headless256Renderer.ANSI_PREFIX + Headless256Renderer.ansiBgColorPrefix + curBgColor + Headless256Renderer.ansiColorSuffix; + final String str = Headless256Renderer.ANSI_PREFIX + Headless256Renderer.ansiBgColorPrefix + curBgColor + Headless256Renderer.ansiColorSuffix; if (win) { WindowsSupport.writeConsole(str); } else { @@ -215,7 +216,7 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin } } if (precFgColor != curFgColor) { - String str = Headless256Renderer.ANSI_PREFIX + Headless256Renderer.ansiFgColorPrefix + curFgColor + Headless256Renderer.ansiColorSuffix; + final String str = Headless256Renderer.ANSI_PREFIX + Headless256Renderer.ansiFgColorPrefix + curFgColor + Headless256Renderer.ansiColorSuffix; if (win) { WindowsSupport.writeConsole(str); } else { @@ -223,7 +224,7 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin } } - String stri = r.charmatrix[x + y * C_WIDTH] + ""; + final String stri = r.charmatrix[x + y * C_WIDTH] + ""; if (win) { WindowsSupport.writeConsole(stri); } else { @@ -275,8 +276,9 @@ public class Headless256Engine implements org.warp.picalculator.gui.graphicengin @Override public boolean isSupported() { - if (Utils.msDosMode || (Utils.forceEngine != null && Utils.forceEngine != "console-256")) + if (Utils.msDosMode || (Utils.forceEngine != null && Utils.forceEngine != "console-256")) { return false; + } return true; } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Font.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Font.java index 74f93ba7..477a96a1 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Font.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Font.java @@ -44,4 +44,14 @@ public class Headless256Font implements BinaryFont { return true; } + @Override + public int getSkinWidth() { + return 0; + } + + @Override + public int getSkinHeight() { + return 0; + } + } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Renderer.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Renderer.java index fc065907..36bf7500 100755 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Renderer.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Renderer.java @@ -41,20 +41,20 @@ public class Headless256Renderer implements Renderer { public static int rgbToX256(int r_U, int g_U, int b_U) { // Calculate the nearest 0-based color index at 16 .. 231 - int ir = v2ci(r_U), ig = v2ci(g_U), ib = v2ci(b_U); // 0..5 each + final int ir = v2ci(r_U), ig = v2ci(g_U), ib = v2ci(b_U); // 0..5 each /* 0..215, lazy evaluation */ // Calculate the nearest 0-based gray index at 232 .. 255 - int average = (r_U + g_U + b_U) / 3; - int grayIndex = average > 238 ? 23 : (average - 3) / 10; // 0..23 + final int average = (r_U + g_U + b_U) / 3; + final int grayIndex = average > 238 ? 23 : (average - 3) / 10; // 0..23 - int cr = i2cv[ir], cg = i2cv[ig], cb = i2cv[ib]; // r/g/b, 0..255 each - int gv = 8 + 10 * grayIndex; // same value for r/g/b, 0..255 + final int cr = i2cv[ir], cg = i2cv[ig], cb = i2cv[ib]; // r/g/b, 0..255 each + final int gv = 8 + 10 * grayIndex; // same value for r/g/b, 0..255 // Return the one which is nearer to the original input rgb value - int colorErr = distSquare(cr, cg, cb, r_U, g_U, b_U); - int grayErr = distSquare(gv, gv, gv, r_U, g_U, b_U); + final int colorErr = distSquare(cr, cg, cb, r_U, g_U, b_U); + final int grayErr = distSquare(gv, gv, gv, r_U, g_U, b_U); return colorErr <= grayErr ? 16 + colorIndex(ir, ig, ib) : 232 + grayIndex; } @@ -115,11 +115,11 @@ public class Headless256Renderer implements Renderer { y1 /= Headless256Engine.C_MUL_Y; y2 /= Headless256Engine.C_MUL_Y; - int dx = (int) Math.abs(x2 - x1); - int dy = (int) Math.abs(y2 - y1); + final int dx = (int) Math.abs(x2 - x1); + final int dy = (int) Math.abs(y2 - y1); - int sx = (x1 < x2) ? 1 : -1; - int sy = (y1 < y2) ? 1 : -1; + final int sx = (x1 < x2) ? 1 : -1; + final int sy = (y1 < y2) ? 1 : -1; int err = dx - dy; @@ -134,7 +134,7 @@ public class Headless256Renderer implements Renderer { break; } - int e2 = 2 * err; + final int e2 = 2 * err; if (e2 > -dy) { err = err - dy; @@ -187,8 +187,8 @@ public class Headless256Renderer implements Renderer { @Override public void glDrawCharLeft(int x, int y, char ch) { - final int cx = ((int) x) / Headless256Engine.C_MUL_X; - final int cy = ((int) y) / Headless256Engine.C_MUL_Y; + final int cx = (x) / Headless256Engine.C_MUL_X; + final int cy = (y) / Headless256Engine.C_MUL_Y; if (cx >= Headless256Engine.C_WIDTH || cy >= Headless256Engine.C_HEIGHT) { return; } @@ -203,8 +203,8 @@ public class Headless256Renderer implements Renderer { @Override public void glDrawCharRight(int x, int y, char ch) { - final int cx = ((int) x) / Headless256Engine.C_MUL_X - 1; - final int cy = ((int) y) / Headless256Engine.C_MUL_Y; + final int cx = (x) / Headless256Engine.C_MUL_X - 1; + final int cy = (y) / Headless256Engine.C_MUL_Y; if (cx >= Headless256Engine.C_WIDTH || cy >= Headless256Engine.C_HEIGHT) { return; } @@ -217,7 +217,7 @@ public class Headless256Renderer implements Renderer { final int cx = ((int) x) / Headless256Engine.C_MUL_X; final int cy = ((int) y) / Headless256Engine.C_MUL_Y; int i = 0; - for (char c : text.toCharArray()) { + for (final char c : text.toCharArray()) { if (cx + i >= Headless256Engine.C_WIDTH || cy >= Headless256Engine.C_HEIGHT) { break; } @@ -232,7 +232,7 @@ public class Headless256Renderer implements Renderer { final int cx = ((int) x) / Headless256Engine.C_MUL_X - text.length() / 2; final int cy = ((int) y) / Headless256Engine.C_MUL_Y; int i = 0; - for (char c : text.toCharArray()) { + for (final char c : text.toCharArray()) { if (cx + i >= Headless256Engine.C_WIDTH || cy >= Headless256Engine.C_HEIGHT) { break; } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Skin.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Skin.java index cbe67303..a8ddff50 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Skin.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless256/Headless256Skin.java @@ -28,9 +28,9 @@ public class Headless256Skin implements Skin { public static int[] getMatrixOfImage(BufferedImage bufferedImage) { BufferedImage after = new BufferedImage(bufferedImage.getWidth(null), bufferedImage.getHeight(null), BufferedImage.TYPE_INT_ARGB); - AffineTransform at = new AffineTransform(); - at.scale(1f / ((float) Headless256Engine.C_MUL_X), 1f / ((float) Headless256Engine.C_MUL_Y)); - AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); + final AffineTransform at = new AffineTransform(); + at.scale(1f / (Headless256Engine.C_MUL_X), 1f / (Headless256Engine.C_MUL_Y)); + final AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); after = scaleOp.filter(bufferedImage, after); final int width = after.getWidth(null); @@ -38,11 +38,11 @@ public class Headless256Skin implements Skin { final int[] pixels = new int[width * height]; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { - int rgb = after.getRGB(i, j); - int r = (rgb >> 16) & 0xFF; - int g = (rgb >> 8) & 0xFF; - int b = rgb & 0xFF; - boolean transparent = ((rgb >> 24) & 0xFF) <= 128; + final int rgb = after.getRGB(i, j); + final int r = (rgb >> 16) & 0xFF; + final int g = (rgb >> 8) & 0xFF; + final int b = rgb & 0xFF; + final boolean transparent = ((rgb >> 24) & 0xFF) <= 128; pixels[i + j * width] = Headless256Renderer.rgbToX256(r, g, b) | (transparent ? Headless256Renderer.TRANSPARENT : 0); } } @@ -65,4 +65,14 @@ public class Headless256Skin implements Skin { return true; } + @Override + public int getSkinWidth() { + return 0; + } + + @Override + public int getSkinHeight() { + return 0; + } + } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Engine.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Engine.java index ee0d0e21..5a18ca8c 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Engine.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Engine.java @@ -7,15 +7,15 @@ import org.fusesource.jansi.AnsiConsole; import org.fusesource.jansi.internal.WindowsSupport; import org.warp.picalculator.StaticVars; import org.warp.picalculator.Utils; +import org.warp.picalculator.device.Key; import org.warp.picalculator.device.Keyboard; -import org.warp.picalculator.device.Keyboard.Key; import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.headless24bit.Headless24bitRenderer; public class Headless8Engine implements org.warp.picalculator.gui.graphicengine.GraphicEngine { - private Headless8Renderer r = new Headless8Renderer(); + private final Headless8Renderer r = new Headless8Renderer(); private boolean stopped = true; private RenderingLoop renderLoop; public static final int C_MUL_X = 4;//8; @@ -66,7 +66,7 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine. if (Utils.isWindows() && !Utils.msDosMode) { win = true; WindowsSupport.setConsoleMode(0x0200); - Thread t = new Thread(() -> { + final Thread t = new Thread(() -> { int ch = -1; while (true) { if (precKey != null) { @@ -131,8 +131,9 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine. t.start(); } stopped = false; - if (onInitialized != null) + if (onInitialized != null) { onInitialized.run(); + } } @Override @@ -157,7 +158,7 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine. @Override public void start(RenderingLoop d) { - this.renderLoop = d; + renderLoop = d; final Thread th = new Thread(() -> { try { double extratime = 0; @@ -207,7 +208,7 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine. curBgColor = (r.colorMatrix[x + y * C_WIDTH] & 0xF0) >> 4; curFgColor = r.colorMatrix[x + y * C_WIDTH] & 0x0F; if (precBgColor != curBgColor) { - String str = Headless8Renderer.ANSI_PREFIX + Headless8Renderer.ansiBgColorPrefix + Headless8Renderer.colorANSI[curBgColor] + Headless8Renderer.ansiColorSuffix; + final String str = Headless8Renderer.ANSI_PREFIX + Headless8Renderer.ansiBgColorPrefix + Headless8Renderer.colorANSI[curBgColor] + Headless8Renderer.ansiColorSuffix; if (win) { WindowsSupport.writeConsole(str); } else { @@ -215,7 +216,7 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine. } } if (precFgColor != curFgColor) { - String str = Headless8Renderer.ANSI_PREFIX + Headless8Renderer.ansiFgColorPrefix + Headless8Renderer.colorANSI[curFgColor] + Headless8Renderer.ansiColorSuffix; + final String str = Headless8Renderer.ANSI_PREFIX + Headless8Renderer.ansiFgColorPrefix + Headless8Renderer.colorANSI[curFgColor] + Headless8Renderer.ansiColorSuffix; if (win) { WindowsSupport.writeConsole(str); } else { @@ -223,7 +224,7 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine. } } - String stri = r.charmatrix[x + y * C_WIDTH] + ""; + final String stri = r.charmatrix[x + y * C_WIDTH] + ""; if (win) { WindowsSupport.writeConsole(stri); } else { @@ -275,8 +276,9 @@ public class Headless8Engine implements org.warp.picalculator.gui.graphicengine. @Override public boolean isSupported() { - if (Utils.forceEngine != null && Utils.forceEngine != "console-8") + if (Utils.forceEngine != null && Utils.forceEngine != "console-8") { return false; + } return true; } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Font.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Font.java index 3c30618f..365347a6 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Font.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Font.java @@ -44,4 +44,14 @@ public class Headless8Font implements BinaryFont { return true; } + @Override + public int getSkinWidth() { + return 0; + } + + @Override + public int getSkinHeight() { + return 0; + } + } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Renderer.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Renderer.java index 540cc3d1..60ff9c0f 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Renderer.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Renderer.java @@ -22,9 +22,14 @@ public class Headless8Renderer implements Renderer { public static final char FILL = Utils.msDosMode ? 0xDB : '█'; private int hexColor(int red, int green, int blue) { - int r1 = red, r2, g1 = green, g2, b1 = blue, b2; + final int r1 = red; + int r2; + final int g1 = green; + int g2; + final int b1 = blue; + int b2; - float[] match = new float[16]; + final float[] match = new float[16]; // COLOR r2 = 0; @@ -124,7 +129,7 @@ public class Headless8Renderer implements Renderer { int minIndex = 0; for (int i = 1; i < match.length; i++) { - float newnumber = match[i]; + final float newnumber = match[i]; if ((newnumber < match[minIndex])) { minIndex = i; } @@ -231,11 +236,11 @@ public class Headless8Renderer implements Renderer { y1 /= Headless8Engine.C_MUL_Y; y2 /= Headless8Engine.C_MUL_Y; - int dx = (int) Math.abs(x2 - x1); - int dy = (int) Math.abs(y2 - y1); + final int dx = (int) Math.abs(x2 - x1); + final int dy = (int) Math.abs(y2 - y1); - int sx = (x1 < x2) ? 1 : -1; - int sy = (y1 < y2) ? 1 : -1; + final int sx = (x1 < x2) ? 1 : -1; + final int sy = (y1 < y2) ? 1 : -1; int err = dx - dy; @@ -243,7 +248,7 @@ public class Headless8Renderer implements Renderer { if (((int) x1) >= Headless8Engine.C_WIDTH || ((int) y1) >= Headless8Engine.C_HEIGHT || ((int) x2) >= Headless8Engine.C_WIDTH || ((int) y2) >= Headless8Engine.C_HEIGHT) { break; } - int precBG = colorMatrix[((int) x1) + ((int) y1) * Headless8Engine.C_WIDTH] & 0xF0; + final int precBG = colorMatrix[((int) x1) + ((int) y1) * Headless8Engine.C_WIDTH] & 0xF0; colorMatrix[((int) x1) + ((int) y1) * Headless8Engine.C_WIDTH] = precBG | curColor; charmatrix[((int) x1) + ((int) y1) * Headless8Engine.C_WIDTH] = FILL; @@ -251,7 +256,7 @@ public class Headless8Renderer implements Renderer { break; } - int e2 = 2 * err; + final int e2 = 2 * err; if (e2 > -dy) { err = err - dy; @@ -300,7 +305,7 @@ public class Headless8Renderer implements Renderer { final int sizeW = Headless8Engine.C_WIDTH; for (int px = ix; px < x1; px++) { for (int py = iy; py < y1; py++) { - int precBG = colorMatrix[(px) + (py) * sizeW] & 0xF0; + final int precBG = colorMatrix[(px) + (py) * sizeW] & 0xF0; colorMatrix[(px) + (py) * sizeW] = precBG | color; charmatrix[(px) + (py) * sizeW] = character; } @@ -309,13 +314,13 @@ public class Headless8Renderer implements Renderer { @Override public void glDrawCharLeft(int x, int y, char ch) { - final int cx = ((int) x) / Headless8Engine.C_MUL_X; - final int cy = ((int) y) / Headless8Engine.C_MUL_Y; + final int cx = (x) / Headless8Engine.C_MUL_X; + final int cy = (y) / Headless8Engine.C_MUL_Y; if (cx >= Headless8Engine.C_WIDTH || cy >= Headless8Engine.C_HEIGHT) { return; } charmatrix[cx + cy * Headless8Engine.C_WIDTH] = ch; - int precBG = colorMatrix[cx + cy * Headless8Engine.C_WIDTH] & 0xF0; + final int precBG = colorMatrix[cx + cy * Headless8Engine.C_WIDTH] & 0xF0; colorMatrix[cx + cy * Headless8Engine.C_WIDTH] = precBG | curColor; } @@ -326,13 +331,13 @@ public class Headless8Renderer implements Renderer { @Override public void glDrawCharRight(int x, int y, char ch) { - final int cx = ((int) x) / Headless8Engine.C_MUL_X - 1; - final int cy = ((int) y) / Headless8Engine.C_MUL_Y; + final int cx = (x) / Headless8Engine.C_MUL_X - 1; + final int cy = (y) / Headless8Engine.C_MUL_Y; if (cx >= Headless8Engine.C_WIDTH || cy >= Headless8Engine.C_HEIGHT) { return; } charmatrix[cx + cy * Headless8Engine.C_WIDTH] = ch; - int precBG = colorMatrix[cx + cy * Headless8Engine.C_WIDTH] & 0xF0; + final int precBG = colorMatrix[cx + cy * Headless8Engine.C_WIDTH] & 0xF0; colorMatrix[cx + cy * Headless8Engine.C_WIDTH] = precBG | curColor; } @@ -341,12 +346,12 @@ public class Headless8Renderer implements Renderer { final int cx = ((int) x) / Headless8Engine.C_MUL_X; final int cy = ((int) y) / Headless8Engine.C_MUL_Y; int i = 0; - for (char c : text.toCharArray()) { + for (final char c : text.toCharArray()) { if (cx + i >= Headless8Engine.C_WIDTH || cy >= Headless8Engine.C_HEIGHT) { break; } charmatrix[cx + i + cy * Headless8Engine.C_WIDTH] = c; - int precBG = colorMatrix[cx + i + cy * Headless8Engine.C_WIDTH] & 0xF0; + final int precBG = colorMatrix[cx + i + cy * Headless8Engine.C_WIDTH] & 0xF0; colorMatrix[cx + i + cy * Headless8Engine.C_WIDTH] = precBG | curColor; i++; } @@ -357,12 +362,12 @@ public class Headless8Renderer implements Renderer { final int cx = ((int) x) / Headless8Engine.C_MUL_X - text.length() / 2; final int cy = ((int) y) / Headless8Engine.C_MUL_Y; int i = 0; - for (char c : text.toCharArray()) { + for (final char c : text.toCharArray()) { if (cx + i >= Headless8Engine.C_WIDTH || cy >= Headless8Engine.C_HEIGHT) { break; } charmatrix[cx + i + cy * Headless8Engine.C_WIDTH] = c; - int precBG = colorMatrix[cx + i + cy * Headless8Engine.C_WIDTH] & 0xF0; + final int precBG = colorMatrix[cx + i + cy * Headless8Engine.C_WIDTH] & 0xF0; colorMatrix[cx + i + cy * Headless8Engine.C_WIDTH] = precBG | curColor; i++; } @@ -438,7 +443,7 @@ public class Headless8Renderer implements Renderer { final int b = (int) ((oldColor & 0xFF) * a1 + (newColor & 0xFF) * a2); newColor = 0xFF000000 | r << 16 | g << 8 | b; } - int bgColor = colorMatrix[pixelX + pixelY * Headless8Engine.C_WIDTH] & 0xF0; + final int bgColor = colorMatrix[pixelX + pixelY * Headless8Engine.C_WIDTH] & 0xF0; colorMatrix[pixelX + pixelY * Headless8Engine.C_WIDTH] = bgColor | hexColor(newColor >> 16 & 0xFF, newColor >> 8 & 0xFF, newColor & 0xFF); charmatrix[pixelX + pixelY * Headless8Engine.C_WIDTH] = FILL; } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Skin.java b/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Skin.java index 257639d5..52811909 100644 --- a/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Skin.java +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/headless8/Headless8Skin.java @@ -28,9 +28,9 @@ public class Headless8Skin implements Skin { public static int[] getMatrixOfImage(BufferedImage bufferedImage) { BufferedImage after = new BufferedImage(bufferedImage.getWidth(null), bufferedImage.getHeight(null), BufferedImage.TYPE_INT_ARGB); - AffineTransform at = new AffineTransform(); - at.scale(1f / ((float) Headless8Engine.C_MUL_X), 1f / ((float) Headless8Engine.C_MUL_Y)); - AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); + final AffineTransform at = new AffineTransform(); + at.scale(1f / (Headless8Engine.C_MUL_X), 1f / (Headless8Engine.C_MUL_Y)); + final AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); after = scaleOp.filter(bufferedImage, after); final int width = after.getWidth(null); @@ -60,4 +60,14 @@ public class Headless8Skin implements Skin { return true; } + @Override + public int getSkinWidth() { + return 0; + } + + @Override + public int getSkinHeight() { + return 0; + } + } diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/nogui/NoGuiEngine.java b/src/main/java/org/warp/picalculator/gui/graphicengine/nogui/NoGuiEngine.java new file mode 100644 index 00000000..1381376a --- /dev/null +++ b/src/main/java/org/warp/picalculator/gui/graphicengine/nogui/NoGuiEngine.java @@ -0,0 +1,285 @@ +package org.warp.picalculator.gui.graphicengine.nogui; + +import java.io.IOException; +import java.util.concurrent.Semaphore; + +import org.warp.picalculator.Utils; +import org.warp.picalculator.gui.graphicengine.BinaryFont; +import org.warp.picalculator.gui.graphicengine.GraphicEngine; +import org.warp.picalculator.gui.graphicengine.Renderer; +import org.warp.picalculator.gui.graphicengine.RenderingLoop; +import org.warp.picalculator.gui.graphicengine.Skin; + +public class NoGuiEngine implements GraphicEngine { + + private boolean initialized; + public Semaphore exitSemaphore = new Semaphore(0); + + @Override + public int[] getSize() { + return new int[] { 2, 2 }; + } + + @Override + public boolean isInitialized() { + return initialized; + } + + @Override + public void setTitle(String title) {} + + @Override + public void setResizable(boolean r) {} + + @Override + public void setDisplayMode(int ww, int wh) {} + + @Override + public void create(Runnable onInitialized) { + initialized = true; + if (onInitialized != null) { + onInitialized.run(); + } + } + + @Override + public boolean wasResized() { + return false; + } + + @Override + public int getWidth() { + return 2; + } + + @Override + public int getHeight() { + return 2; + } + + @Override + public void destroy() { + initialized = false; + exitSemaphore.release(); + } + + @Override + public void start(RenderingLoop d) {} + + @Override + public void repaint() {} + + @Override + public Renderer getRenderer() { + return new Renderer() { + @Override + public int glGetClearColor() { + return 0; + } + + @Override + public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth, + float uvHeight) {} + + @Override + public void glFillColor(float x, float y, float width, float height) {} + + @Override + public void glDrawStringRight(float x, float y, String text) {} + + @Override + public void glDrawStringLeft(float x, float y, String text) {} + + @Override + public void glDrawStringCenter(float x, float y, String text) {} + + @Override + public void glDrawLine(float x0, float y0, float x1, float y1) {} + + @Override + public void glDrawCharRight(int x, int y, char ch) {} + + @Override + public void glDrawCharLeft(int x, int y, char ch) {} + + @Override + public void glDrawCharCenter(int x, int y, char ch) {} + + @Override + public void glColor4i(int red, int green, int blue, int alpha) {} + + @Override + public void glColor4f(float red, float green, float blue, float alpha) {} + + @Override + public void glColor3i(int r, int gg, int b) {} + + @Override + public void glColor3f(float red, float green, float blue) {} + + @Override + public void glColor(int c) {} + + @Override + public void glClearSkin() {} + + @Override + public void glClearColor4i(int red, int green, int blue, int alpha) {} + + @Override + public void glClearColor4f(float red, float green, float blue, float alpha) {} + + @Override + public void glClearColor(int c) {} + + @Override + public void glClear(int screenWidth, int screenHeight) {} + + @Override + public BinaryFont getCurrentFont() { + return null; + } + }; + } + + @Override + public BinaryFont loadFont(String fontName) throws IOException { + return new BinaryFont() { + @Override + public void use(GraphicEngine d) {} + + @Override + public void load(String file) throws IOException {} + + @Override + public boolean isInitialized() { + return true; + } + + @Override + public void initialize(GraphicEngine d) {} + + @Override + public int getStringWidth(String text) { + return 1; + } + + @Override + public int getCharacterWidth() { + return 1; + } + + @Override + public int getCharacterHeight() { + return 1; + } + + @Override + public int getSkinWidth() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getSkinHeight() { + // TODO Auto-generated method stub + return 0; + } + }; + } + + @Override + public BinaryFont loadFont(String path, String fontName) throws IOException { + return new BinaryFont() { + @Override + public void use(GraphicEngine d) {} + + @Override + public void load(String file) throws IOException {} + + @Override + public boolean isInitialized() { + return true; + } + + @Override + public void initialize(GraphicEngine d) {} + + @Override + public int getStringWidth(String text) { + return 1; + } + + @Override + public int getCharacterWidth() { + return 1; + } + + @Override + public int getCharacterHeight() { + return 1; + } + + @Override + public int getSkinWidth() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getSkinHeight() { + // TODO Auto-generated method stub + return 0; + } + }; + } + + @Override + public Skin loadSkin(String file) throws IOException { + return new Skin() { + @Override + public void use(GraphicEngine d) {} + + @Override + public void load(String file) throws IOException {} + + @Override + public boolean isInitialized() { + return true; + } + + @Override + public void initialize(GraphicEngine d) {} + + @Override + public int getSkinWidth() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getSkinHeight() { + // TODO Auto-generated method stub + return 0; + } + }; + } + + @Override + public void waitForExit() { + try { + exitSemaphore.acquire(); + } catch (final InterruptedException e) {} + } + + @Override + public boolean isSupported() { + return Utils.forceEngine != null && Utils.forceEngine.equals("nogui"); + } + + @Override + public boolean doesRefreshPauses() { + return true; + } + +} diff --git a/src/main/java/org/warp/picalculator/gui/screens/ChooseVariableValueScreen.java b/src/main/java/org/warp/picalculator/gui/screens/ChooseVariableValueScreen.java index 9ef4fdcc..57cd7e84 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/ChooseVariableValueScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/ChooseVariableValueScreen.java @@ -2,7 +2,7 @@ package org.warp.picalculator.gui.screens; import org.warp.picalculator.StaticVars; import org.warp.picalculator.Utils; -import org.warp.picalculator.device.Keyboard.Key; +import org.warp.picalculator.device.Key; import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.functions.Variable.VariableValue; @@ -24,7 +24,7 @@ public class ChooseVariableValueScreen extends Screen { public void created() throws InterruptedException {} @Override - public void init() throws InterruptedException {} + public void initialized() throws InterruptedException {} @Override public void render() { diff --git a/src/main/java/org/warp/picalculator/gui/screens/EmptyScreen.java b/src/main/java/org/warp/picalculator/gui/screens/EmptyScreen.java index 46f9b7da..0f3144ae 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/EmptyScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/EmptyScreen.java @@ -1,6 +1,6 @@ package org.warp.picalculator.gui.screens; -import org.warp.picalculator.device.Keyboard.Key; +import org.warp.picalculator.device.Key; public class EmptyScreen extends Screen { @@ -17,7 +17,7 @@ public class EmptyScreen extends Screen { } @Override - public void init() throws InterruptedException {} + public void initialized() throws InterruptedException {} @Override public void render() { diff --git a/src/main/java/org/warp/picalculator/gui/screens/KeyboardDebugScreen.java b/src/main/java/org/warp/picalculator/gui/screens/KeyboardDebugScreen.java index 139801cc..482411ee 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/KeyboardDebugScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/KeyboardDebugScreen.java @@ -1,7 +1,7 @@ package org.warp.picalculator.gui.screens; import org.warp.picalculator.StaticVars; -import org.warp.picalculator.device.Keyboard.Key; +import org.warp.picalculator.device.Key; import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.graphicengine.Renderer; @@ -23,7 +23,7 @@ public class KeyboardDebugScreen extends Screen { public void created() throws InterruptedException {} @Override - public void init() throws InterruptedException {} + public void initialized() throws InterruptedException {} @Override public void render() { 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..0816cd80 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/LoadingScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/LoadingScreen.java @@ -1,7 +1,7 @@ package org.warp.picalculator.gui.screens; import org.warp.picalculator.StaticVars; -import org.warp.picalculator.device.Keyboard.Key; +import org.warp.picalculator.device.Key; import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.GraphicUtils; @@ -10,6 +10,8 @@ public class LoadingScreen extends Screen { public float endLoading; boolean mustRefresh = true; public float loadingTextTranslation = 0.0f; + public boolean loaded = false; + private float previousZoomValue = 1; public LoadingScreen() { super(); @@ -22,14 +24,18 @@ public class LoadingScreen extends Screen { } @Override - public void init() throws InterruptedException {} + public void initialized() throws InterruptedException { + previousZoomValue = StaticVars.getCurrentZoomValue(); + StaticVars.windowZoom = 1; + } @Override public void beforeRender(float dt) { loadingTextTranslation = GraphicUtils.sinDeg(endLoading * 90f) * 10f; endLoading += dt; - if (StaticVars.debugOn || endLoading >= 5f) { + if (loaded && (StaticVars.debugOn || endLoading >= 3.5f)) { + StaticVars.windowZoom = previousZoomValue; DisplayManager.INSTANCE.setScreen(new MathInputScreen()); } mustRefresh = true; diff --git a/src/main/java/org/warp/picalculator/gui/screens/MarioScreen.java b/src/main/java/org/warp/picalculator/gui/screens/MarioScreen.java index 6f112de0..5fbcb17b 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/MarioScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/MarioScreen.java @@ -3,36 +3,39 @@ package org.warp.picalculator.gui.screens; import java.io.IOException; import org.warp.picalculator.StaticVars; +import org.warp.picalculator.device.Key; import org.warp.picalculator.device.Keyboard; -import org.warp.picalculator.device.Keyboard.Key; +import org.warp.picalculator.extra.mario.MarioGame; +import org.warp.picalculator.extra.mario.MarioWorld; import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.Skin; public class MarioScreen extends Screen { + private MarioGame g; + private static Skin skin; private static Skin groundskin; - private static BinaryFont easterfont; - private static BinaryFont fu32font; - private static Skin easterskin; - private int easterNum = 0; - private float easterElapsed = 0; - private int easterMax = 21; - private String[] easterFu32 = new String[] {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "ò"}; - private int easterFu32Num = 0; - private float easterFu32Elapsed = 0; + private static BinaryFont gpuTest2; + private static BinaryFont gpuTest1; + private static boolean gpuTest12; + private static Skin gpuTest3; + private int gpuTestNum = 0; + private float gpuTestElapsed = 0; + private final int gpuTestMax = 21; + private final String[] gpuCharTest1 = new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "ò" }; + private int gpuCharTest1Num = 0; + private float gpuCharTestt1Elapsed = 0; private boolean errored; - public float[] marioPos = new float[] { 30, 0 }; - public float[] marioForces = new float[] { 0, 0 }; - public float walkAnimation = 0; - public float jumptime = 0; - public boolean walking = false; - public boolean running = false; - public boolean jumping = false; - public boolean flipped = false; - public boolean onGround = true; - public int[] marioSkinPos = new int[] { 0, 0 }; +// public float[] marioPos = new float[] { 30, 0 }; +// public float[] marioForces = new float[] { 0, 0 }; +// public float jumptime = 0; +// public boolean walking = false; +// public boolean running = false; +// public boolean jumping = false; +// public boolean flipped = false; +// public boolean onGround = true; public MarioScreen() { super(); @@ -40,24 +43,36 @@ public class MarioScreen extends Screen { } @Override - public void init() { + public void initialized() { try { - if (skin == null) + if (skin == null) { skin = DisplayManager.INSTANCE.engine.loadSkin("marioskin.png"); - if (groundskin == null) + } + if (groundskin == null) { groundskin = DisplayManager.INSTANCE.engine.loadSkin("marioground.png"); - if (easterfont == null) + } + if (gpuTest2 == null) { try { - easterfont = DisplayManager.INSTANCE.engine.loadFont("easter"); - } catch (Exception ex) {} - if (fu32font == null) + gpuTest2 = DisplayManager.INSTANCE.engine.loadFont("gputest2"); + } catch (final Exception ex) {} + } + if (gpuTest1 == null) { try { - fu32font = DisplayManager.INSTANCE.engine.loadFont("fu32"); - } catch (Exception ex) {} - if (easterskin == null) + gpuTest1 = DisplayManager.INSTANCE.engine.loadFont("gputest12"); + gpuTest12 = true; + StaticVars.windowZoom = 1; + } catch (final Exception ex) { + gpuTest12 = false; + try { + gpuTest1 = DisplayManager.INSTANCE.engine.loadFont("gputest1"); + } catch (final Exception ex2) {} + } + } + if (gpuTest3 == null) { try { - easterskin = DisplayManager.INSTANCE.engine.loadSkin("font_easter.png"); - } catch (Exception ex) {} + gpuTest3 = DisplayManager.INSTANCE.engine.loadSkin("font_gputest3.png"); + } catch (final Exception ex) {} + } } catch (final IOException e) { e.printStackTrace(); } @@ -66,89 +81,31 @@ public class MarioScreen extends Screen { @Override public void created() throws InterruptedException { if (!errored) { - + g = new MarioGame(); } } @Override public void beforeRender(float dt) { if (!errored) { - walkAnimation += dt; final boolean rightPressed = Keyboard.isKeyDown(2, 5); final boolean leftPressed = Keyboard.isKeyDown(2, 3); final boolean jumpPressed = Keyboard.isKeyDown(2, 1); - if ((leftPressed || rightPressed) == (leftPressed & rightPressed)) { - walking = false; - walkAnimation = 0; - } else { - if (rightPressed) { //RIGHT - if (marioForces[0] < 500f) { - marioForces[0] += dt * 500f; - } - walking = true; - flipped = false; - } - if (leftPressed) { //LEFT - if (marioForces[0] > -500f) { - marioForces[0] -= dt * 500f; - } - walking = true; - flipped = true; - } - } - if (jumpPressed) { //JUMP - jumptime += dt; - if (!jumping && onGround) { - marioForces[1] = dt * (4 * 1569.6f); - jumping = true; - onGround = false; - } else if (jumptime <= 0.5f) { - marioForces[1] = dt * (4 * 1569.6f); - } - } else { - jumping = false; - jumptime = 0; - } - if (!walking & !running & !jumping) { - marioSkinPos[0] = 0; - marioSkinPos[1] = 0; - } else if (onGround & walking & !running & !jumping && walkAnimation >= 0.08) { - while (walkAnimation > 0.08) { - walkAnimation -= 0.08; - if (marioSkinPos[0] == 1 & marioSkinPos[1] == 0) { - marioSkinPos[0] += 2; - } else if (marioSkinPos[0] == 3 & marioSkinPos[1] == 0) { - marioSkinPos[0] -= 1; - } else if (marioSkinPos[0] == 2 & marioSkinPos[1] == 0) { - marioSkinPos[0] -= 1; - } else { - marioSkinPos[0] = 1; - marioSkinPos[1] = 0; - } - } - } else if (jumping) { - marioSkinPos[0] = 5; - marioSkinPos[1] = 1; - } - marioForces[1] -= dt * 1569.6; - marioPos[0] += dt * marioForces[0]; - if (!onGround) { - marioPos[1] -= dt * marioForces[1]; - } - marioForces[0] *= 0.75; + final boolean upPressed = false, downPressed = false, runPressed = false; + g.gameTick(dt, upPressed, downPressed, leftPressed, rightPressed, jumpPressed, runPressed); - easterElapsed += dt; - while (easterElapsed >= 0.04) { - easterNum = (easterNum + 1) % easterMax; - easterElapsed -= 0.04; + gpuTestElapsed += dt; + while (gpuTestElapsed >= 0.04) { + gpuTestNum = (gpuTestNum + 1) % gpuTestMax; + gpuTestElapsed -= 0.04; } - easterFu32Elapsed += dt; - while (easterFu32Elapsed >= 1.5) { - easterFu32Num = (easterFu32Num + 1) % easterFu32.length; - easterFu32Elapsed -= 1.5; + gpuCharTestt1Elapsed += dt; + while (gpuCharTestt1Elapsed >= 1.5) { + gpuCharTest1Num = (gpuCharTest1Num + 1) % gpuCharTest1.length; + gpuCharTestt1Elapsed -= 1.5; } - - DisplayManager.INSTANCE.renderer.glClearColor(0xff9290ff); + + DisplayManager.INSTANCE.renderer.glClearColor(0xff000000); } } @@ -157,62 +114,81 @@ public class MarioScreen extends Screen { if (errored) { DisplayManager.INSTANCE.renderer.glDrawStringLeft(0, 20, "ERROR"); } else { - groundskin.use(DisplayManager.INSTANCE.engine); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 0, 25 + 25, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 1, 25 + 25, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 2, 25 + 25, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 3, 25 + 25, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 4, 25 + 25, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 5, 25 + 25, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 6, 25 + 25, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 7, 25 + 25, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 8, 25 + 25, 16, 16, 0, 0, 16, 16); + if (groundskin != null) { + final double playerX = g.getPlayer().getX(); + final double playerY = g.getPlayer().getY(); + groundskin.use(DisplayManager.INSTANCE.engine); + final MarioWorld w = g.getCurrentWorld(); + final int width = w.getWidth(); + final int height = w.getHeight(); + final float screenX = DisplayManager.INSTANCE.engine.getWidth() / 2f - 8f; + final float screenY = DisplayManager.INSTANCE.engine.getHeight() / 2f - 8f; + final float shiftX = -8 + 16 * (float) playerX; + final float shiftY = -8 + 16 * (height - (float) playerY); + int blue = -1; + for (int ix = 0; ix < width; ix++) { + for (int iy = 0; iy < height; iy++) { + final double distX = Math.abs(playerX - ix); + final double distY = Math.abs(playerY - iy - 1.5d); + if ((distX * distX + distY * distY / 2d) < 25d) { + final byte b = w.getBlockIdAt(ix, iy); + if (b == 0) { + if (blue != 1) { + blue = 1; + DisplayManager.INSTANCE.renderer.glColor(0xff9290ff); + } + DisplayManager.INSTANCE.renderer.glFillColor(screenX - shiftX + 16 * ix, screenY - shiftY + 16 * (height - iy), 16, 16); + } else { + if (blue != 0) { + blue = 0; + DisplayManager.INSTANCE.renderer.glColor(0xffffffff); + } + DisplayManager.INSTANCE.renderer.glFillRect(screenX - shiftX + 16 * ix, screenY - shiftY + 16 * (height - iy), 16, 16, 0, 0, 16, 16); + } + } + } + } + if (blue != 0) { + blue = 0; + DisplayManager.INSTANCE.renderer.glColor(0xffffffff); + } - DisplayManager.INSTANCE.renderer.glFillRect(16 * 0, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 1, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 2, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 3, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 4, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 5, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 6, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 7, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); - DisplayManager.INSTANCE.renderer.glFillRect(16 * 8, 25 + 25 + 16 * 1, 16, 16, 0, 0, 16, 16); + //DRAW MARIO + skin.use(DisplayManager.INSTANCE.engine); + DisplayManager.INSTANCE.renderer.glFillRect(screenX - (g.getPlayer().flipped ? 3 : 0), screenY, 35, 27, 35 * (g.getPlayer().marioSkinPos[0] + (g.getPlayer().flipped ? 2 : 1)), 27 * g.getPlayer().marioSkinPos[1], 35 * (g.getPlayer().flipped ? -1 : 1), 27); +// PIDisplay.renderer.glDrawSkin(getPosX() - 18, 25 + getPosY(), 35 * (marioSkinPos[0] + (flipped ? 2 : 1)), 27 * marioSkinPos[1], 35 * (marioSkinPos[0] + (flipped ? 1 : 2)), 27 * (marioSkinPos[1] + 1), true); + } -// EASTER EGG - if (fu32font != null) { - DisplayManager.INSTANCE.renderer.glColor3f(1,1,1); - DisplayManager.INSTANCE.renderer.glFillColor(DisplayManager.INSTANCE.engine.getWidth()-256, DisplayManager.INSTANCE.engine.getHeight() / 2 - 128, 256, 256); - fu32font.use(DisplayManager.INSTANCE.engine); +// GPU PERFORMANCE TEST + if (gpuTest1 != null) { + DisplayManager.INSTANCE.renderer.glColor3f(1, 1, 1); + DisplayManager.INSTANCE.renderer.glFillColor(DisplayManager.INSTANCE.engine.getWidth() - (gpuTest12 ? 512 : 256), DisplayManager.INSTANCE.engine.getHeight() / 2 - (gpuTest12 ? 256 : 128), gpuTest12 ? 512 : 256, gpuTest12 ? 512 : 256); + gpuTest1.use(DisplayManager.INSTANCE.engine); DisplayManager.INSTANCE.renderer.glColor3f(0, 0, 0); - DisplayManager.INSTANCE.renderer.glDrawStringRight(DisplayManager.INSTANCE.engine.getWidth(), DisplayManager.INSTANCE.engine.getHeight() / 2 - 128, easterFu32[easterFu32Num]); + DisplayManager.INSTANCE.renderer.glDrawStringRight(DisplayManager.INSTANCE.engine.getWidth(), DisplayManager.INSTANCE.engine.getHeight() / 2 - (gpuTest12 ? 256 : 128), gpuCharTest1[gpuCharTest1Num]); } - if (easterskin != null) { - easterskin.use(DisplayManager.INSTANCE.engine); + if (gpuTest3 != null) { + gpuTest3.use(DisplayManager.INSTANCE.engine); DisplayManager.INSTANCE.renderer.glColor4f(1, 1, 1, 0.7f); - DisplayManager.INSTANCE.renderer.glFillRect(0, StaticVars.screenSize[1] - 128, 224, 128, easterNum * 224, 0, 224, 128); + DisplayManager.INSTANCE.renderer.glFillRect(0, StaticVars.screenSize[1] - 128, 224, 128, gpuTestNum * 224, 0, 224, 128); } - if (easterfont != null) { - easterfont.use(DisplayManager.INSTANCE.engine); + if (gpuTest2 != null) { + gpuTest2.use(DisplayManager.INSTANCE.engine); DisplayManager.INSTANCE.renderer.glColor(0xFF000000); - DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - easterfont.getCharacterHeight(), "A"); + DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - gpuTest2.getCharacterHeight(), "A"); DisplayManager.INSTANCE.renderer.glColor(0xFF800000); - DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - easterfont.getCharacterHeight(), "B"); + DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - gpuTest2.getCharacterHeight(), "B"); DisplayManager.INSTANCE.renderer.glColor(0xFFeea28e); - DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - easterfont.getCharacterHeight(), "C"); + DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - gpuTest2.getCharacterHeight(), "C"); DisplayManager.INSTANCE.renderer.glColor(0xFFee7255); - DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - easterfont.getCharacterHeight(), "D"); + DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - gpuTest2.getCharacterHeight(), "D"); DisplayManager.INSTANCE.renderer.glColor(0xFFeac0b0); - DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - easterfont.getCharacterHeight(), "E"); + DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - gpuTest2.getCharacterHeight(), "E"); DisplayManager.INSTANCE.renderer.glColor(0xFFf3d8ce); - DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - easterfont.getCharacterHeight(), "F"); + DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - gpuTest2.getCharacterHeight(), "F"); DisplayManager.INSTANCE.renderer.glColor(0xFFffede7); - DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - easterfont.getCharacterHeight(), "G"); + DisplayManager.INSTANCE.renderer.glDrawStringRight(StaticVars.screenSize[0], DisplayManager.INSTANCE.engine.getHeight() - gpuTest2.getCharacterHeight(), "G"); } - - //DRAW MARIO - skin.use(DisplayManager.INSTANCE.engine); - DisplayManager.INSTANCE.renderer.glFillRect(getPosX() - 18, 25 + getPosY(), 35, 27, 35 * (marioSkinPos[0] + 1), 27 * marioSkinPos[1], 35, 27); -// PIDisplay.renderer.glDrawSkin(getPosX() - 18, 25 + getPosY(), 35 * (marioSkinPos[0] + (flipped ? 2 : 1)), 27 * marioSkinPos[1], 35 * (marioSkinPos[0] + (flipped ? 1 : 2)), 27 * (marioSkinPos[1] + 1), true); } } @@ -231,12 +207,4 @@ public class MarioScreen extends Screen { return false; } - private int getPosX() { - return (int) marioPos[0]; - } - - private int getPosY() { - return (int) marioPos[1]; - } - } 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..305a4430 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java @@ -3,14 +3,16 @@ package org.warp.picalculator.gui.screens; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.List; +import org.warp.picalculator.ConsoleUtils; import org.warp.picalculator.Error; import org.warp.picalculator.Errors; +import org.warp.picalculator.PlatformUtils; import org.warp.picalculator.StaticVars; import org.warp.picalculator.Utils; +import org.warp.picalculator.deps.DSystem; +import org.warp.picalculator.device.Key; import org.warp.picalculator.device.Keyboard; -import org.warp.picalculator.device.Keyboard.Key; import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.expression.InputContext; import org.warp.picalculator.gui.expression.blocks.Block; @@ -33,13 +35,14 @@ import org.warp.picalculator.math.functions.Number; import org.warp.picalculator.math.functions.Variable; import org.warp.picalculator.math.functions.Variable.VariableValue; import org.warp.picalculator.math.parser.MathParser; +import org.warp.picalculator.math.solver.MathSolver; import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class MathInputScreen extends Screen { private static final BinaryFont fontBig = Utils.getFont(false); - + public MathContext calc; public InputContext ic; public InputContainer userInput; @@ -68,7 +71,7 @@ public class MathInputScreen extends Screen { BlockContainer.initializeFonts(DisplayManager.INSTANCE.engine.loadFont("norm"), DisplayManager.INSTANCE.engine.loadFont("smal")); } catch (final IOException e) { e.printStackTrace(); - System.exit(1); + DSystem.exit(1); } userInput = new NormalInputContainer(ic); @@ -78,7 +81,7 @@ public class MathInputScreen extends Screen { } @Override - public void init() throws InterruptedException { + public void initialized() throws InterruptedException { /* Fine caricamento */ } @@ -94,7 +97,7 @@ public class MathInputScreen extends Screen { } if (computingResult) { computingElapsedTime += dt; - computingAnimationElapsedTime+=dt; + computingAnimationElapsedTime += dt; if (computingAnimationElapsedTime > 0.1) { computingAnimationElapsedTime -= 0.1; computingAnimationIndex = (computingAnimationIndex + 1) % 16; @@ -102,7 +105,7 @@ public class MathInputScreen extends Screen { } if (computingElapsedTime > 5) { computingBreakTipVisible = true; - } + } } else { computingElapsedTime = 0; computingAnimationElapsedTime = 0; @@ -110,6 +113,7 @@ public class MathInputScreen extends Screen { computingBreakTipVisible = false; } } + @Override public void render() { final Renderer renderer = DisplayManager.INSTANCE.renderer; @@ -131,7 +135,7 @@ public class MathInputScreen extends Screen { if (computingBreakTipVisible) { Utils.getFont(false).use(DisplayManager.INSTANCE.engine); renderer.glColor3f(0.75f, 0, 0); - renderer.glDrawStringRight(DisplayManager.INSTANCE.engine.getWidth() - 4 - size - 4, DisplayManager.INSTANCE.engine.getHeight() - size/2 - renderer.getCurrentFont().getCharacterHeight()/2 - 4, "Press (=) to stop"); + renderer.glDrawStringRight(DisplayManager.INSTANCE.engine.getWidth() - 4 - size - 4, DisplayManager.INSTANCE.engine.getHeight() - size / 2 - renderer.getCurrentFont().getCharacterHeight() / 2 - 4, "Press (=) to stop"); } } else { if (!result.isContentEmpty()) { @@ -141,7 +145,7 @@ public class MathInputScreen extends Screen { } @Override - public void renderStatusbar() { + public void renderTopmost() { final Renderer renderer = DisplayManager.INSTANCE.renderer; renderer.glColor3f(1, 1, 1); final int pos = 2; @@ -152,10 +156,10 @@ public class MathInputScreen extends Screen { } else { skinN = 21; } + DisplayManager.INSTANCE.guiSkin.use(DisplayManager.INSTANCE.engine); renderer.glFillRect(2 + 18 * pos + 2 * spacersNumb, 2, 16, 16, 16 * skinN, 16 * 0, 16, 16); } - @Override public boolean mustBeRefreshed() { if (mustRefresh) { @@ -168,319 +172,294 @@ public class MathInputScreen extends Screen { @Override public boolean keyPressed(Key k) { - Utils.out.println(1, k.toString()); - switch (k) { - case OK: - userInput.toggleExtra(); - mustRefresh = true; - return true; - case HISTORY_BACK: - if (userInput.isExtraOpened()) { - userInput.closeExtra(); - currentStep = 0; + ConsoleUtils.out.println(1, k.toString()); + try { + switch (k) { + case OK: + userInput.toggleExtra(); mustRefresh = true; return true; - } - default: - if (userInput.isExtraOpened() && userInput.getExtraKeyboardEventListener().keyPressed(k)) { - currentStep = 0; - return true; - } else { - final boolean step = k == Key.STEP; - switch (k) { + case HISTORY_BACK: + if (userInput.isExtraOpened()) { + userInput.closeExtra(); + currentStep = 0; + mustRefresh = true; + return true; + } + default: + if (userInput.isExtraOpened() && userInput.getExtraKeyboardEventListener().keyPressed(k)) { + currentStep = 0; + return true; + } else { + final boolean step = k == Key.STEP; + switch (k) { - case STEP: - currentStep++; - case SIMPLIFY: - if (!step) currentStep = 0; - if (DisplayManager.INSTANCE.error != null) { - //TODO: make the error management a global API rather than being relegated to this screen. - Utils.out.println(1, "Resetting after error..."); - DisplayManager.INSTANCE.error = null; - calc.f = null; - calc.f2 = null; - calc.resultsCount = 0; - return true; - } else { - if (!computingResult) { - computingResult = true; - computingThread = new Thread(()-> { - try { - try { - if (!userInput.isAlreadyParsed() && !userInput.isEmpty()) { - Expression expr = MathParser.parseInput(calc, userInput); - if (calc.f == null | calc.f2 == null) { - calc.f = new ObjectArrayList<>(); - calc.f2 = new ObjectArrayList<>(); - } else { - calc.f.clear(); - calc.f2.clear(); - } - 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."); - } - for (Function rr : resultExpressions) { - Utils.out.println(1, "RESULT: " + rr.toString()); - } - ObjectArrayList> resultBlocks = MathParser.parseOutput(calc, resultExpressions); - result.setContentAsMultipleGroups(resultBlocks); - // showVariablesDialog(() -> { - // currentExpression = newExpression; - // simplify(); - // }); - } - } catch (final InterruptedException ex) { - Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MIN, "Computing thread stopped."); - } catch (final Exception ex) { - if (StaticVars.debugOn) { - ex.printStackTrace(); - } - throw new Error(Errors.SYNTAX_ERROR); - } - } catch (final Error e) { - final StringWriter sw = new StringWriter(); - final PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n"); - DisplayManager.INSTANCE.error = e.id.toString(); - System.err.println(e.id); - } - computingResult = false; - }); - computingThread.setName("Computing Thread"); - computingThread.setDaemon(true); - computingThread.setPriority(Thread.NORM_PRIORITY + 3); - computingThread.start(); + case STEP: + currentStep++; + case SIMPLIFY: + if (!step) { + currentStep = 0; + } + if (DisplayManager.INSTANCE.error != null) { + //TODO: make the error management a global API rather than being relegated to this screen. + ConsoleUtils.out.println(1, "Resetting after error..."); + DisplayManager.INSTANCE.error = null; + calc.f = null; + calc.f2 = null; + calc.resultsCount = 0; return true; } else { - if (computingThread != null) { - computingThread.interrupt(); - computingResult = false; + if (!computingResult) { + computingResult = true; + computingThread = new Thread(() -> { + try { + try { + if (!userInput.isAlreadyParsed() && !userInput.isEmpty()) { + final Expression expr = MathParser.parseInput(calc, userInput); + if (calc.f == null | calc.f2 == null) { + calc.f = new ObjectArrayList<>(); + calc.f2 = new ObjectArrayList<>(); + } else { + calc.f.clear(); + calc.f2.clear(); + } + calc.f.add(expr); + ConsoleUtils.out.println(2, "INPUT: " + expr); + final MathSolver ms = new MathSolver(expr); + final ObjectArrayList> resultSteps = ms.solveAllSteps(); + resultSteps.add(0, Utils.newArrayList(expr)); + final ObjectArrayList resultExpressions = resultSteps.get(resultSteps.size() - 1); + for (final Function rr : resultExpressions) { + ConsoleUtils.out.println(0, "RESULT: " + rr.toString()); + } + final ObjectArrayList> resultBlocks = MathParser.parseOutput(calc, resultExpressions); + result.setContentAsMultipleGroups(resultBlocks); + // showVariablesDialog(() -> { + // currentExpression = newExpression; + // simplify(); + // }); + } + } catch (final InterruptedException ex) { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Computing thread stopped."); + } catch (final Exception ex) { + if (StaticVars.debugOn) { + ex.printStackTrace(); + } + throw new Error(Errors.SYNTAX_ERROR); + } + } catch (final Error e) { + d.errorStackTrace = PlatformUtils.stacktraceToString(e); + DisplayManager.INSTANCE.error = e.id.toString(); + System.err.println(e.id); + } + computingResult = false; + }); + PlatformUtils.setThreadName(computingThread, "Computing Thread"); + PlatformUtils.setDaemon(computingThread); + computingThread.setPriority(Thread.NORM_PRIORITY + 3); + computingThread.start(); return true; + } else { + if (computingThread != null) { + computingThread.interrupt(); + computingResult = false; + return true; + } + return false; } - return false; } - } - case NUM0: - typeChar('0'); - return true; - case NUM1: - typeChar('1'); - return true; - case NUM2: - typeChar('2'); - return true; - case NUM3: - typeChar('3'); - return true; - case NUM4: - typeChar('4'); - return true; - case NUM5: - typeChar('5'); - return true; - case NUM6: - typeChar('6'); - return true; - case NUM7: - typeChar('7'); - return true; - case NUM8: - typeChar('8'); - return true; - case NUM9: - typeChar('9'); - return true; - case PLUS: - typeChar('+'); - return true; - case MINUS: - typeChar('-'); - return true; - case PLUS_MINUS: - typeChar('±'); - return true; - case MULTIPLY: - typeChar('*'); - return true; - case DIVIDE: - typeChar('/'); - return true; - case PARENTHESIS_OPEN: - typeChar('('); - return true; - case PARENTHESIS_CLOSE: - typeChar(')'); - return true; - case DOT: - typeChar('.'); - return true; - case EQUAL: - typeChar('='); - return true; - case SQRT: - typeChar('Ⓐ'); - return true; - case ROOT: - typeChar('√'); - return true; - case POWER_OF_2: - typeChar(MathematicalSymbols.POWER_OF_TWO); - return true; - case POWER_OF_x: - typeChar(MathematicalSymbols.POWER); - return true; - case PI: - typeChar(MathematicalSymbols.PI); - return true; - case LETTER_X: - typeChar(MathematicalSymbols.variables[23]); - return true; - case LETTER_Y: - typeChar(MathematicalSymbols.variables[24]); - return true; - case SINE: - typeChar(MathematicalSymbols.SINE); - return true; - case COSINE: - typeChar(MathematicalSymbols.COSINE); - return true; - case TANGENT: - typeChar(MathematicalSymbols.TANGENT); - return true; - case ARCSINE: - typeChar(MathematicalSymbols.ARC_SINE); - return true; - case ARCCOSINE: - typeChar(MathematicalSymbols.ARC_COSINE); - return true; - case ARCTANGENT: - typeChar(MathematicalSymbols.ARC_TANGENT); - return true; - case DELETE: - userInput.del(); - currentStep = 0; - mustRefresh = true; - return true; - case LEFT: - userInput.moveLeft(); - mustRefresh = true; - return true; - case RIGHT: - userInput.moveRight(); - mustRefresh = true; - return true; - case RESET: - userInput.clear(); - result.clear(); - currentStep = 0; - if (DisplayManager.INSTANCE.error != null) { - Utils.out.println(1, "Resetting after error..."); - DisplayManager.INSTANCE.error = null; - } - return true; - case SURD_MODE: - calc.exactMode = !calc.exactMode; - result.clear(); - currentStep = 0; - Keyboard.keyPressed(Key.SIMPLIFY); - return true; - case debug1: - DisplayManager.INSTANCE.setScreen(new EmptyScreen()); - return true; - case HISTORY_BACK: - // if (DisplayManager.INSTANCE.canGoBack()) { - // if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.INSTANCE.sessions[DisplayManager.INSTANCE.currentSession + 1] instanceof MathInputScreen) { - // newExpression = currentExpression; - // try { - // interpreta(true); - // } catch (final Error e) {} - // } - // } - return false; - case HISTORY_FORWARD: - // if (DisplayManager.INSTANCE.canGoForward()) { - // if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.INSTANCE.sessions[DisplayManager.INSTANCE.currentSession - 1] instanceof MathInputScreen) { - // newExpression = currentExpression; - // try { - // interpreta(true); - // } catch (final Error e) {} - // } - // } - return false; - case debug_DEG: - if (calc.angleMode.equals(AngleMode.DEG) == false) { - calc.angleMode = AngleMode.DEG; + case NUM0: + typeChar('0'); + return true; + case NUM1: + typeChar('1'); + return true; + case NUM2: + typeChar('2'); + return true; + case NUM3: + typeChar('3'); + return true; + case NUM4: + typeChar('4'); + return true; + case NUM5: + typeChar('5'); + return true; + case NUM6: + typeChar('6'); + return true; + case NUM7: + typeChar('7'); + return true; + case NUM8: + typeChar('8'); + return true; + case NUM9: + typeChar('9'); + return true; + case PLUS: + typeChar('+'); + return true; + case MINUS: + typeChar('-'); + return true; + case PLUS_MINUS: + typeChar('±'); + return true; + case MULTIPLY: + typeChar('*'); + return true; + case DIVIDE: + typeChar('/'); + return true; + case PARENTHESIS_OPEN: + typeChar('('); + return true; + case PARENTHESIS_CLOSE: + typeChar(')'); + return true; + case DOT: + typeChar('.'); + return true; + case EQUAL: + typeChar('='); + return true; + case SQRT: + typeChar('Ⓐ'); + return true; + case ROOT: + typeChar('√'); + return true; + case POWER_OF_2: + typeChar(MathematicalSymbols.POWER_OF_TWO); + return true; + case POWER_OF_x: + typeChar(MathematicalSymbols.POWER); + return true; + case PI: + typeChar(MathematicalSymbols.PI); + return true; + case EULER_NUMBER: + typeChar(MathematicalSymbols.EULER_NUMBER); + return true; + case LETTER_X: + typeChar(MathematicalSymbols.variables[23]); + return true; + case LETTER_Y: + typeChar(MathematicalSymbols.variables[24]); + return true; + case SINE: + typeChar(MathematicalSymbols.SINE); + return true; + case COSINE: + typeChar(MathematicalSymbols.COSINE); + return true; + case TANGENT: + typeChar(MathematicalSymbols.TANGENT); + return true; + case ARCSINE: + typeChar(MathematicalSymbols.ARC_SINE); + return true; + case ARCCOSINE: + typeChar(MathematicalSymbols.ARC_COSINE); + return true; + case ARCTANGENT: + typeChar(MathematicalSymbols.ARC_TANGENT); + return true; + case LOGARITHM: + typeChar(MathematicalSymbols.LOGARITHM); + return true; + case DELETE: + userInput.del(); + currentStep = 0; + mustRefresh = true; + return true; + case LEFT: + userInput.moveLeft(); + mustRefresh = true; + return true; + case RIGHT: + userInput.moveRight(); + mustRefresh = true; + return true; + case RESET: + userInput.clear(); + result.clear(); + currentStep = 0; + if (DisplayManager.INSTANCE.error != null) { + ConsoleUtils.out.println(1, "Resetting after error..."); + DisplayManager.INSTANCE.error = null; + } + return true; + case SURD_MODE: + calc.exactMode = !calc.exactMode; + result.clear(); + currentStep = 0; + Keyboard.keyPressed(Key.SIMPLIFY); + return true; + case debug1: + DisplayManager.INSTANCE.setScreen(new EmptyScreen()); + return true; + case HISTORY_BACK: + // if (DisplayManager.INSTANCE.canGoBack()) { + // if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.INSTANCE.sessions[DisplayManager.INSTANCE.currentSession + 1] instanceof MathInputScreen) { + // newExpression = currentExpression; + // try { + // interpreta(true); + // } catch (final Error e) {} + // } + // } + return false; + case HISTORY_FORWARD: + // if (DisplayManager.INSTANCE.canGoForward()) { + // if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.INSTANCE.sessions[DisplayManager.INSTANCE.currentSession - 1] instanceof MathInputScreen) { + // newExpression = currentExpression; + // try { + // interpreta(true); + // } catch (final Error e) {} + // } + // } + return false; + case debug_DEG: + if (calc.angleMode.equals(AngleMode.DEG) == false) { + calc.angleMode = AngleMode.DEG; + currentStep = 0; + return true; + } + return false; + case debug_RAD: + if (calc.angleMode.equals(AngleMode.RAD) == false) { + calc.angleMode = AngleMode.RAD; + currentStep = 0; + return true; + } + return false; + case debug_GRA: + if (calc.angleMode.equals(AngleMode.GRA) == false) { + calc.angleMode = AngleMode.GRA; + currentStep = 0; + return true; + } + return false; + case DRG_CYCLE: + if (calc.angleMode.equals(AngleMode.DEG) == true) { + calc.angleMode = AngleMode.RAD; + } else if (calc.angleMode.equals(AngleMode.RAD) == true) { + calc.angleMode = AngleMode.GRA; + } else { + calc.angleMode = AngleMode.DEG; + } currentStep = 0; return true; - } - return false; - case debug_RAD: - if (calc.angleMode.equals(AngleMode.RAD) == false) { - calc.angleMode = AngleMode.RAD; - currentStep = 0; - return true; - } - return false; - case debug_GRA: - if (calc.angleMode.equals(AngleMode.GRA) == false) { - calc.angleMode = AngleMode.GRA; - currentStep = 0; - return true; - } - return false; - case DRG_CYCLE: - if (calc.angleMode.equals(AngleMode.DEG) == true) { - calc.angleMode = AngleMode.RAD; - } else if (calc.angleMode.equals(AngleMode.RAD) == true) { - calc.angleMode = AngleMode.GRA; - } else { - calc.angleMode = AngleMode.DEG; - } - currentStep = 0; - return true; - default: - return false; + default: + return false; + } } - } + } + } catch (final Exception ex) { + ex.printStackTrace(); + return true; } } @@ -683,9 +662,9 @@ public class MathInputScreen extends Screen { } } }); - ct.setName("Variables user-input queue thread"); + PlatformUtils.setThreadName(ct, "Variables user-input queue thread"); ct.setPriority(Thread.MIN_PRIORITY); - ct.setDaemon(true); + PlatformUtils.setDaemon(ct); ct.start(); } diff --git a/src/main/java/org/warp/picalculator/gui/screens/Screen.java b/src/main/java/org/warp/picalculator/gui/screens/Screen.java index fffca7a3..fcdbb1ea 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/Screen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/Screen.java @@ -2,8 +2,9 @@ package org.warp.picalculator.gui.screens; import org.warp.picalculator.device.KeyboardEventListener; import org.warp.picalculator.gui.DisplayManager; +import org.warp.picalculator.gui.GraphicalInterface; -public abstract class Screen implements KeyboardEventListener { +public abstract class Screen implements KeyboardEventListener, GraphicalInterface { public DisplayManager d; public boolean created = false; public boolean initialized = false; @@ -11,13 +12,15 @@ public abstract class Screen implements KeyboardEventListener { public Screen() {} + @Override public void initialize() throws InterruptedException { if (!initialized) { initialized = true; - init(); + initialized(); } } + @Override public void create() throws InterruptedException { if (!created) { created = true; @@ -27,15 +30,19 @@ public abstract class Screen implements KeyboardEventListener { public abstract void created() throws InterruptedException; - public abstract void init() throws InterruptedException; + public abstract void initialized() throws InterruptedException; + @Override public abstract void render(); - public void renderStatusbar() { + @Override + public void renderTopmost() { } + @Override public abstract void beforeRender(float dt); + @Override public abstract boolean mustBeRefreshed(); } diff --git a/src/main/java/org/warp/picalculator/gui/screens/SolveEquationScreen.java b/src/main/java/org/warp/picalculator/gui/screens/SolveForXScreen.java similarity index 88% rename from src/main/java/org/warp/picalculator/gui/screens/SolveEquationScreen.java rename to src/main/java/org/warp/picalculator/gui/screens/SolveForXScreen.java index 3ec770ec..dcaa0dec 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/SolveEquationScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/SolveForXScreen.java @@ -1,15 +1,15 @@ package org.warp.picalculator.gui.screens; import org.warp.picalculator.StaticVars; -import org.warp.picalculator.device.Keyboard.Key; +import org.warp.picalculator.device.Key; import org.warp.picalculator.gui.DisplayManager; -public class SolveEquationScreen extends Screen { +public class SolveForXScreen extends Screen { @SuppressWarnings("unused") private final MathInputScreen es; - public SolveEquationScreen(MathInputScreen es) { + public SolveForXScreen(MathInputScreen es) { super(); canBeInHistory = false; @@ -20,7 +20,7 @@ public class SolveEquationScreen extends Screen { public void created() throws InterruptedException {} @Override - public void init() throws InterruptedException {} + public void initialized() throws InterruptedException {} @Override public void render() { diff --git a/src/main/java/org/warp/picalculator/math/Function.java b/src/main/java/org/warp/picalculator/math/Function.java index c9ca8a5e..e09a20d0 100755 --- a/src/main/java/org/warp/picalculator/math/Function.java +++ b/src/main/java/org/warp/picalculator/math/Function.java @@ -1,9 +1,8 @@ package org.warp.picalculator.math; -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; @@ -55,18 +54,16 @@ public interface Function { public MathContext getMathContext(); /** - * Simplify the current function or it's children - * @throws InterruptedException - */ - public List simplify() throws Error, InterruptedException; - - /** - * The current simplification status of this function and it's childrens + * Simplify the current function or it's children using the specified + * rule * - * @return boolean - * @throws InterruptedException + * @param rule + * @return A list of the resulting Functions if the rule is applicable and + * something changed, null otherwise + * @throws Error + * @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..d31a0c0b 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,43 @@ 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(); } - if (Thread.interrupted()) throw new InterruptedException(); - ObjectArrayList result = solved ? solve() : null; + final 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(); } - - final Function[][] results = Utils.joinFunctionsResults(ln); - - for (final Function[] f : results) { - result.add(this.setParameters(f)); + final 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); + + 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..693b29cb 100755 --- a/src/main/java/org/warp/picalculator/math/FunctionOperator.java +++ b/src/main/java/org/warp/picalculator/math/FunctionOperator.java @@ -1,7 +1,9 @@ package org.warp.picalculator.math; import org.warp.picalculator.Error; +import org.warp.picalculator.Errors; import org.warp.picalculator.Utils; +import org.warp.picalculator.math.rules.Rule; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -113,69 +115,62 @@ public abstract class FunctionOperator implements Function { } @Override - public boolean isSimplified() throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - return (parameter1.isSimplified() & parameter2.isSimplified()) ? !isSolvable() : false; - } + public final ObjectArrayList simplify(Rule rule) throws Error, InterruptedException { + if (Thread.interrupted()) { + throw new InterruptedException(); + } - /** - * 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 { - if (Thread.interrupted()) throw new InterruptedException(); - final boolean solved = parameter1.isSimplified() & parameter2.isSimplified(); - 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 (Thread.interrupted()) throw new InterruptedException(); - if (parameter1.isSimplified()) { - l1.add(parameter1); - } else { - if (Thread.interrupted()) throw new InterruptedException(); - l1.addAll(parameter1.simplify()); - } - if (Thread.interrupted()) throw new InterruptedException(); - if (parameter2.isSimplified()) { - l2.add(parameter2); - } else { - if (Thread.interrupted()) throw new InterruptedException(); - l2.addAll(parameter2.simplify()); + final ObjectArrayList simplifiedParam1 = parameter1.simplify(rule); + final ObjectArrayList simplifiedParam2 = parameter2.simplify(rule); + try { + if (simplifiedParam1 == null & simplifiedParam2 == null) { + return rule.execute(this); } + } catch (final Exception e) { + final Error err = new Error(Errors.ERROR, "Error while executing rule '" + rule.getRuleName() + "'!\n" + e.getMessage()); + err.initCause(e); + throw err; + } - final Function[][] results = Utils.joinFunctionsResults(l1, l2); + if (Thread.interrupted()) { + throw new InterruptedException(); + } + final ObjectArrayList result = new ObjectArrayList<>(); - for (final Function[] f : results) { - result.add(setParameter1(f[0]).setParameter2(f[1])); + final ObjectArrayList l1 = new ObjectArrayList<>(); + final ObjectArrayList l2 = new ObjectArrayList<>(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } + if (simplifiedParam1 == null) { + l1.add(parameter1); + } else { + if (Thread.interrupted()) { + throw new InterruptedException(); } + l1.addAll(simplifiedParam1); + } + if (Thread.interrupted()) { + throw new InterruptedException(); + } + if (simplifiedParam2 == null) { + l2.add(parameter2); + } else { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + 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(); @@ -189,6 +184,6 @@ public abstract class FunctionOperator implements Function { @Override public String toString() { - return this.getClass().getSimpleName() + "(" + this.getParameter1() + "," + this.getParameter2() + ")"; + return this.getClass().getSimpleName() + "(" + getParameter1() + "," + getParameter2() + ")"; } } diff --git a/src/main/java/org/warp/picalculator/math/FunctionSingle.java b/src/main/java/org/warp/picalculator/math/FunctionSingle.java index 9a0a5550..08b570b5 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,20 @@ public abstract class FunctionSingle implements Function { } @Override - public final ObjectArrayList simplify() throws Error, InterruptedException { - final boolean simplified = parameter.isSimplified(); - ObjectArrayList result = simplified ? solve() : null; + public final ObjectArrayList simplify(Rule rule) throws Error, InterruptedException { + final ObjectArrayList simplifiedParam = parameter.simplify(rule); + if (simplifiedParam == null) { + return rule.execute(this); + } - 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)); - } + final 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/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/MathematicalSymbols.java b/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java index 96ed1150..11805572 100755 --- a/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java +++ b/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java @@ -16,7 +16,6 @@ public class MathematicalSymbols { public static final char PARENTHESIS_OPEN = '('; public static final char PARENTHESIS_CLOSE = ')'; public static final char POWER = 'Ⓑ'; - public static final char POWER_OF_TWO = 'Ⓘ'; public static final char EQUATION = '='; public static final char SYSTEM = '{'; public static final char SINE = 'Ⓒ'; @@ -25,11 +24,17 @@ public class MathematicalSymbols { public static final char ARC_SINE = 'Ⓕ'; public static final char ARC_COSINE = 'Ⓖ'; public static final char ARC_TANGENT = 'Ⓗ'; + public static final char POWER_OF_TWO = 'Ⓘ'; + public static final char LOGARITHM = 'Ⓙ'; + public static final char UNDEFINED = '∅'; public static final char PI = 'π'; + public static final char EULER_NUMBER = 'e'; + public static final char X = 'ⓧ'; + public static final char Y = 'Ⓨ'; public static final char[] functionsNSN = new char[] { NTH_ROOT, POWER }; - public static final char[] functionsSN = new char[] { SQUARE_ROOT, POWER_OF_TWO, MINUS, SINE, COSINE, TANGENT, ARC_SINE, ARC_COSINE, ARC_TANGENT }; + public static final char[] functionsSN = new char[] { SQUARE_ROOT, POWER_OF_TWO, MINUS, SINE, COSINE, TANGENT, ARC_SINE, ARC_COSINE, ARC_TANGENT, LOGARITHM }; public static final char[] functions = concat(functionsNSN, functionsSN); @@ -48,7 +53,7 @@ public class MathematicalSymbols { public static final char[] parentheses = new char[] { PARENTHESIS_OPEN, PARENTHESIS_CLOSE }; - public static final char[] variables = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'ⓧ', 'Ⓨ', 'Z', PI }; + public static final char[] variables = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', X, Y, 'Z', PI, EULER_NUMBER, UNDEFINED }; public static final char[] genericSyntax = new char[] { SYSTEM, EQUATION }; 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..1d78a1c7 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Division.java +++ b/src/main/java/org/warp/picalculator/math/functions/Division.java @@ -1,25 +1,12 @@ package org.warp.picalculator.math.functions; -import java.math.BigInteger; -import java.util.Iterator; -import java.util.LinkedList; - import org.warp.picalculator.Error; -import org.warp.picalculator.Utils; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockContainer; import org.warp.picalculator.gui.expression.blocks.BlockDivision; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionOperator; import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.rules.FractionsRule1; -import org.warp.picalculator.math.rules.FractionsRule11; -import org.warp.picalculator.math.rules.FractionsRule12; -import org.warp.picalculator.math.rules.FractionsRule2; -import org.warp.picalculator.math.rules.FractionsRule3; -import org.warp.picalculator.math.rules.UndefinedRule2; -import org.warp.picalculator.math.rules.methods.DivisionRule1; - import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class Division extends FunctionOperator { @@ -28,92 +15,6 @@ public class Division extends FunctionOperator { 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) { @@ -135,16 +36,16 @@ public class Division extends FunctionOperator { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); - ObjectArrayList sub1 = getParameter1().toBlock(context); - ObjectArrayList sub2 = getParameter2().toBlock(context); - BlockDivision bd = new BlockDivision(); - BlockContainer uc = bd.getUpperContainer(); - BlockContainer lc = bd.getLowerContainer(); - for (Block b : sub1) { + final ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList sub1 = getParameter1().toBlock(context); + final ObjectArrayList sub2 = getParameter2().toBlock(context); + final BlockDivision bd = new BlockDivision(); + final BlockContainer uc = bd.getUpperContainer(); + final BlockContainer lc = bd.getLowerContainer(); + for (final Block b : sub1) { uc.appendBlockUnsafe(b); } - for (Block b : sub2) { + for (final Block b : sub2) { lc.appendBlockUnsafe(b); } uc.recomputeDimensions(); 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..f7775d34 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, InterruptedException { + 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..44d341b7 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Expression.java +++ b/src/main/java/org/warp/picalculator/math/functions/Expression.java @@ -1,7 +1,5 @@ package org.warp.picalculator.math.functions; -import java.util.List; - import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockContainer; @@ -28,7 +26,7 @@ public class Expression extends FunctionSingle { super(root, value); } - private boolean initialParenthesis = false; + private final boolean initialParenthesis = false; @Deprecated public Expression(MathContext root, String string) throws Error { @@ -548,37 +546,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) { @@ -603,11 +570,11 @@ public class Expression extends FunctionSingle { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); - ObjectArrayList sub = getParameter(0).toBlock(context); - BlockParenthesis bp = new BlockParenthesis(); - BlockContainer bpc = bp.getNumberContainer(); - for (Block b : sub) { + final ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList sub = getParameter(0).toBlock(context); + final BlockParenthesis bp = new BlockParenthesis(); + final BlockContainer bpc = bp.getNumberContainer(); + for (final Block b : sub) { bpc.appendBlockUnsafe(b); } bpc.recomputeDimensions(); @@ -624,7 +591,6 @@ public class Expression extends FunctionSingle { } else { s += parameter.toString(); } - s = s.substring(0, s.length() - 1); s += ")"; return s; } @@ -635,7 +601,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..99f870f4 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, InterruptedException { + return rule.execute(this); } @Override diff --git a/src/main/java/org/warp/picalculator/math/functions/Logarithm.java b/src/main/java/org/warp/picalculator/math/functions/Logarithm.java new file mode 100644 index 00000000..70304a44 --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/functions/Logarithm.java @@ -0,0 +1,54 @@ +package org.warp.picalculator.math.functions; + +import org.warp.picalculator.Error; +import org.warp.picalculator.gui.expression.blocks.Block; +import org.warp.picalculator.gui.expression.blocks.BlockContainer; +import org.warp.picalculator.gui.expression.blocks.BlockLogarithm; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +public class Logarithm extends FunctionOperator { + + public Logarithm(MathContext root, Function value1, Function value2) { + super(root, value1, value2); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Logarithm) { + final FunctionOperator f = (FunctionOperator) o; + return parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2()); + } + return false; + } + + @Override + public Logarithm clone() { + return new Logarithm(mathContext, parameter1, parameter2); + } + + @Override + public ObjectArrayList toBlock(MathContext context) throws Error { + final ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList sub1 = getParameter1().toBlock(context); + final ObjectArrayList sub2 = getParameter2().toBlock(context); + final BlockLogarithm bd = new BlockLogarithm(); + final BlockContainer uc = bd.getBaseContainer(); + final BlockContainer lc = bd.getNumberContainer(); + for (final Block b : sub1) { + uc.appendBlockUnsafe(b); + } + for (final Block b : sub2) { + lc.appendBlockUnsafe(b); + } + uc.recomputeDimensions(); + lc.recomputeDimensions(); + bd.recomputeDimensions(); + result.add(bd); + return result; + } + +} 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..270793b8 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Multiplication.java +++ b/src/main/java/org/warp/picalculator/math/functions/Multiplication.java @@ -8,15 +8,6 @@ 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.ExpandRule2; -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.methods.MultiplicationMethod1; - import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class Multiplication extends FunctionOperator { @@ -29,65 +20,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) { @@ -108,19 +40,19 @@ public class Multiplication extends FunctionOperator { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); - Function par1 = getParameter1(); - Function par2 = getParameter2(); - ObjectArrayList sub1 = par1.toBlock(context); - ObjectArrayList sub2 = par2.toBlock(context); - Block nearLeft = sub1.get(sub1.size() - 1); - Block nearRight = sub2.get(0); + final ObjectArrayList result = new ObjectArrayList<>(); + final Function par1 = getParameter1(); + final Function par2 = getParameter2(); + final ObjectArrayList sub1 = par1.toBlock(context); + final ObjectArrayList sub2 = par2.toBlock(context); + final Block nearLeft = sub1.get(sub1.size() - 1); + final Block nearRight = sub2.get(0); if (par1 instanceof Number && ((Number) par1).equals(new Number(context, -1))) { result.add(new BlockChar(MathematicalSymbols.MINUS)); if (new Expression(context, par2).parenthesisNeeded()) { - ObjectArrayList parBlocks = par2.toBlock(context); - BlockParenthesis par = new BlockParenthesis(parBlocks); + final ObjectArrayList parBlocks = par2.toBlock(context); + final BlockParenthesis par = new BlockParenthesis(parBlocks); result.add(par); } else { result.addAll(sub2); @@ -128,23 +60,20 @@ public class Multiplication extends FunctionOperator { return result; } else { if (new Expression(context, par1).parenthesisNeeded()) { - ObjectArrayList parBlocks = par1.toBlock(context); - BlockParenthesis par = new BlockParenthesis(parBlocks); + final ObjectArrayList parBlocks = par1.toBlock(context); + final BlockParenthesis par = new BlockParenthesis(parBlocks); result.add(par); } else { result.addAll(sub1); } - if ((nearLeft instanceof BlockChar && nearRight instanceof BlockChar) - && !(par2 instanceof Negative) - && !(par1 instanceof Number && par2 instanceof Number) - ) { + if ((nearLeft instanceof BlockChar && nearRight instanceof BlockChar) && !(par2 instanceof Negative) && !(par1 instanceof Number && par2 instanceof Number)) { } else { result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION)); } if (new Expression(context, par2).parenthesisNeeded()) { - ObjectArrayList parBlocks = par2.toBlock(context); - BlockParenthesis par = new BlockParenthesis(parBlocks); + final ObjectArrayList parBlocks = par2.toBlock(context); + final BlockParenthesis par = new BlockParenthesis(parBlocks); result.add(par); } else { result.addAll(sub2); @@ -152,4 +81,22 @@ public class Multiplication extends FunctionOperator { return result; } } + + public boolean isNegative() { + return parameter1.equals(new Number(getMathContext(), -1)) || parameter2.equals(new Number(getMathContext(), -1)); + } + + public Function toPositive() { + if (parameter1.equals(new Number(getMathContext(), -1))) { + return parameter2; + } else if (parameter2.equals(new Number(getMathContext(), -1))) { + return parameter2; + } else { + return null; + } + } + + public static Multiplication newNegative(MathContext context, Function value2) { + return new Multiplication(context, new Number(context, -1), value2); + } } \ No newline at end of file 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..3b7de3ba 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Negative.java +++ b/src/main/java/org/warp/picalculator/math/functions/Negative.java @@ -1,7 +1,6 @@ package org.warp.picalculator.math.functions; import org.warp.picalculator.Error; -import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockChar; import org.warp.picalculator.gui.expression.blocks.BlockParenthesis; @@ -9,8 +8,6 @@ import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionSingle; 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.ExpandRule5; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -20,47 +17,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) { @@ -76,12 +32,12 @@ public class Negative extends FunctionSingle { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList blocks = new ObjectArrayList(); + final ObjectArrayList blocks = new ObjectArrayList<>(); blocks.add(new BlockChar(MathematicalSymbols.MINUS)); if (new Expression(context, getParameter()).parenthesisNeeded()) { - BlockParenthesis par = new BlockParenthesis(); - ObjectArrayList parBlocks = getParameter().toBlock(context); - for (Block b : parBlocks) { + final BlockParenthesis par = new BlockParenthesis(); + final ObjectArrayList parBlocks = getParameter().toBlock(context); + for (final Block b : parBlocks) { par.getNumberContainer().appendBlockUnsafe(b); // Skips recomputeDimension } par.recomputeDimensions(); // Recompute dimensions after appendBlockUnsafe 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..e8a07e71 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Number.java +++ b/src/main/java/org/warp/picalculator/math/functions/Number.java @@ -3,8 +3,6 @@ package org.warp.picalculator.math.functions; import java.math.BigDecimal; import java.math.BigInteger; import java.util.LinkedList; -import java.util.List; - import org.nevec.rjm.BigDecimalMath; import org.warp.picalculator.Error; import org.warp.picalculator.Utils; @@ -15,6 +13,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; @@ -77,7 +76,9 @@ public class Number implements Function { if (Utils.isIntegerValue(f.term)) { final BigInteger bi = f.term.toBigInteger().abs(); for (BigInteger i = BigInteger.ZERO; i.compareTo(bi) < 0; i = i.add(BigInteger.ONE)) { - if (Thread.interrupted()) throw new InterruptedException(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } ret = ret.multiply(new Number(root, getTerm())); } if (f.term.signum() == -1) { @@ -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, InterruptedException { + return rule.execute(this); } public int getNumberOfDecimalPlaces() { @@ -234,7 +217,7 @@ public class Number implements Function { if (n.compareTo(BigInteger.ONE) > 0) { BigInteger f = BigInteger.valueOf(3); - while (f.multiply(f).compareTo(n) <= 0) { + while (f.compareTo(Utils.maxFactor) <= 0 && f.multiply(f).compareTo(n) <= 0) { if (n.mod(f).equals(BigInteger.ZERO)) { fs.add(f); n = n.divide(f); @@ -250,16 +233,16 @@ public class Number implements Function { @Override public ObjectArrayList toBlock(MathContext context) { - ObjectArrayList result = new ObjectArrayList<>(); - String numberString = this.toString(); + final ObjectArrayList result = new ObjectArrayList<>(); + final String numberString = toString(); if (numberString.contains("ℯ℮")) { - String[] numberParts = numberString.split("ℯ℮", 2); - BlockPower bp = new BlockExponentialNotation(); - BlockContainer bpec = bp.getExponentContainer(); - for (char c : numberParts[0].toCharArray()) { + final String[] numberParts = numberString.split("ℯ℮", 2); + final BlockPower bp = new BlockExponentialNotation(); + final BlockContainer bpec = bp.getExponentContainer(); + for (final char c : numberParts[0].toCharArray()) { result.add(new BlockChar(c)); } - for (char c : numberParts[1].toCharArray()) { + for (final char c : numberParts[1].toCharArray()) { bpec.appendBlockUnsafe(new BlockChar(c)); } ; bpec.recomputeDimensions(); @@ -267,7 +250,7 @@ public class Number implements Function { result.add(bp); return result; } else { - for (char c : numberString.toCharArray()) { + for (final char c : numberString.toCharArray()) { result.add(new BlockChar(c)); } } 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..67374cfa 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Power.java +++ b/src/main/java/org/warp/picalculator/math/functions/Power.java @@ -7,14 +7,6 @@ import org.warp.picalculator.gui.expression.blocks.BlockPower; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionOperator; import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.rules.ExponentRule1; -import org.warp.picalculator.math.rules.ExponentRule2; -import org.warp.picalculator.math.rules.ExponentRule3; -import org.warp.picalculator.math.rules.ExponentRule4; -import org.warp.picalculator.math.rules.ExponentRule9; -import org.warp.picalculator.math.rules.FractionsRule4; -import org.warp.picalculator.math.rules.FractionsRule5; -import org.warp.picalculator.math.rules.UndefinedRule1; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -24,63 +16,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) { @@ -97,13 +32,13 @@ public class Power extends FunctionOperator { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); - ObjectArrayList sub1 = getParameter1().toBlock(context); - ObjectArrayList sub2 = getParameter2().toBlock(context); - BlockPower bp = new BlockPower(); - BlockContainer ec = bp.getExponentContainer(); + final ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList sub1 = getParameter1().toBlock(context); + final ObjectArrayList sub2 = getParameter2().toBlock(context); + final BlockPower bp = new BlockPower(); + final BlockContainer ec = bp.getExponentContainer(); result.addAll(sub1); - for (Block b : sub2) { + for (final Block b : sub2) { ec.appendBlockUnsafe(b); } ec.recomputeDimensions(); 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..d750f2ec 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Root.java +++ b/src/main/java/org/warp/picalculator/math/functions/Root.java @@ -1,8 +1,5 @@ package org.warp.picalculator.math.functions; -import java.math.BigDecimal; -import java.math.BigInteger; - import org.warp.picalculator.Error; import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; @@ -18,50 +15,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..f17e5eee 100755 --- a/src/main/java/org/warp/picalculator/math/functions/RootSquare.java +++ b/src/main/java/org/warp/picalculator/math/functions/RootSquare.java @@ -1,79 +1,41 @@ package org.warp.picalculator.math.functions; -import java.math.BigInteger; - import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockContainer; import org.warp.picalculator.gui.expression.blocks.BlockSquareRoot; import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.FunctionOperator; import org.warp.picalculator.math.MathContext; import it.unimi.dsi.fastutil.objects.ObjectArrayList; -public class RootSquare extends FunctionSingle { +public class RootSquare extends FunctionOperator { - public RootSquare(MathContext root, Function value) { - 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; + public RootSquare(MathContext root, Function value2) { + super(root, new Number(root, 2), value2); } @Override public boolean equals(Object o) { - if (o instanceof RootSquare) { - return ((RootSquare) o).getParameter().equals(parameter); + if (o instanceof Root) { + final FunctionOperator f = (FunctionOperator) o; + return parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2()); } return false; } @Override public RootSquare clone() { - return new RootSquare(mathContext, parameter); + return new RootSquare(mathContext, parameter2); } @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); - BlockSquareRoot bsqr = new BlockSquareRoot(); - BlockContainer bsqrc = bsqr.getNumberContainer(); - for (Block b : getParameter().toBlock(context)) { + final ObjectArrayList result = new ObjectArrayList<>(); + final BlockSquareRoot bsqr = new BlockSquareRoot(); + final BlockContainer bsqrc = bsqr.getNumberContainer(); + for (final Block b : getParameter2().toBlock(context)) { bsqrc.appendBlockUnsafe(b); } bsqrc.recomputeDimensions(); @@ -81,4 +43,5 @@ public class RootSquare extends FunctionSingle { result.add((bsqr)); return result; } + } 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..d552c05d 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Subtraction.java +++ b/src/main/java/org/warp/picalculator/math/functions/Subtraction.java @@ -7,14 +7,6 @@ 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.ExpandRule5; -import org.warp.picalculator.math.rules.NumberRule3; -import org.warp.picalculator.math.rules.NumberRule5; -import org.warp.picalculator.math.rules.VariableRule1; -import org.warp.picalculator.math.rules.VariableRule2; -import org.warp.picalculator.math.rules.VariableRule3; -import org.warp.picalculator.math.rules.methods.SumMethod1; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -24,63 +16,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) { @@ -97,7 +32,7 @@ public class Subtraction extends FunctionOperator { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList result = new ObjectArrayList<>(); result.addAll(getParameter1().toBlock(context)); result.add(new BlockChar(MathematicalSymbols.SUBTRACTION)); result.addAll(getParameter2().toBlock(context)); 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..5d6036cf 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Sum.java +++ b/src/main/java/org/warp/picalculator/math/functions/Sum.java @@ -1,23 +1,12 @@ package org.warp.picalculator.math.functions; -import java.math.BigDecimal; - import org.warp.picalculator.Error; -import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockChar; import org.warp.picalculator.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.NumberRule3; -import org.warp.picalculator.math.rules.NumberRule5; -import org.warp.picalculator.math.rules.NumberRule7; -import org.warp.picalculator.math.rules.VariableRule1; -import org.warp.picalculator.math.rules.VariableRule2; -import org.warp.picalculator.math.rules.VariableRule3; -import org.warp.picalculator.math.rules.methods.SumMethod1; - import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class Sum extends FunctionOperator { @@ -26,73 +15,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) { @@ -113,7 +35,7 @@ public class Sum extends FunctionOperator { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList result = new ObjectArrayList<>(); result.addAll(getParameter1().toBlock(context)); result.add(new BlockChar(MathematicalSymbols.SUM)); result.addAll(getParameter2().toBlock(context)); 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..26f911cf 100755 --- a/src/main/java/org/warp/picalculator/math/functions/SumSubtraction.java +++ b/src/main/java/org/warp/picalculator/math/functions/SumSubtraction.java @@ -1,17 +1,12 @@ package org.warp.picalculator.math.functions; import org.warp.picalculator.Error; -import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockChar; import org.warp.picalculator.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.NumberRule3; -import org.warp.picalculator.math.rules.NumberRule4; -import org.warp.picalculator.math.rules.NumberRule5; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -21,47 +16,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) { @@ -78,7 +32,7 @@ public class SumSubtraction extends FunctionOperator { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList result = new ObjectArrayList<>(); result.addAll(getParameter1().toBlock(context)); result.add(new BlockChar(MathematicalSymbols.SUM_SUBTRACTION)); result.addAll(getParameter2().toBlock(context)); 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..0ced4634 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Undefined.java +++ b/src/main/java/org/warp/picalculator/math/functions/Undefined.java @@ -1,12 +1,11 @@ package org.warp.picalculator.math.functions; -import java.util.List; - import org.warp.picalculator.Error; -import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; +import org.warp.picalculator.gui.expression.blocks.BlockUndefined; 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 +18,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, InterruptedException { + return rule.execute(this); } @Override @@ -35,9 +29,6 @@ public class Undefined implements Function { @Override public boolean equals(Object o) { - if (o instanceof Undefined) { - return true; - } return false; } @@ -57,9 +48,15 @@ public class Undefined implements Function { } @Override - public ObjectArrayList toBlock(MathContext context) throws Error { - // TODO Auto-generated method stub - throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + getClass().getSimpleName()); + public ObjectArrayList toBlock(MathContext context) { + final ObjectArrayList result = new ObjectArrayList<>(); + result.add(new BlockUndefined()); + return result; + } + + @Override + public String toString() { + return "UNDEFINED"; } } diff --git a/src/main/java/org/warp/picalculator/math/functions/Variable.java b/src/main/java/org/warp/picalculator/math/functions/Variable.java index 5b2df76f..2b422ebf 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Variable.java +++ b/src/main/java/org/warp/picalculator/math/functions/Variable.java @@ -1,15 +1,11 @@ package org.warp.picalculator.math.functions; -import java.util.List; - -import org.nevec.rjm.BigDecimalMath; import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockChar; 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; @@ -61,26 +57,8 @@ public class Variable implements Function { } @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, InterruptedException { + return rule.execute(this); } @Override @@ -122,7 +100,7 @@ public class Variable implements Function { @Override public ObjectArrayList toBlock(MathContext context) { - ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList result = new ObjectArrayList<>(); //TODO: Temporary solution. In near future Variables will be distint objects and they will have a color. So they will be no longer a BlockChar/FeatureChar result.add(new BlockChar(getChar())); return result; 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..5116a648 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 @@ -1,19 +1,15 @@ package org.warp.picalculator.math.functions.equations; -import java.math.BigDecimal; import java.util.HashSet; import java.util.List; import java.util.Set; import org.warp.picalculator.Error; -import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionOperator; import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.SolveMethod; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.solver.SolveMethod; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -23,33 +19,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..87cfd698 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 @@ -1,15 +1,10 @@ package org.warp.picalculator.math.functions.equations; -import java.util.List; - import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionDynamic; import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Number; - import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class EquationsSystem extends FunctionDynamic { @@ -27,45 +22,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..5f98a612 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 @@ -2,7 +2,6 @@ package org.warp.picalculator.math.functions.equations; import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; -import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionSingle; import org.warp.picalculator.math.MathContext; @@ -14,18 +13,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..58077c8d 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 @@ -1,16 +1,12 @@ package org.warp.picalculator.math.functions.trigonometry; -import org.nevec.rjm.BigDecimalMath; import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockContainer; import org.warp.picalculator.gui.expression.blocks.BlockSine; -import org.warp.picalculator.math.AngleMode; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionSingle; import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Number; - import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class Sine extends FunctionSingle { @@ -19,31 +15,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) { @@ -62,11 +33,11 @@ public class Sine extends FunctionSingle { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - ObjectArrayList result = new ObjectArrayList<>(); - ObjectArrayList sub = getParameter(0).toBlock(context); - BlockSine bs = new BlockSine(); - BlockContainer bpc = bs.getNumberContainer(); - for (Block b : sub) { + final ObjectArrayList result = new ObjectArrayList<>(); + final ObjectArrayList sub = getParameter(0).toBlock(context); + final BlockSine bs = new BlockSine(); + final BlockContainer bpc = bs.getNumberContainer(); + for (final Block b : sub) { bpc.appendBlockUnsafe(b); } bpc.recomputeDimensions(); 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/parser/MathParser.java b/src/main/java/org/warp/picalculator/math/parser/MathParser.java index b74182ec..e669a7f2 100755 --- a/src/main/java/org/warp/picalculator/math/parser/MathParser.java +++ b/src/main/java/org/warp/picalculator/math/parser/MathParser.java @@ -1,10 +1,10 @@ package org.warp.picalculator.math.parser; +import org.warp.picalculator.ConsoleUtils; import org.warp.picalculator.Error; import org.warp.picalculator.Errors; import org.warp.picalculator.IntegerObj; import org.warp.picalculator.StaticVars; -import org.warp.picalculator.Utils; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.containers.InputContainer; import org.warp.picalculator.math.Function; @@ -45,10 +45,11 @@ public class MathParser { public static ObjectArrayList> parseOutput(MathContext context, ObjectArrayList resultExpressions) throws Error { final ObjectArrayList> result = new ObjectArrayList<>(); - for (Function resultExpression : resultExpressions) { - ObjectArrayList resultBlocks = resultExpression.toBlock(context); - if (resultBlocks == null) + for (final Function resultExpression : resultExpressions) { + final ObjectArrayList resultBlocks = resultExpression.toBlock(context); + if (resultBlocks == null) { throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + resultExpression.getClass().getSimpleName()); + } result.add(resultBlocks); } return result; @@ -61,9 +62,10 @@ public class MathParser { ObjectArrayList process = new ObjectArrayList<>(); for (final Feature f : features) { - Function fnc = f.toFunction(context); - if (fnc == null) + final Function fnc = f.toFunction(context); + if (fnc == null) { throw new Error(Errors.SYNTAX_ERROR, "\"" + f.getClass().getSimpleName() + "\" can't be converted into a Function!"); + } process.add(fnc); } @@ -78,35 +80,28 @@ public class MathParser { private static ObjectArrayList fixStack(MathContext context, ObjectArrayList functionsList) throws Error { - final MathParserStep[] steps = new MathParserStep[] { - new JoinNumberAndVariables(context), - new FixSingleFunctionArgs(), - new RemoveParentheses(context), - 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; if (StaticVars.debugOn) { - Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: "); - for (Function f : functionsList) { - Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, f.toString()); + ConsoleUtils.out.print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "\tStatus: "); + for (final Function f : functionsList) { + ConsoleUtils.out.print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, f.toString()); } - Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MAX); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE); } - for (MathParserStep step : steps) { + for (final MathParserStep step : steps) { if (StaticVars.debugOn) { - Utils.out.println(2, "Stack fixing step \"" + step.getStepName() + "\""); + ConsoleUtils.out.println(2, "Stack fixing step \"" + step.getStepName() + "\""); } - int stepQty = step.requiresReversedIteration() ? -1 : 1, + final int stepQty = step.requiresReversedIteration() ? -1 : 1, initialIndex = step.requiresReversedIteration() ? functionsList.size() - 1 : 0; do { lastLoopDidSomething = false; lastElement = null; - IntegerObj curIndex = new IntegerObj(initialIndex); + final IntegerObj curIndex = new IntegerObj(initialIndex); while (curIndex.i >= 0 && curIndex.i < functionsList.size()) { final int i = curIndex.i; final Function f = functionsList.get(i); @@ -121,11 +116,11 @@ public class MathParser { } while (lastLoopDidSomething); if (StaticVars.debugOn) { - Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: "); - for (Function f : functionsList) { - Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, f.toString()); + ConsoleUtils.out.print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "\tStatus: "); + for (final Function f : functionsList) { + ConsoleUtils.out.print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, f.toString()); } - Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MAX); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE); } } @@ -192,7 +187,7 @@ public class MathParser { break; } - for (char var : MathematicalSymbols.variables) { + for (final char var : MathematicalSymbols.variables) { if (featureChar == var) { result = new FeatureVariable(featureChar, V_TYPE.VARIABLE); break; diff --git a/src/main/java/org/warp/picalculator/math/parser/features/FeatureLogarithm.java b/src/main/java/org/warp/picalculator/math/parser/features/FeatureLogarithm.java new file mode 100644 index 00000000..b3472bcd --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/parser/features/FeatureLogarithm.java @@ -0,0 +1,18 @@ +package org.warp.picalculator.math.parser.features; + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Logarithm; + +public class FeatureLogarithm extends FeatureDoubleImpl { + + public FeatureLogarithm(Object child1, Object child2) { + super(child1, child2); + } + + @Override + public Logarithm toFunction(MathContext context) throws Error { + return new Logarithm(context, getFunction1(), getFunction2()); + } + +} diff --git a/src/main/java/org/warp/picalculator/math/parser/features/FeatureParenthesis.java b/src/main/java/org/warp/picalculator/math/parser/features/FeatureParenthesis.java index f6198ea9..37234b9d 100755 --- a/src/main/java/org/warp/picalculator/math/parser/features/FeatureParenthesis.java +++ b/src/main/java/org/warp/picalculator/math/parser/features/FeatureParenthesis.java @@ -13,7 +13,7 @@ public class FeatureParenthesis extends FeatureSingleImpl { @Override public Function toFunction(MathContext context) throws Error { - return new Expression(context, this.getFunction1()); + return new Expression(context, getFunction1()); } } diff --git a/src/main/java/org/warp/picalculator/math/parser/features/FeatureSine.java b/src/main/java/org/warp/picalculator/math/parser/features/FeatureSine.java index 5c8e22c9..e9e79bd6 100644 --- a/src/main/java/org/warp/picalculator/math/parser/features/FeatureSine.java +++ b/src/main/java/org/warp/picalculator/math/parser/features/FeatureSine.java @@ -13,7 +13,7 @@ public class FeatureSine extends FeatureSingleImpl { @Override public Function toFunction(MathContext context) throws Error { - return new Sine(context, this.getFunction1()); + return new Sine(context, getFunction1()); } } diff --git a/src/main/java/org/warp/picalculator/math/parser/steps/AddImplicitMultiplications.java b/src/main/java/org/warp/picalculator/math/parser/steps/AddImplicitMultiplications.java index 94e7bea4..185f1a76 100644 --- a/src/main/java/org/warp/picalculator/math/parser/steps/AddImplicitMultiplications.java +++ b/src/main/java/org/warp/picalculator/math/parser/steps/AddImplicitMultiplications.java @@ -2,7 +2,6 @@ package org.warp.picalculator.math.parser.steps; import org.warp.picalculator.IntegerObj; import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionSingle; import org.warp.picalculator.math.MathContext; import org.warp.picalculator.math.functions.Multiplication; import org.warp.picalculator.math.parser.MathParserStep; @@ -11,7 +10,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class AddImplicitMultiplications implements MathParserStep { - private MathContext context; + private final MathContext context; public AddImplicitMultiplications(MathContext context) { this.context = context; diff --git a/src/main/java/org/warp/picalculator/math/parser/steps/JoinNumberAndVariables.java b/src/main/java/org/warp/picalculator/math/parser/steps/JoinNumberAndVariables.java index f35b5fdc..db1fd56b 100644 --- a/src/main/java/org/warp/picalculator/math/parser/steps/JoinNumberAndVariables.java +++ b/src/main/java/org/warp/picalculator/math/parser/steps/JoinNumberAndVariables.java @@ -13,14 +13,15 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class JoinNumberAndVariables implements MathParserStep { - private MathContext context; + private final MathContext context; public JoinNumberAndVariables(MathContext context) { this.context = context; } @Override - public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList functionsList) { + public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, + ObjectArrayList 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; diff --git a/src/main/java/org/warp/picalculator/math/parser/steps/RemoveParentheses.java b/src/main/java/org/warp/picalculator/math/parser/steps/RemoveParentheses.java index 781b8e3f..bfce5828 100644 --- a/src/main/java/org/warp/picalculator/math/parser/steps/RemoveParentheses.java +++ b/src/main/java/org/warp/picalculator/math/parser/steps/RemoveParentheses.java @@ -10,19 +10,20 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class RemoveParentheses implements MathParserStep { - private MathContext context; + private final MathContext context; public RemoveParentheses(MathContext context) { this.context = context; } @Override - public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList functionsList) { + public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, + ObjectArrayList functionsList) { if (currentFunction instanceof Expression) { - if (((Expression)currentFunction).getParameter() == null) { + if (((Expression) currentFunction).getParameter() == null) { functionsList.remove(curIndex.i); } else { - functionsList.set(curIndex.i, ((Expression)currentFunction).getParameter()); + functionsList.set(curIndex.i, ((Expression) currentFunction).getParameter()); } return true; } diff --git a/src/main/java/org/warp/picalculator/math/rules/ExpandRule1.java b/src/main/java/org/warp/picalculator/math/rules/ExpandRule1.java deleted file mode 100755 index acbe6f62..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExpandRule1.java +++ /dev/null @@ -1,114 +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.Number; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; -import org.warp.picalculator.math.functions.SumSubtraction; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Expand rule
- * -(+a+b) = -a-b
- * -(+a-b) = -a+b - * - * @author Andrea Cavalli - * - */ -public class ExpandRule1 { - - public static boolean compare(Function f) { - 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 instanceof Subtraction) { - return true; - } else if (expr instanceof SumSubtraction) { - return true; - } - } - } else if (f instanceof Subtraction || f instanceof SumSubtraction) { - final FunctionOperator fnc = (FunctionOperator) f; - 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; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final MathContext root = f.getMathContext(); - - Function expr = null; - int fromSubtraction = 0; - FunctionOperator subtraction = null; - if (f instanceof Multiplication) { - expr = ((Multiplication) f).getParameter2(); - } else if (f instanceof Subtraction || f instanceof SumSubtraction) { - expr = ((FunctionOperator) f).getParameter2(); - if (f instanceof Subtraction) { - fromSubtraction = 1; - } else { - fromSubtraction = 2; - } - } - - if (f instanceof SumSubtraction) { - - } - - 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 Multiplication(root, new Number(root, -1), a), b); - if (fromSubtraction > 0) { - subtraction = new Subtraction(root, ((FunctionOperator) f).getParameter1(), fnc2); - result.add(subtraction); - } else { - result.add(fnc2); - } - } else if (fnc instanceof Subtraction) { - final Function a = ((Subtraction) fnc).getParameter1(); - final Function b = ((Subtraction) fnc).getParameter2(); - 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); - } else { - result.add(fnc2); - } - } else if (fnc instanceof SumSubtraction) { - final Function a = ((SumSubtraction) fnc).getParameter1(); - final Function b = ((SumSubtraction) fnc).getParameter2(); - 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); - subtraction = new SumSubtraction(root, ((FunctionOperator) f).getParameter1(), fnc3); - result.add(subtraction); - result.add(subtraction); - } else { - result.add(fnc2); - result.add(fnc2); - } - } - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExpandRule2.java b/src/main/java/org/warp/picalculator/math/rules/ExpandRule2.java deleted file mode 100644 index 336268e2..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExpandRule2.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.Errors; -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.Number; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; -import org.warp.picalculator.math.functions.SumSubtraction; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Expand rule
- * a(b+c) = ab+ac - * - * @author Andrea Cavalli - * - */ -public class ExpandRule2 { - - public static boolean compare(Function f) { - if (f instanceof Multiplication) { - final Multiplication fnc = (Multiplication) f; - if (fnc.getParameter1() instanceof Sum) { - return true; - } else if (fnc.getParameter2() instanceof Sum) { - return true; - } else { - return false; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final MathContext root = f.getMathContext(); - - final Multiplication fnc = (Multiplication) f; - final Sum sum; - final Function a; - if (fnc.getParameter1() instanceof Sum) { - sum = (Sum) fnc.getParameter1(); - a = fnc.getParameter2(); - } else if (fnc.getParameter2() instanceof Sum) { - sum = (Sum) fnc.getParameter2(); - a = fnc.getParameter1(); - } else { - throw new Error(Errors.UNBALANCED_STACK); - } - - final Function b = sum.getParameter1(); - final Function c = sum.getParameter2(); - final Multiplication ab = new Multiplication(root, a, b); - final Multiplication ac = new Multiplication(root, a, c); - result.add(new Sum(root, ab, ac)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExpandRule5.java b/src/main/java/org/warp/picalculator/math/rules/ExpandRule5.java deleted file mode 100755 index 045f573c..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExpandRule5.java +++ /dev/null @@ -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.functions.Expression; -import org.warp.picalculator.math.functions.Negative; -import org.warp.picalculator.math.functions.Subtraction; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Expand rule
- * -(-a) = a - * - * @author Andrea Cavalli - * - */ -public class ExpandRule5 { - - public static boolean compare(Function f) { - if (f instanceof Negative) { - final Negative fnc = (Negative) f; - if (fnc.getParameter() instanceof Expression) { - final Expression e = (Expression) fnc.getParameter(); - return e.getParameter() instanceof Negative; - } - } else if (f instanceof Subtraction) { - final Subtraction fnc = (Subtraction) f; - if (fnc.getParameter2() instanceof Expression) { - final Expression e = (Expression) fnc.getParameter2(); - return e.getParameter() instanceof Negative; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - - if (f instanceof Negative) { - final Negative fnc = (Negative) f; - result.add(((Negative) ((Expression) fnc.getParameter()).getParameter()).getParameter()); - } else if (f instanceof Subtraction) { - final Subtraction fnc = (Subtraction) f; - result.add(((Negative) ((Expression) fnc.getParameter2()).getParameter()).getParameter()); - } - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExponentRule1.java b/src/main/java/org/warp/picalculator/math/rules/ExponentRule1.java deleted file mode 100755 index bdafd7eb..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExponentRule1.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Exponent rule
- * 1^a=1 - * - * @author Andrea Cavalli - * - */ -public class ExponentRule1 { - - public static boolean compare(Function f) { - final Power fnc = (Power) f; - final MathContext root = f.getMathContext(); - if (fnc.getParameter1().equals(new Number(root, 1))) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Number(root, 1)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExponentRule15.java b/src/main/java/org/warp/picalculator/math/rules/ExponentRule15.java deleted file mode 100755 index 926194be..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExponentRule15.java +++ /dev/null @@ -1,42 +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.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Exponent rule
- * a*a=a^2 - * - * @author Andrea Cavalli - * - */ -public class ExponentRule15 { - - public static boolean compare(Function f) { - final Multiplication fnc = (Multiplication) f; - if (fnc.getParameter1().equals(fnc.getParameter2())) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication fnc = (Multiplication) f; - final Function a = fnc.getParameter1(); - final Expression expr = new Expression(root, a); - final Number two = new Number(root, 2); - final Power p = new Power(root, expr, two); - result.add(p); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExponentRule16.java b/src/main/java/org/warp/picalculator/math/rules/ExponentRule16.java deleted file mode 100755 index 0dd2fd84..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExponentRule16.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Exponent rule
- * (a ^ b) * (a ^ c) = a ^ (b + c) - * - * @author Andrea Cavalli - * - */ -public class ExponentRule16 { - - public static boolean compare(Function f) { - final Multiplication fnc = (Multiplication) f; - if (fnc.getParameter1() instanceof Power && fnc.getParameter2() instanceof Power) { - return ((Power) fnc.getParameter1()).getParameter1().equals(((Power) fnc.getParameter2()).getParameter1()); - } else if (fnc.getParameter1() instanceof Power) { - return ((Power) fnc.getParameter1()).getParameter1().equals(fnc.getParameter2()); - } else if (fnc.getParameter2() instanceof Power) { - return ((Power) fnc.getParameter2()).getParameter1().equals(fnc.getParameter1()); - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication fnc = (Multiplication) f; - 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, 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, fnc.getParameter1(), new Sum(root, new Number(root, 1), new Expression(root, ((Power) fnc.getParameter2()).getParameter2())))); - } - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExponentRule17.java b/src/main/java/org/warp/picalculator/math/rules/ExponentRule17.java deleted file mode 100755 index 0ec1fb49..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExponentRule17.java +++ /dev/null @@ -1,45 +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.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; -import org.warp.picalculator.math.functions.Root; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Exponent rule
- * a√x=x^1/a - * - * @author Andrea Cavalli - * - */ -public class ExponentRule17 { - - public static boolean compare(Function f) { - if (f instanceof Root) { - final Root fnc = (Root) f; - if (fnc.getParameter1().equals(fnc.getParameter2())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication fnc = (Multiplication) f; - final Function a = fnc.getParameter1(); - final Expression expr = new Expression(root, a); - final Number two = new Number(root, 2); - final Power p = new Power(fnc.getMathContext(), expr, two); - result.add(p); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExponentRule2.java b/src/main/java/org/warp/picalculator/math/rules/ExponentRule2.java deleted file mode 100755 index ce026078..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExponentRule2.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Exponent rule
- * a^1=a - * - * @author Andrea Cavalli - * - */ -public class ExponentRule2 { - - public static boolean compare(Function f) { - final Power fnc = (Power) f; - if (fnc.getParameter2().equals(new Number(f.getMathContext(), 1))) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(((Power) f).getParameter1()); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExponentRule3.java b/src/main/java/org/warp/picalculator/math/rules/ExponentRule3.java deleted file mode 100755 index bc29e18f..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExponentRule3.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Exponent rule
- * a^0=1 - * - * @author Andrea Cavalli - * - */ -public class ExponentRule3 { - - public static boolean compare(Function f) { - final Power fnc = (Power) f; - if (fnc.getParameter2().equals(new Number(f.getMathContext(), 0))) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Number(f.getMathContext(), 1)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExponentRule4.java b/src/main/java/org/warp/picalculator/math/rules/ExponentRule4.java deleted file mode 100755 index de13cece..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExponentRule4.java +++ /dev/null @@ -1,48 +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.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Exponent rule
- * (a*b)^n=a^n*b^n - * - * @author Andrea Cavalli - * - */ -public class ExponentRule4 { - - public static boolean compare(Function f) { - final Power fnc = (Power) f; - if (fnc.getParameter1() instanceof Expression && ((Expression) fnc.getParameter1()).getParameter() instanceof Multiplication && fnc.getParameter2() instanceof Number) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Power fnc = (Power) f; - final Expression expr = (Expression) fnc.getParameter1(); - final Multiplication mult = (Multiplication) expr.getParameter(); - final Function a = mult.getParameter1(); - final Function b = mult.getParameter2(); - final Number n = (Number) fnc.getParameter2(); - final Expression e1 = new Expression(root, a); - final Power p1 = new Power(root, e1, n); - final Expression e2 = new Expression(root, b); - final Power p2 = new Power(root, e2, n); - final Multiplication retMult = new Multiplication(root, p1, p2); - result.add(retMult); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/ExponentRule9.java b/src/main/java/org/warp/picalculator/math/rules/ExponentRule9.java deleted file mode 100755 index fad60d1f..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/ExponentRule9.java +++ /dev/null @@ -1,39 +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.Multiplication; -import org.warp.picalculator.math.functions.Power; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Exponent rule
- * (a ^ b) ^ c = a ^ (b * c) - * - * @author Andrea Cavalli - * - */ -public class ExponentRule9 { - - public static boolean compare(Function f) { - final Power fnc = (Power) f; - if (fnc.getParameter1() instanceof Power) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Power powC = (Power) f; - final Power powB = (Power) powC.getParameter1(); - final Power p = new Power(root, powB.getParameter1(), new Multiplication(root, new Expression(root, powB.getParameter2()), new Expression(root, powC.getParameter2()))); - result.add(p); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule1.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule1.java deleted file mode 100755 index a9bf6a18..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule1.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * 0 / a = 0 - * - * @author Andrea Cavalli - * - */ -public class FractionsRule1 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Division fnc = (Division) f; - if (fnc.getParameter1() instanceof Number) { - final Number numb1 = (Number) fnc.getParameter1(); - if (numb1.equals(new Number(root, 0))) { - if (fnc.getParameter2() instanceof Number) { - final Number numb2 = (Number) fnc.getParameter2(); - if (numb2.equals(new Number(root, 0))) { - return false; - } - } - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Number(f.getMathContext(), 0)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule11.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule11.java deleted file mode 100755 index f827f0f6..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule11.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * a / (b / c) = (a * c) / b - * - * @author Andrea Cavalli - * - */ -public class FractionsRule11 { - - public static boolean compare(Function f) throws InterruptedException { - final Division fnc = (Division) f; - Function a; - Function c; - Division div2; - if (fnc.getParameter2() instanceof Division) { - div2 = (Division) fnc.getParameter2(); - } else { - return false; - } - a = fnc.getParameter1(); - c = div2.getParameter2(); - return new Multiplication(fnc.getMathContext(), a, c).isSimplified() == false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final Division fnc = (Division) f; - Function a; - Function b; - Function c; - - final Division div2 = (Division) fnc.getParameter2(); - - a = fnc.getParameter1(); - b = div2.getParameter1(); - c = div2.getParameter2(); - result.add(new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), b)); - - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java deleted file mode 100755 index 3426b5ed..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule12.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * (b / c) / a = b / (a * c) - * - * @author Andrea Cavalli - * - */ -public class FractionsRule12 { - - public static boolean compare(Function f) throws InterruptedException { - final Division fnc = (Division) f; - Function a; - Function c; - if (fnc.getParameter1() instanceof Division) { - final Division div2 = (Division) fnc.getParameter1(); - a = fnc.getParameter1(); - c = div2.getParameter2(); - return new Multiplication(fnc.getMathContext(), a, c).isSimplified() == false; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final Division fnc = (Division) f; - Function a; - Function b; - Function c; - - final Division div2 = (Division) fnc.getParameter1(); - a = fnc.getParameter2(); - b = div2.getParameter1(); - c = div2.getParameter2(); - result.add(new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), b)); - - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java deleted file mode 100755 index 49ad6bfc..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Multiplication; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * (a / b) * (c / d) = (a * c) / (b * d) - * - * @author Andrea Cavalli - * - */ -public class FractionsRule14 { - - public static boolean compare(Function f) throws InterruptedException { - final Multiplication fnc = (Multiplication) f; - Function a; - Function b; - Function c; - Function d; - if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Division) { - final Division div1 = (Division) fnc.getParameter1(); - final Division div2 = (Division) fnc.getParameter2(); - a = div1.getParameter1(); - b = div1.getParameter2(); - c = div2.getParameter1(); - d = div2.getParameter2(); - return new Multiplication(f.getMathContext(), a, c).isSimplified() == false || 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; - } 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 false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication fnc = (Multiplication) f; - Function a; - Function b; - Function c; - Function d; - - if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Division) { - final Division div1 = (Division) fnc.getParameter1(); - final Division div2 = (Division) fnc.getParameter2(); - a = div1.getParameter1(); - b = div1.getParameter2(); - c = div2.getParameter1(); - d = div2.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), new Multiplication(fnc.getMathContext(), b, d)); - result.add(div); - } else if (fnc.getParameter1() instanceof Division) { - final Division div1 = (Division) fnc.getParameter1(); - a = div1.getParameter1(); - b = div1.getParameter2(); - c = fnc.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), b); - result.add(div); - } else if (fnc.getParameter2() instanceof Division) { - final Division div2 = (Division) fnc.getParameter2(); - a = fnc.getParameter1(); - c = div2.getParameter1(); - d = div2.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), d); - result.add(div); - } - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule2.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule2.java deleted file mode 100755 index 8c32b510..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule2.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * a / 1 = a - * - * @author Andrea Cavalli - * - */ -public class FractionsRule2 { - - public static boolean compare(Function f) { - final Division fnc = (Division) f; - if (fnc.getParameter2() instanceof Number) { - final Number numb = (Number) fnc.getParameter2(); - if (numb.equals(new Number(f.getMathContext(), 1))) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final Division fnc = (Division) f; - result.add(fnc.getParameter1()); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule3.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule3.java deleted file mode 100755 index b5782332..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule3.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * a / a = 1 - * - * @author Andrea Cavalli - * - */ -public class FractionsRule3 { - - public static boolean compare(Function f) { - final Division fnc = (Division) f; - if (fnc.getParameter1().equals(fnc.getParameter2())) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Number(f.getMathContext(), 1)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule4.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule4.java deleted file mode 100755 index cd0fc30d..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule4.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * (a / b) ^ -1 = b / a - * - * @author Andrea Cavalli - * - */ -public class FractionsRule4 { - - public static boolean compare(Function f) { - final Power fnc = (Power) f; - if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Number) { - final Number n2 = (Number) fnc.getParameter2(); - if (n2.equals(new Number(f.getMathContext(), -1))) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - final Power fnc = (Power) f; - final Function a = ((Division) fnc.getParameter1()).getParameter1(); - final Function b = ((Division) fnc.getParameter1()).getParameter2(); - final Division res = new Division(f.getMathContext(), b, a); - result.add(res); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule5.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule5.java deleted file mode 100755 index 0b707d7a..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule5.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.warp.picalculator.math.rules; - -import java.math.BigDecimal; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Fractions rule
- * (a / b) ^ -c = (b / a) ^ c - * - * @author Andrea Cavalli - * - */ -public class FractionsRule5 { - - public static boolean compare(Function f) { - final Power fnc = (Power) f; - if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Number) { - final Number n2 = (Number) fnc.getParameter2(); - if (n2.getTerm().compareTo(BigDecimal.ZERO) < 0) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Power fnc = (Power) f; - final Function a = ((Division) fnc.getParameter1()).getParameter1(); - final Function b = ((Division) fnc.getParameter1()).getParameter2(); - final Function c = ((Number) fnc.getParameter2()).multiply(new Number(root, "-1")); - final Division dv = new Division(root, b, a); - final Power pow = new Power(root, dv, c); - result.add(pow); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule1.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule1.java deleted file mode 100755 index 29cf7029..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule1.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a * 0 = 0 - * - * @author Andrea Cavalli - * - */ -public class NumberRule1 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Multiplication mult = (Multiplication) f; - if (mult.getParameter1() instanceof Number) { - final Number numb = (Number) mult.getParameter1(); - if (numb.equals(new Number(root, 0))) { - return true; - } - } - if (mult.getParameter2() instanceof Number) { - final Number numb = (Number) mult.getParameter2(); - if (numb.equals(new Number(root, 0))) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Number(f.getMathContext(), "0")); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule2.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule2.java deleted file mode 100755 index 817fadb0..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule2.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a * 1 = a - * - * @author Andrea Cavalli - * - */ -public class NumberRule2 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Multiplication mult = (Multiplication) f; - if (mult.getParameter1() instanceof Number) { - final Number numb = (Number) mult.getParameter1(); - if (numb.equals(new Number(root, 1))) { - return true; - } - } - if (mult.getParameter2() instanceof Number) { - final Number numb = (Number) mult.getParameter2(); - if (numb.equals(new Number(root, 1))) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - Function a = null; - boolean aFound = false; - final Multiplication mult = (Multiplication) f; - if (aFound == false & mult.getParameter1() instanceof Number) { - final Number numb = (Number) mult.getParameter1(); - if (numb.equals(new Number(root, 1))) { - a = mult.getParameter2(); - aFound = true; - } - } - if (aFound == false && mult.getParameter2() instanceof Number) { - final Number numb = (Number) mult.getParameter2(); - if (numb.equals(new Number(root, 1))) { - a = mult.getParameter1(); - aFound = true; - } - } - - result.add(a); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule3.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule3.java deleted file mode 100755 index edc8a816..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule3.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Negative; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; -import org.warp.picalculator.math.functions.SumSubtraction; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a - a = 0
- * -a + a = 0
- * a ± a = {0, 2a} - * - * @author Andrea Cavalli - * - */ -public class NumberRule3 { - - public static boolean compare(Function f) { - if (f instanceof Subtraction) { - final Subtraction sub = (Subtraction) f; - if (sub.getParameter1().equals(sub.getParameter2())) { - return true; - } - } else if (f instanceof Sum) { - final Sum sub = (Sum) f; - if (sub.getParameter1() instanceof Negative) { - final Negative neg = (Negative) sub.getParameter1(); - if (neg.getParameter().equals(sub.getParameter2())) { - return true; - } - } - } else if (f instanceof SumSubtraction) { - final SumSubtraction sub = (SumSubtraction) f; - if (sub.getParameter1().equals(sub.getParameter2())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - if (f instanceof SumSubtraction) { - final Multiplication mul = new Multiplication(root, new Number(root, 2), ((SumSubtraction) f).getParameter1()); - result.add(mul); - } - result.add(new Number(root, 0)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule4.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule4.java deleted file mode 100755 index c90ffbb9..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule4.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; -import org.warp.picalculator.math.functions.SumSubtraction; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a ± b = {a+b, a-b} - * - * @author Andrea Cavalli - * - */ -public class NumberRule4 { - - public static boolean compare(Function f) { - if (f instanceof SumSubtraction) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final SumSubtraction ss = (SumSubtraction) f; - result.add(new Sum(root, ss.getParameter1(), ss.getParameter2())); - result.add(new Subtraction(root, ss.getParameter1(), ss.getParameter2())); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule5.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule5.java deleted file mode 100755 index 5874f46e..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule5.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionOperator; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Number; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a + 0 = a
- * 0 + a = a
- * a - 0 = a
- * 0 - a = a
- * a ± 0 = a
- * 0 ± a = a - * - * @author Andrea Cavalli - * - */ -public class NumberRule5 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final FunctionOperator fnc = (FunctionOperator) f; - if (fnc.getParameter1().equals(new Number(root, 0)) || fnc.getParameter2().equals(new Number(root, 0))) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final FunctionOperator fnc = (FunctionOperator) f; - Function a = fnc.getParameter1(); - if (a.equals(new Number(root, 0))) { - a = fnc.getParameter2(); - } - result.add(a); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/NumberRule7.java b/src/main/java/org/warp/picalculator/math/rules/NumberRule7.java deleted file mode 100755 index 3fc042a5..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/NumberRule7.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Number rule
- * a + a = 2a - * - * @author Andrea Cavalli - * - */ -public class NumberRule7 { - - public static boolean compare(Sum f) { - return f.getParameter1().equals(f.getParameter2()); - } - - public static ObjectArrayList execute(Sum f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication mult = new Multiplication(root, new Number(root, 2), f.getParameter1()); - result.add(mult); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/Rule.java b/src/main/java/org/warp/picalculator/math/rules/Rule.java new file mode 100644 index 00000000..d861a67a --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/rules/Rule.java @@ -0,0 +1,46 @@ +package org.warp.picalculator.math.rules; + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import jdk.nashorn.internal.objects.annotations.SpecializedFunction; + +/** + * Rule interface + * + * @author Andrea Cavalli + * + */ +public interface Rule { + /** + * Get rule name + * + * @return + */ + public default String getRuleName() { + return "UnnamedRule1"; + } + + /** + * Get rule type + * + * @return + */ + @SpecializedFunction + public RuleType getRuleType(); + + /** + * + * @param func + * @return + *
    + *
  • null if it's not executable on the function + * func
  • + *
  • An ObjectArrayList<Function> if it did + * something
  • + *
+ * @throws Error + */ + public ObjectArrayList execute(Function func) throws Error, InterruptedException; +} \ 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..ce6341c7 --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/rules/RuleType.java @@ -0,0 +1,22 @@ +package org.warp.picalculator.math.rules; + +public enum RuleType { + /** + * A rule that tries to factorize and group a polynomial expression into a + * shorter expression + */ + REDUCTION, + /** + * A rule that tries to transform an expression to a simple polynomial + * expression + */ + EXPANSION, + /** + * Calculation + */ + CALCULATION, + /** + * Existence + */ + EXISTENCE +} diff --git a/src/main/java/org/warp/picalculator/math/rules/RulesManager.java b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java new file mode 100644 index 00000000..c504ecc2 --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/rules/RulesManager.java @@ -0,0 +1,239 @@ +package org.warp.picalculator.math.rules; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import org.warp.picalculator.ConsoleUtils; +import org.warp.picalculator.Error; +import org.warp.picalculator.Utils; +import org.warp.picalculator.ZipUtils; +import org.warp.picalculator.deps.StorageUtils; +import org.warp.picalculator.deps.DJDTCompiler; +import org.warp.picalculator.deps.DSystem; +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.Variable; +import org.warp.picalculator.math.functions.Variable.V_TYPE; +import org.warp.picalculator.math.solver.MathSolver; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +public class RulesManager { + + public static ObjectArrayList[] rules; + + private RulesManager() {} + + @SuppressWarnings("unchecked") + public static void initialize() { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Loading the rules"); + rules = new ObjectArrayList[RuleType.values().length]; + for (final RuleType val : RuleType.values()) { + rules[val.ordinal()] = new ObjectArrayList<>(); + } + try { + boolean compiledSomething = false; + final Path defaultRulesPath = Utils.getResource("/default-rules.lst"); + if (!StorageUtils.exists(defaultRulesPath)) { + throw new FileNotFoundException("default-rules.lst not found!"); + } + final List ruleLines = new ArrayList<>(); + final Path rulesPath = StorageUtils.get("rules/"); + if (rulesPath.toFile().exists()) { + try (Stream paths = Files.walk(rulesPath)) { + paths.filter(Files::isRegularFile).forEach((Path p) -> { + if (p.toString().endsWith(".java")) { + String path = rulesPath.relativize(p).toString(); + path = path.substring(0, path.length() - ".java".length()); + ruleLines.add(path); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Found external rule: " + p.toAbsolutePath().toString()); + System.err.println(path); + } + }); + } + } + ruleLines.addAll(Files.readAllLines(defaultRulesPath)); + + boolean useCache = false; + final Path tDir = Paths.get(System.getProperty("java.io.tmpdir"), "WarpPi-Calculator").resolve("rules-rt"); +// try { +// final Path defaultResource = Utils.getResource("/math-rules-cache.zip"); +// } + final Path cacheFilePath = Utils.getResource("/math-rules-cache.zip");//Paths.get(Utils.getJarDirectory().toString()).resolve("math-rules-cache.zip").toAbsolutePath(); + if (cacheFilePath.toFile().exists()) { + try { + if (tDir.toFile().exists()) { + tDir.toFile().delete(); + } + ZipUtils.unzip(cacheFilePath.toString(), tDir.getParent().toString(), ""); + useCache = !Utils.debugCache; + } catch (final Exception ex) { + ex.printStackTrace(); + } + } + for (final String rulesLine : ruleLines) { + if (rulesLine.length() > 0) { + final String[] ruleDetails = rulesLine.split(",", 1); + final String ruleName = ruleDetails[0]; + final String ruleNameEscaped = ruleName.replace(".", "_"); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Evaluating /rules/" + ruleNameEscaped + ".java"); + final String pathWithoutExtension = "/rules/" + ruleNameEscaped; + final String scriptFile = pathWithoutExtension + ".java"; + final InputStream resourcePath = Utils.getResourceStream(scriptFile); + if (resourcePath == null) { + System.err.println(new FileNotFoundException("/rules/" + ruleName + ".java not found!")); + } else { + Rule r = null; + if (useCache) { + try { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "Trying to load cached rule"); + r = loadClassRuleFromSourceFile(scriptFile, tDir); + if (r != null) { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "Loaded cached rule"); + } + } catch (final Exception e) { + e.printStackTrace(); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", ruleName, "Can't load the rule!"); + } + } + if (r == null || !useCache) { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "This rule is not cached. Compiling"); + try { + r = compileJavaRule(scriptFile, tDir); + compiledSomething = true; + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IOException e) { + e.printStackTrace(); + } + + } + if (r != null) { + RulesManager.addRule(r); + } + } + } + } + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Loaded all the rules successfully"); + if (compiledSomething) { + if (cacheFilePath.toFile().exists()) { + cacheFilePath.toFile().delete(); + } + ZipUtils.zip(tDir.toString(), cacheFilePath.toString(), ""); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Cached the compiled rules"); + } + } catch (URISyntaxException | IOException e) { + e.printStackTrace(); + DSystem.exit(1); + } + } + + public static Rule compileJavaRule(String scriptFile, Path tDir) throws IOException, URISyntaxException, + InstantiationException, IllegalAccessException, ClassNotFoundException { + final InputStream resource = Utils.getResourceStream(scriptFile); + final String text = Utils.read(resource); + final String[] textArray = text.split("\\n", 5); + final String javaClassDeclaration = textArray[2].substring(6); + int extIndex = javaClassDeclaration.lastIndexOf('.'); + final String javaClassNameOnly = javaClassDeclaration.substring(extIndex + 1, javaClassDeclaration.length()); + final String javaClassNameAndPath = new StringBuilder("org.warp.picalculator.math.rules.").append(javaClassDeclaration).toString(); + extIndex = javaClassNameAndPath.lastIndexOf('.'); + final String javaCode = new StringBuilder("package ").append(javaClassNameAndPath.substring(0, extIndex >= 0 ? extIndex : javaClassNameAndPath.length())).append(";\n").append(textArray[4]).toString(); + final Path tDirPath = tDir.resolve(javaClassNameAndPath.replace('.', File.separatorChar)).getParent(); + final Path tFileJava = tDirPath.resolve(javaClassNameOnly + ".java"); + final Path tFileClass = tDirPath.resolve(javaClassNameOnly + ".class"); + if (!tDirPath.toFile().exists()) { + Files.createDirectories(tDirPath); + } + if (tFileJava.toFile().exists()) { + tFileJava.toFile().delete(); + } + Files.write(tFileJava, javaCode.getBytes("UTF-8"), StandardOpenOption.WRITE, StandardOpenOption.CREATE); + final boolean compiled = DJDTCompiler.compile(new String[] { "-nowarn", "-1.8", tFileJava.toString() }, new PrintWriter(System.out), new PrintWriter(System.err)); + if (Utils.debugCache) { + tFileJava.toFile().deleteOnExit(); + } else { + tFileJava.toFile().delete(); + } + if (compiled) { + tFileClass.toFile().deleteOnExit(); + return loadClassRuleDirectly(javaClassNameAndPath, tDir); + } else { + throw new IOException("Can't build script file '" + scriptFile + "'"); + } + } + + public static Rule loadClassRuleFromSourceFile(String scriptFile, Path tDir) throws IOException, URISyntaxException, + InstantiationException, IllegalAccessException, ClassNotFoundException { + final InputStream resource = Utils.getResourceStream(scriptFile); + final String text = Utils.read(resource); + final String[] textArray = text.split("\\n", 5); + final String javaClassName = textArray[2].substring(6); + final String javaClassNameAndPath = new StringBuilder("org.warp.picalculator.math.rules.").append(javaClassName).toString(); + try { + return loadClassRuleDirectly(javaClassNameAndPath, tDir); + } catch (final Exception ex) { + ex.printStackTrace(); + return null; + } + } + + public static Rule loadClassRuleDirectly(String javaClassNameAndPath, Path tDir) throws IOException, + URISyntaxException, InstantiationException, IllegalAccessException, ClassNotFoundException { + final URLClassLoader cl = new URLClassLoader(new URL[] { tDir.toUri().toURL() }); + final Class aClass = cl.loadClass(javaClassNameAndPath); + cl.close(); + return (Rule) aClass.newInstance(); + } + + public static void warmUp() throws Error, InterruptedException { + ObjectArrayList uselessResult = null; + boolean uselessVariable = false; + for (final RuleType val : RuleType.values()) { + final ObjectArrayList ruleList = rules[val.ordinal()]; + for (final Rule rule : ruleList) { + String ruleName = ""; + try { + ruleName = rule.getRuleName(); + final ObjectArrayList uselessResult2 = rule.execute(generateUselessExpression()); + uselessVariable = (uselessResult == null ? new ObjectArrayList<>() : uselessResult).equals(uselessResult2); + uselessResult = uselessResult2; + } catch (final Exception e) { + if (uselessVariable || true) { + System.err.println("Exception thrown by rule '" + ruleName + "'!"); + e.printStackTrace(); + } + } + } + } + try { + new MathSolver(generateUselessExpression()).solveAllSteps(); + } catch (InterruptedException | Error e) { + e.printStackTrace(); + } + } + + private static Function generateUselessExpression() { + final MathContext mc = new MathContext(); + Function expr = new Expression(mc); + expr = expr.setParameter(0, new Variable(mc, 'x', V_TYPE.VARIABLE)); + return expr; + } + + public static void addRule(Rule rule) { + rules[rule.getRuleType().ordinal()].add(rule); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", rule.getRuleName(), "Loaded as " + rule.getRuleType() + " rule"); + } +} diff --git a/src/main/java/org/warp/picalculator/math/rules/UndefinedRule1.java b/src/main/java/org/warp/picalculator/math/rules/UndefinedRule1.java deleted file mode 100755 index 4444e571..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/UndefinedRule1.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Power; -import org.warp.picalculator.math.functions.Undefined; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Undefined rule
- * 0^0=undefined - * - * @author Andrea Cavalli - * - */ -public class UndefinedRule1 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Power fnc = (Power) f; - if (fnc.getParameter1().equals(new Number(root, 0)) && fnc.getParameter2().equals(new Number(root, 0))) { - return true; - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Undefined(root)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/UndefinedRule2.java b/src/main/java/org/warp/picalculator/math/rules/UndefinedRule2.java deleted file mode 100755 index 4222e728..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/UndefinedRule2.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Undefined; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Undefined rule
- * a / 0 = undefined - * - * @author Andrea Cavalli - * - */ -public class UndefinedRule2 { - - public static boolean compare(Function f) { - final MathContext root = f.getMathContext(); - final Division fnc = (Division) f; - if (fnc.getParameter2() instanceof Number) { - final Number numb = (Number) fnc.getParameter2(); - if (numb.equals(new Number(root, 0))) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(Function f) throws Error { - final MathContext root = f.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - result.add(new Undefined(root)); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/VariableRule1.java b/src/main/java/org/warp/picalculator/math/rules/VariableRule1.java deleted file mode 100755 index 97e13fdf..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/VariableRule1.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionOperator; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Variable rule
- * ax+bx=(a+b)*x (a,b NUMBER; x VARIABLE|MULTIPLICATION) - * - * @author Andrea Cavalli - * - */ -public class VariableRule1 { - - public static boolean compare(FunctionOperator fnc) { - if (fnc.getParameter1() instanceof Multiplication & fnc.getParameter2() instanceof Multiplication) { - final Multiplication m1 = (Multiplication) fnc.getParameter1(); - final Multiplication m2 = (Multiplication) fnc.getParameter2(); - if (m1.getParameter1().equals(m2.getParameter1()) || m1.getParameter2().equals(m2.getParameter2())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(FunctionOperator fnc) throws Error { - final MathContext root = fnc.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication m1 = (Multiplication) fnc.getParameter1(); - final Multiplication m2 = (Multiplication) fnc.getParameter2(); - final Function a; - final Function b; - final Function x; - if (m1.getParameter2().equals(m2.getParameter2())) { - x = m1.getParameter2(); - a = m1.getParameter1(); - b = m2.getParameter1(); - } else { - x = m1.getParameter1(); - a = m1.getParameter2(); - b = m2.getParameter2(); - } - - FunctionOperator rets; - if (fnc instanceof Sum) { - rets = new Sum(root, a, b); - } else { - rets = new Subtraction(root, a, b); - } - final Multiplication retm = new Multiplication(root, rets, x); - result.add(retm); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/VariableRule2.java b/src/main/java/org/warp/picalculator/math/rules/VariableRule2.java deleted file mode 100755 index 5409dbb6..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/VariableRule2.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionOperator; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Variable rule
- * ax+x=(a+1)*x (a,b NUMBER; x VARIABLES) - * - * @author Andrea Cavalli - * - */ -public class VariableRule2 { - - public static boolean compare(FunctionOperator fnc) { - if (fnc.getParameter1() instanceof Multiplication) { - final Multiplication m1 = (Multiplication) fnc.getParameter1(); - if (m1.getParameter2().equals(fnc.getParameter2())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(FunctionOperator fnc) throws Error { - final MathContext root = fnc.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication m1 = (Multiplication) fnc.getParameter1(); - final Function a = m1.getParameter1(); - final Function x = fnc.getParameter2(); - - FunctionOperator rets; - if (fnc instanceof Sum) { - rets = new Sum(root, a, new Number(root, 1)); - } else { - rets = new Subtraction(root, a, new Number(root, 1)); - } - final Multiplication retm = new Multiplication(root, rets, x); - result.add(retm); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/VariableRule3.java b/src/main/java/org/warp/picalculator/math/rules/VariableRule3.java deleted file mode 100755 index 6d378c3c..00000000 --- a/src/main/java/org/warp/picalculator/math/rules/VariableRule3.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.warp.picalculator.math.rules; - -import org.warp.picalculator.Error; -import org.warp.picalculator.math.Function; -import org.warp.picalculator.math.FunctionOperator; -import org.warp.picalculator.math.MathContext; -import org.warp.picalculator.math.functions.Expression; -import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; -import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.functions.Sum; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -/** - * Variable rule
- * x+ax=(a+1)*x (a,b NUMBER; x VARIABLES) - * - * @author Andrea Cavalli - * - */ -public class VariableRule3 { - - public static boolean compare(FunctionOperator fnc) { - if (fnc.getParameter2() instanceof Multiplication) { - final Multiplication m2 = (Multiplication) fnc.getParameter2(); - if (m2.getParameter2().equals(fnc.getParameter1())) { - return true; - } - } - return false; - } - - public static ObjectArrayList execute(FunctionOperator fnc) throws Error { - final MathContext root = fnc.getMathContext(); - final ObjectArrayList result = new ObjectArrayList<>(); - final Multiplication m2 = (Multiplication) fnc.getParameter2(); - final Function a = m2.getParameter1(); - final Function x = fnc.getParameter1(); - - FunctionOperator rets; - if (fnc instanceof Sum) { - rets = new Sum(root, new Number(root, 1), a); - } else { - rets = new Subtraction(root, new Number(root, 1), a); - } - - final Multiplication retm = new Multiplication(root, rets, x); - result.add(retm); - return result; - } - -} diff --git a/src/main/java/org/warp/picalculator/math/rules/methods/DivisionRule1.java b/src/main/java/org/warp/picalculator/math/rules/methods/DivisionRule1.java index 498ce555..fedf4bd5 100755 --- a/src/main/java/org/warp/picalculator/math/rules/methods/DivisionRule1.java +++ b/src/main/java/org/warp/picalculator/math/rules/methods/DivisionRule1.java @@ -19,7 +19,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class DivisionRule1 { public static boolean compare(Division f) throws InterruptedException { - return f.getParameter1().isSimplified() && f.getParameter2().isSimplified() && (f.getParameter1() instanceof Multiplication || f.getParameter2() instanceof Multiplication) && getFirstWorkingDivisionCouple(getDivisionElements(f)) != null; + return false;//TODO: return f.getParameter1().isSimplified() && f.getParameter2().isSimplified() && (f.getParameter1() instanceof Multiplication || f.getParameter2() instanceof Multiplication) && getFirstWorkingDivisionCouple(getDivisionElements(f)) != null; } public static ObjectArrayList execute(Division f) throws Error, InterruptedException { @@ -41,9 +41,9 @@ public class DivisionRule1 { }*/ final int[] size = new int[] { elements[0].size(), elements[1].size() }; - Function separatedDivision = new Division(root, elem1, elem2); + final Function separatedDivision = new Division(root, elem1, elem2); - Function[] resultDivisionArray = new Function[2]; + final Function[] resultDivisionArray = new Function[2]; Function prec; for (int part = 0; part < 2; part++) { prec = null; @@ -76,7 +76,9 @@ public class DivisionRule1 { final ObjectArrayList elementsNumerator = new ObjectArrayList<>(); Function numMult = division.getParameter1(); while (numMult instanceof Multiplication) { - if (Thread.interrupted()) throw new InterruptedException(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } elementsNumerator.add(((Multiplication) numMult).getParameter1()); numMult = ((Multiplication) numMult).getParameter2(); } @@ -85,7 +87,9 @@ public class DivisionRule1 { final ObjectArrayList elementsDenominator = new ObjectArrayList<>(); Function denomMult = division.getParameter2(); while (denomMult instanceof Multiplication) { - if (Thread.interrupted()) throw new InterruptedException(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } elementsDenominator.add(((Multiplication) denomMult).getParameter1()); denomMult = ((Multiplication) denomMult).getParameter2(); } @@ -94,26 +98,29 @@ public class DivisionRule1 { return new ObjectArrayList[] { elementsNumerator, elementsDenominator }; } - private static int[] getFirstWorkingDivisionCouple(ObjectArrayList[] elements) throws InterruptedException { - final int[] size = new int[] { elements[0].size(), elements[1].size() }; - Function a; - Function b; - if (elements[0].size() + elements[1].size() <= 2) { - return null; - } - for (int i = 0; i < size[0]; i++) { - a = elements[0].get(i); - for (int j = 0; j < size[1]; j++) { - if (Thread.interrupted()) throw new InterruptedException(); - b = elements[1].get(j); - Function testFunc; - testFunc = new Division(a.getMathContext(), a, b); - if (!testFunc.isSimplified()) { - return new int[] { i, j }; - } - } - } + private static int[] getFirstWorkingDivisionCouple(ObjectArrayList[] elements) + throws InterruptedException { return null; + //TODO: +// final int[] size = new int[] { elements[0].size(), elements[1].size() }; +// Function a; +// Function b; +// if (elements[0].size() + elements[1].size() <= 2) { +// return null; +// } +// for (int i = 0; i < size[0]; i++) { +// a = elements[0].get(i); +// for (int j = 0; j < size[1]; j++) { +// if (Thread.interrupted()) throw new InterruptedException(); +// b = elements[1].get(j); +// Function testFunc; +// testFunc = new Division(a.getMathContext(), a, b); +// if (!testFunc.isSimplified()) { +// return new int[] { i, j }; +// } +// } +// } +// return null; } } diff --git a/src/main/java/org/warp/picalculator/math/rules/methods/MultiplicationMethod1.java b/src/main/java/org/warp/picalculator/math/rules/methods/MultiplicationMethod1.java index 6609ffa0..daac20c1 100755 --- a/src/main/java/org/warp/picalculator/math/rules/methods/MultiplicationMethod1.java +++ b/src/main/java/org/warp/picalculator/math/rules/methods/MultiplicationMethod1.java @@ -4,8 +4,6 @@ import org.warp.picalculator.Error; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; import org.warp.picalculator.math.functions.Multiplication; -import org.warp.picalculator.math.functions.Number; - import it.unimi.dsi.fastutil.objects.ObjectArrayList; /** @@ -18,7 +16,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class MultiplicationMethod1 { public static boolean compare(Function f) throws InterruptedException { - return ((Multiplication) f).getParameter1().isSimplified() && ((Multiplication) f).getParameter2().isSimplified() && !(((Multiplication) f).getParameter1() instanceof Number && ((Multiplication) f).getParameter2() instanceof Number) && getFirstWorkingMultiplicationCouple(getMultiplicationElements(f)) != null; + return false;//TODO: return ((Multiplication) f).getParameter1().isSimplified() && ((Multiplication) f).getParameter2().isSimplified() && !(((Multiplication) f).getParameter1() instanceof Number && ((Multiplication) f).getParameter2() instanceof Number) && getFirstWorkingMultiplicationCouple(getMultiplicationElements(f)) != null; } public static ObjectArrayList execute(Function f) throws Error, InterruptedException { @@ -32,7 +30,9 @@ public class MultiplicationMethod1 { final int size = elements.size(); Function prec = new Multiplication(root, elem1, elem2); for (int i = size - 1; i >= 0; i--) { - if (Thread.interrupted()) throw new InterruptedException(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } if (i != workingElementCouple[0] & i != workingElementCouple[1]) { final Function a = prec; final Function b = elements.get(i); @@ -50,7 +50,9 @@ public class MultiplicationMethod1 { private static ObjectArrayList getMultiplicationElements(Function mult) throws InterruptedException { final ObjectArrayList elements = new ObjectArrayList<>(); while (mult instanceof Multiplication) { - if (Thread.interrupted()) throw new InterruptedException(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } elements.add(((Multiplication) mult).getParameter1()); mult = ((Multiplication) mult).getParameter2(); } @@ -58,32 +60,35 @@ public class MultiplicationMethod1 { return elements; } - private static int[] getFirstWorkingMultiplicationCouple(ObjectArrayList elements) throws InterruptedException { - final int size = elements.size(); - Function a; - Function b; - if (elements.size() == 0) { - return null; - } - if (elements.size() == 2) { - return null; - } - final MathContext root = elements.get(0).getMathContext(); - for (int i = 0; i < size; i++) { - a = elements.get(i); - for (int j = 0; j < size; j++) { - if (Thread.interrupted()) throw new InterruptedException(); - b = elements.get(j); - if (i != j) { - Function testFunc; - testFunc = new Multiplication(root, a, b); - if (!testFunc.isSimplified()) { - return new int[] { i, j }; - } - } - } - } + private static int[] getFirstWorkingMultiplicationCouple(ObjectArrayList elements) + throws InterruptedException { return null; + // TODO: +// final int size = elements.size(); +// Function a; +// Function b; +// if (elements.size() == 0) { +// return null; +// } +// if (elements.size() == 2) { +// return null; +// } +// final MathContext root = elements.get(0).getMathContext(); +// for (int i = 0; i < size; i++) { +// a = elements.get(i); +// for (int j = 0; j < size; j++) { +// if (Thread.interrupted()) throw new InterruptedException(); +// b = elements.get(j); +// if (i != j) { +// Function testFunc; +// testFunc = new Multiplication(root, a, b); +// if (!testFunc.isSimplified()) { +// return new int[] { i, j }; +// } +// } +// } +// } +// return null; } } diff --git a/src/main/java/org/warp/picalculator/math/rules/methods/SumMethod1.java b/src/main/java/org/warp/picalculator/math/rules/methods/SumMethod1.java index 3de7b312..b64f406f 100755 --- a/src/main/java/org/warp/picalculator/math/rules/methods/SumMethod1.java +++ b/src/main/java/org/warp/picalculator/math/rules/methods/SumMethod1.java @@ -23,8 +23,10 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class SumMethod1 { public static boolean compare(Function f) throws InterruptedException { - final MathContext root = f.getMathContext(); - return (f instanceof Sum || f instanceof Subtraction) && ((FunctionOperator) f).getParameter1().isSimplified() && ((FunctionOperator) f).getParameter2().isSimplified() && !(((FunctionOperator) f).getParameter1() instanceof Number && ((FunctionOperator) f).getParameter2() instanceof Number) && getFirstWorkingSumCouple(root, getSumElements(f)) != null; + return false; + //TODO: +// final MathContext root = f.getMathContext(); +// return (f instanceof Sum || f instanceof Subtraction) && ((FunctionOperator) f).getParameter1().isSimplified() && ((FunctionOperator) f).getParameter2().isSimplified() && !(((FunctionOperator) f).getParameter1() instanceof Number && ((FunctionOperator) f).getParameter2() instanceof Number) && getFirstWorkingSumCouple(root, getSumElements(f)) != null; } public static ObjectArrayList execute(Function f) throws Error, InterruptedException { @@ -39,7 +41,9 @@ public class SumMethod1 { Function prec = new Sum(root, elem1, elem2); for (int i = size - 1; i >= 0; i--) { if (i != workingElementCouple[0] & i != workingElementCouple[1]) { - if (Thread.interrupted()) throw new InterruptedException(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } final Function a = prec; final Function b = elements.get(i); if (b instanceof Negative) { @@ -65,7 +69,9 @@ public class SumMethod1 { final MathContext root = sum.getMathContext(); final ObjectArrayList elements = new ObjectArrayList<>(); while (sum instanceof Sum || sum instanceof Subtraction) { - if (Thread.interrupted()) throw new InterruptedException(); + if (Thread.interrupted()) { + throw new InterruptedException(); + } if (sum instanceof Sum) { elements.add(((FunctionOperator) sum).getParameter2()); } else { @@ -77,38 +83,40 @@ public class SumMethod1 { return elements; } - private static int[] getFirstWorkingSumCouple(MathContext root, ObjectArrayList elements) throws InterruptedException { - final int size = elements.size(); - Function a; - Function b; - if (elements.size() == 2) { - return null; - } - for (int i = 0; i < size; i++) { - a = elements.get(i); - for (int j = 0; j < size; j++) { - if (Thread.interrupted()) throw new InterruptedException(); - b = elements.get(j); - if (i != j) { - Function testFunc; - if (b instanceof Negative) { - testFunc = new Subtraction(root, a, ((Negative) b).getParameter()); - } else if (b instanceof Number && ((Number) b).getTerm().compareTo(BigDecimal.ZERO) < 0) { - testFunc = new Subtraction(root, a, ((Number) b).multiply(new Number(root, -1))); - } else if (a instanceof Negative) { - testFunc = new Subtraction(root, b, ((Negative) a).getParameter()); - } else if (a instanceof Number && ((Number) a).getTerm().compareTo(BigDecimal.ZERO) < 0) { - testFunc = new Subtraction(root, b, ((Number) a).multiply(new Number(root, -1))); - } else { - testFunc = new Sum(root, a, b); - } - if (!testFunc.isSimplified()) { - return new int[] { i, j }; - } - } - } - } + private static int[] getFirstWorkingSumCouple(MathContext root, ObjectArrayList elements) + throws InterruptedException { return null; +// final int size = elements.size(); +// Function a; +// Function b; +// if (elements.size() == 2) { +// return null; +// } +// for (int i = 0; i < size; i++) { +// a = elements.get(i); +// for (int j = 0; j < size; j++) { +// if (Thread.interrupted()) throw new InterruptedException(); +// b = elements.get(j); +// if (i != j) { +// Function testFunc; +// if (b instanceof Negative) { +// testFunc = new Subtraction(root, a, ((Negative) b).getParameter()); +// } else if (b instanceof Number && ((Number) b).getTerm().compareTo(BigDecimal.ZERO) < 0) { +// testFunc = new Subtraction(root, a, ((Number) b).multiply(new Number(root, -1))); +// } else if (a instanceof Negative) { +// testFunc = new Subtraction(root, b, ((Negative) a).getParameter()); +// } else if (a instanceof Number && ((Number) a).getTerm().compareTo(BigDecimal.ZERO) < 0) { +// testFunc = new Subtraction(root, b, ((Number) a).multiply(new Number(root, -1))); +// } else { +// testFunc = new Sum(root, a, b); +// } +// if (!testFunc.isSimplified()) { +// return new int[] { i, j }; +// } +// } +// } +// } +// return null; } } diff --git a/src/main/java/org/warp/picalculator/math/solver/MathSolver.java b/src/main/java/org/warp/picalculator/math/solver/MathSolver.java new file mode 100644 index 00000000..f251ec4e --- /dev/null +++ b/src/main/java/org/warp/picalculator/math/solver/MathSolver.java @@ -0,0 +1,254 @@ +package org.warp.picalculator.math.solver; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.warp.picalculator.ConsoleUtils; +import org.warp.picalculator.Error; +import org.warp.picalculator.StaticVars; +import org.warp.picalculator.deps.DAtomicInteger; +import org.warp.picalculator.math.Function; +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 Function initialFunction; + private final DAtomicInteger stepState = new DAtomicInteger(0); + private int stepStateRepetitions = 0; + private int consecutiveNullSteps = 0; + + private enum StepState { + _1_CALCULATION, _2_EXPANSION, _3_CALCULATION, _4_REDUCTION + } + + private final StepState[] stepStates = StepState.values(); + @SuppressWarnings("unchecked") + private final ObjectArrayList[][] lastFunctions = new ObjectArrayList[2][stepStates.length]; + + public MathSolver(Function initialFunction) { + this.initialFunction = initialFunction; + } + + @SuppressWarnings("unchecked") + public ObjectArrayList> solveAllSteps() throws InterruptedException, Error { + final ObjectArrayList> steps = new ObjectArrayList<>(); + ObjectArrayList lastFnc = null, currFnc = new ObjectArrayList<>(); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Solving all steps. Input: " + initialFunction.toString()); + currFnc.add(initialFunction); + long stepNumber = 0; + int initStepState = 0, endStepState = 0; + final DAtomicInteger stepState = new DAtomicInteger(0); + do { + final ObjectArrayList[] currFncHistory = new ObjectArrayList[stepStates.length]; + final String stepName = "Step " + stepNumber; + if (initStepState > endStepState) { + for (int i = initStepState; i < stepStates.length; i++) { + currFncHistory[i] = currFnc; + } + for (int i = 0; i <= initStepState; i++) { + currFncHistory[i] = currFnc; + } + } else { + for (int i = initStepState; i <= endStepState; i++) { + currFncHistory[i] = currFnc; + } + } + if (currFnc != null) { + lastFunctions[1] = lastFunctions[0]; + lastFunctions[0] = currFncHistory; + } + lastFnc = currFnc; + initStepState = stepState.get(); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Starting step " + stepStates[initStepState] + ". Input: " + currFnc); + final ObjectArrayList stepResult = solveStep(lastFnc, stepState); + if (stepResult != null) { + for (final Function result : stepResult) { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, result.toString()); + } + currFnc = stepResult; + steps.add(currFnc); + } + endStepState = stepState.get(); + stepNumber++; + + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Step result: " + stepResult); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Step result details: Consecutive steps that did nothing: " + consecutiveNullSteps + ", this step did " + stepStateRepetitions + " simplifications."); + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Next step state: " + stepStates[endStepState]); + if (StaticVars.debugOn) { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, currFnc + " is " + (checkEquals(currFnc, lastFunctions[0][endStepState]) ? "" : "not ") + "equals to [0]:" + lastFunctions[0][endStepState]); + } + if (StaticVars.debugOn) { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, currFnc + " is " + (checkEquals(currFnc, lastFunctions[1][endStepState]) ? "" : "not ") + "equals to [1]:" + lastFunctions[1][endStepState]); + } + } while (consecutiveNullSteps < stepStates.length && !checkEquals(currFnc, lastFunctions[0][endStepState]) && !checkEquals(currFnc, lastFunctions[1][endStepState])); + if (consecutiveNullSteps >= stepStates.length) { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + consecutiveNullSteps + " >= " + stepStates.length); + } else if (checkEquals(currFnc, lastFunctions[0][endStepState])) { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + currFnc + " is equals to [0]:" + lastFunctions[0][endStepState]); + } else { + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + currFnc + " is equals to [1]:" + lastFunctions[1][endStepState]); + } + 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(ObjectArrayList fncs) throws InterruptedException, Error { + return solveStep(fncs, stepState); + } + + private ObjectArrayList solveStep(ObjectArrayList fncs, DAtomicInteger stepState) + throws InterruptedException, Error { + final ObjectArrayList processedFncs = applyRules(fncs, RuleType.EXISTENCE); // Apply existence rules before everything + if (processedFncs != null) { + fncs = processedFncs; + } + RuleType currentAcceptedRules; + switch (stepStates[stepState.get()]) { + case _1_CALCULATION: { + currentAcceptedRules = RuleType.CALCULATION; + break; + } + case _2_EXPANSION: { + currentAcceptedRules = RuleType.EXPANSION; + break; + } + case _3_CALCULATION: { + currentAcceptedRules = RuleType.CALCULATION; + break; + } + case _4_REDUCTION: { + currentAcceptedRules = RuleType.REDUCTION; + break; + } + default: + System.err.println("Unknown Step State"); + throw new NotImplementedException(); + } + final ObjectArrayList results = applyRules(fncs, currentAcceptedRules); + switch (stepStates[stepState.get()]) { + case _1_CALCULATION: { + if (results == null) { + stepState.incrementAndGet(); + consecutiveNullSteps++; + stepStateRepetitions = 0; + } else { + consecutiveNullSteps = 0; + stepStateRepetitions++; + return results; + } + break; + } + case _2_EXPANSION: { + if (results == null) { + if (stepStateRepetitions == 0) { + stepState.addAndGet(2); + consecutiveNullSteps += 2; + } else { + stepState.incrementAndGet(); + consecutiveNullSteps++; + } + stepStateRepetitions = 0; + } else { + consecutiveNullSteps = 0; + stepStateRepetitions++; + return results; + } + break; + } + case _3_CALCULATION: { + if (results == null) { + stepState.incrementAndGet(); + consecutiveNullSteps++; + stepStateRepetitions = 0; + } else { + consecutiveNullSteps = 0; + stepStateRepetitions++; + return results; + } + break; + } + case _4_REDUCTION: { + if (results == null) { + stepState.set(1); + consecutiveNullSteps++; + stepStateRepetitions = 0; + } else { + stepState.set(0); + consecutiveNullSteps = 0; + stepStateRepetitions++; + return results; + } + break; + } + default: + System.err.println("Unknown Step State"); + throw new NotImplementedException(); + } + return null; + } + + private ObjectArrayList applyRules(ObjectArrayList fncs, RuleType currentAcceptedRules) + throws InterruptedException, Error { + final ObjectArrayList rules = initialFunction.getMathContext().getAcceptableRules(currentAcceptedRules); + ObjectArrayList results = null; + ObjectArrayList appliedRules = new ObjectArrayList<>(); + out: { + for (final Function fnc : fncs) { + boolean didSomething = false; + for (final Rule rule : rules) { + List ruleResults = fnc.simplify(rule); + if ((ruleResults != null && !ruleResults.isEmpty())) { + if (results == null) { + results = new ObjectArrayList<>(); + } + results.addAll(ruleResults); + appliedRules.add(rule); + didSomething = true; + break; + } + } + if (!didSomething && fncs.size() > 1) { + if (results == null) { + results = new ObjectArrayList<>(); + } + results.add(fnc); + } + } + } + if (appliedRules.isEmpty()) results = null; + if (StaticVars.debugOn & results != null && !appliedRules.isEmpty()) { + StringBuilder rulesStr = new StringBuilder(); + for(Rule r : appliedRules) { + rulesStr.append(r.getRuleName()); + rulesStr.append(','); + } + if (rulesStr.length() > 0) { + rulesStr.setLength(rulesStr.length() - 1); + } + ConsoleUtils.out.println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", currentAcceptedRules.toString(), "Applied rules: " + rulesStr); + } + return results; + } +} diff --git a/src/main/java/org/warp/picalculator/math/SolveMethod.java b/src/main/java/org/warp/picalculator/math/solver/SolveMethod.java similarity index 84% rename from src/main/java/org/warp/picalculator/math/SolveMethod.java rename to src/main/java/org/warp/picalculator/math/solver/SolveMethod.java index 2f22bd1b..d57c9d00 100755 --- a/src/main/java/org/warp/picalculator/math/SolveMethod.java +++ b/src/main/java/org/warp/picalculator/math/solver/SolveMethod.java @@ -1,4 +1,4 @@ -package org.warp.picalculator.math; +package org.warp.picalculator.math.solver; import org.warp.picalculator.math.functions.equations.Equation; diff --git a/src/main/jni/libpicalc.so b/src/main/jni/libpicalc.so new file mode 100644 index 00000000..25c9e68c Binary files /dev/null and b/src/main/jni/libpicalc.so differ diff --git a/src/main/resources/default-rules.lst b/src/main/resources/default-rules.lst new file mode 100644 index 00000000..9fb50ee4 --- /dev/null +++ b/src/main/resources/default-rules.lst @@ -0,0 +1,49 @@ +functions/DivisionRule +functions/EmptyNumberRule +functions/ExpressionRule +functions/JokeRule +functions/MultiplicationRule +functions/NegativeRule +functions/NumberRule +functions/PowerRule +functions/RootRule +functions/SubtractionRule +functions/SumRule +functions/SumSubtractionRule +functions/VariableRule +ExpandRule1 +ExpandRule2 +ExpandRule5 +ExponentRule1 +ExponentRule2 +ExponentRule3 +ExponentRule4 +ExponentRule8 +ExponentRule9 +ExponentRule15 +ExponentRule16 +ExponentRule17 +FractionsRule1 +FractionsRule2 +FractionsRule3 +FractionsRule4 +FractionsRule5 +FractionsRule6 +FractionsRule7 +FractionsRule8 +FractionsRule9 +FractionsRule10 +FractionsRule11 +FractionsRule12 +FractionsRule14 +NumberRule1 +NumberRule2 +NumberRule3 +NumberRule4 +NumberRule5 +NumberRule7 +UndefinedRule1 +UndefinedRule2 +VariableRule1 +VariableRule2 +VariableRule3 \ No newline at end of file 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 973440c9..00000000 Binary files a/src/main/resources/draft unknown variable choice.png and /dev/null differ diff --git a/src/main/resources/font_norm.rft b/src/main/resources/font_norm.rft index 7e0e03b0..d4e5e1e7 100644 Binary files a/src/main/resources/font_norm.rft and b/src/main/resources/font_norm.rft differ diff --git a/src/main/resources/font_smal.rft b/src/main/resources/font_smal.rft index a61b6966..0f034b49 100644 Binary files a/src/main/resources/font_smal.rft and b/src/main/resources/font_smal.rft differ diff --git a/src/main/resources/libpicalc.so b/src/main/resources/libpicalc.so new file mode 100644 index 00000000..25c9e68c Binary files /dev/null and b/src/main/resources/libpicalc.so differ diff --git a/src/main/resources/marioskin.png b/src/main/resources/marioskin.png index 10c34579..afeb54b6 100755 Binary files a/src/main/resources/marioskin.png and b/src/main/resources/marioskin.png differ diff --git a/src/main/resources/marioskin.xcf b/src/main/resources/marioskin.xcf index c4938caf..61355708 100755 Binary files a/src/main/resources/marioskin.xcf and b/src/main/resources/marioskin.xcf differ diff --git a/src/main/resources/palettetmp.bmp b/src/main/resources/palettetmp.bmp deleted file mode 100755 index db22ad4f..00000000 Binary files a/src/main/resources/palettetmp.bmp and /dev/null differ diff --git a/src/main/resources/rules/ExpandRule1.java b/src/main/resources/rules/ExpandRule1.java new file mode 100644 index 00000000..1dad8003 --- /dev/null +++ b/src/main/resources/rules/ExpandRule1.java @@ -0,0 +1,137 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExpandRule1 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.MathContext; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; + +/** + * Expand rule + * -(+a+b) = -a-b + * -(+a-b) = -a+b + * + * @author Andrea Cavalli + * + */ +public class ExpandRule1 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExpandRule1"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Multiplication) { + Multiplication fnc = (Multiplication) f; + if (fnc.getParameter1().equals(new Number(fnc.getMathContext(), -1))) { + Function 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 (f instanceof Subtraction || f instanceof SumSubtraction) { + FunctionOperator fnc = (FunctionOperator) f; + Function expr = fnc.getParameter2(); + if (expr instanceof Sum) { + isExecutable = true; + } else if (expr instanceof Subtraction) { + isExecutable = true; + } else if (expr instanceof SumSubtraction) { + isExecutable = true; + } + } + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + MathContext root = f.getMathContext(); + + Function expr = null; + int fromSubtraction = 0; + FunctionOperator subtraction = null; + if (f instanceof Multiplication) { + expr = ((Multiplication) f).getParameter2(); + } else if (f instanceof Subtraction || f instanceof SumSubtraction) { + expr = ((Multiplication) f).getParameter2(); + if (f instanceof Subtraction) { + fromSubtraction = 1; + } else { + fromSubtraction = 2; + } + } + + if (f instanceof SumSubtraction) { + + } + + Function fnc = expr; + if (fnc instanceof Sum) { + Function a = ((Sum)fnc).getParameter1(); + Function b = ((Sum)fnc).getParameter2(); + Function 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); + } else { + result.add(fnc2); + } + } else if (fnc instanceof Subtraction) { + Function a = ((Subtraction)fnc).getParameter1(); + Function b = ((Subtraction)fnc).getParameter2(); + Function 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); + } else { + result.add(fnc2); + } + } else if (fnc instanceof SumSubtraction) { + Function a = ((SumSubtraction)fnc).getParameter1(); + Function b = ((SumSubtraction)fnc).getParameter2(); + Function fnc2 = new Sum(root, new Multiplication(root, new Number(root, -1), a), b); + Function 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); + subtraction = new SumSubtraction(root, ((FunctionOperator)f).getParameter1(), fnc3); + result.add(subtraction); + result.add(subtraction); + } else { + result.add(fnc2); + result.add(fnc2); + } + } + return result; + } else { + return null; + } + + } +} diff --git a/src/main/resources/rules/ExpandRule2.java b/src/main/resources/rules/ExpandRule2.java new file mode 100644 index 00000000..1a9d782b --- /dev/null +++ b/src/main/resources/rules/ExpandRule2.java @@ -0,0 +1,87 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExpandRule2 +*/ + +import org.warp.picalculator.Errors; +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; + +/** + * Expand rule + * a(b+c)=ab+ac + * + * @author Andrea Cavalli + * + */ +public class ExpandRule2 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExpandRule2"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) throws Error { + boolean isExecutable = false; + if (f instanceof Multiplication) { + final Multiplication fnc = (Multiplication) f; + if (fnc.getParameter1() instanceof Sum) { + isExecutable = true; + } else if (fnc.getParameter2() instanceof Sum) { + isExecutable = true; + } else { + isExecutable = false; + } + } + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + MathContext root = f.getMathContext(); + + final Multiplication fnc = (Multiplication) f; + final Sum sum; + final Function a; + if (fnc.getParameter1() instanceof Sum) { + sum = (Sum) fnc.getParameter1(); + a = fnc.getParameter2(); + } else if (fnc.getParameter2() instanceof Sum) { + sum = (Sum) fnc.getParameter2(); + a = fnc.getParameter1(); + } else { + throw new Error(Errors.UNBALANCED_STACK); + } + + final Function b = sum.getParameter1(); + final Function c = sum.getParameter2(); + final Multiplication ab = new Multiplication(root, a, b); + final Multiplication ac = new Multiplication(root, a, c); + result.add(new Sum(root, ab, ac)); + return result; + } else { + return null; + } + + } +} diff --git a/src/main/resources/rules/ExpandRule5.java b/src/main/resources/rules/ExpandRule5.java new file mode 100644 index 00000000..d77c966b --- /dev/null +++ b/src/main/resources/rules/ExpandRule5.java @@ -0,0 +1,75 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExpandRule5 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Expression; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Negative; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Expand rule + * -(-a) = a + * + * @author Andrea Cavalli + * + */ +public class ExpandRule5 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExpandRule5"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Negative) { + isExecutable = ((FunctionSingle)f).getParameter() instanceof Negative; + } else if (f instanceof Multiplication) { + if (((FunctionOperator)f).getParameter1().equals(new Number(f.getMathContext(), -1)) && ((FunctionOperator)f).getParameter2() instanceof Multiplication) { + isExecutable = ((FunctionOperator)((FunctionOperator)f).getParameter2()).getParameter1().equals(((FunctionOperator)f).getParameter1()); + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + + if (f instanceof Negative) { + Negative fnc = (Negative) f; + result.add(((FunctionSingle)((FunctionSingle)fnc.getParameter()).getParameter()).getParameter()); + } else if (f instanceof Multiplication) { + FunctionOperator fnc = (FunctionOperator) f; + result.add(((FunctionOperator)fnc.getParameter2()).getParameter2()); + } + return result; + } else { + return null; + } + } + +} diff --git a/src/main/resources/rules/ExponentRule1.java b/src/main/resources/rules/ExponentRule1.java new file mode 100644 index 00000000..2c39f5eb --- /dev/null +++ b/src/main/resources/rules/ExponentRule1.java @@ -0,0 +1,68 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule1 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * 1^a=1 + * + * @author Andrea Cavalli + * + */ +public class ExponentRule1 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule1"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + MathContext root = f.getMathContext(); + if (f instanceof Power) { + if (((Power)f).getParameter1().equals(new Number(root, 1))) { + isExecutable = true; + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new Number(root, 1)); + return result; + } else { + return null; + } + } + +} diff --git a/src/main/resources/rules/ExponentRule15.java b/src/main/resources/rules/ExponentRule15.java new file mode 100644 index 00000000..62565e79 --- /dev/null +++ b/src/main/resources/rules/ExponentRule15.java @@ -0,0 +1,74 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule15 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * a*a=a^2 + * + * @author Andrea Cavalli + * + */ +public class ExponentRule15 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule15"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Multiplication) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1().equals(fnc.getParameter2())) { + isExecutable = true; + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + Function a = fnc.getParameter1(); + Function two = new Number(root, 2); + Function p = new Power(root, a, two); + result.add(p); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/ExponentRule16.java b/src/main/resources/rules/ExponentRule16.java new file mode 100644 index 00000000..cd33e526 --- /dev/null +++ b/src/main/resources/rules/ExponentRule16.java @@ -0,0 +1,82 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule16 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * (a ^ b) * (a ^ c) = a ^ (b + c) + * + * @author Andrea Cavalli + * + */ +public class ExponentRule16 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule16"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.REDUCTION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Multiplication) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Power && fnc.getParameter2() instanceof Power) { + isExecutable = ((FunctionOperator)fnc.getParameter1()).getParameter1().equals(((FunctionOperator)fnc.getParameter2()).getParameter1()); + } else if (fnc.getParameter1() instanceof Power) { + isExecutable = ((FunctionOperator)fnc.getParameter1()).getParameter1().equals(fnc.getParameter2()); + } else if (fnc.getParameter2() instanceof Power) { + isExecutable = ((FunctionOperator)fnc.getParameter2()).getParameter1().equals(fnc.getParameter1()); + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Power && fnc.getParameter2() instanceof Power) { + result.add(new Power(root, ((FunctionOperator)fnc.getParameter1()).getParameter1(), new Sum(root, ((FunctionOperator)fnc.getParameter1()).getParameter2(), ((FunctionOperator)fnc.getParameter2()).getParameter2()))); + } else if (fnc.getParameter1() instanceof Power) { + result.add(new Power(root, fnc.getParameter2(), new Sum(root, ((FunctionOperator)fnc.getParameter1()).getParameter2(), new Number(root, 1)))); + } else if (fnc.getParameter2() instanceof Power) { + result.add(new Power(root, fnc.getParameter1(), new Sum(root, new Number(root, 1), ((FunctionOperator)fnc.getParameter2()).getParameter2()))); + } + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/ExponentRule17.java b/src/main/resources/rules/ExponentRule17.java new file mode 100644 index 00000000..3f14f070 --- /dev/null +++ b/src/main/resources/rules/ExponentRule17.java @@ -0,0 +1,75 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule17 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.functions.Root; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * a√x=x^1/a + * + * @author Andrea Cavalli + * + */ +public class ExponentRule17 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule17"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Root) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1().equals(fnc.getParameter2())) { + isExecutable = true; + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + Function a = fnc.getParameter1(); + Function two = new Number(root, 2); + Function p = new Power(root, a, two); + result.add(p); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/ExponentRule2.java b/src/main/resources/rules/ExponentRule2.java new file mode 100644 index 00000000..72361771 --- /dev/null +++ b/src/main/resources/rules/ExponentRule2.java @@ -0,0 +1,67 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule2 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * a^1=a + * + * @author Andrea Cavalli + * + */ +public class ExponentRule2 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule2"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter2().equals(new Number(f.getMathContext(), 1))) { + isExecutable = true; + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(((FunctionOperator)f).getParameter1()); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/ExponentRule3.java b/src/main/resources/rules/ExponentRule3.java new file mode 100644 index 00000000..ed2b1ec9 --- /dev/null +++ b/src/main/resources/rules/ExponentRule3.java @@ -0,0 +1,67 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule3 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * a^0=1 + * + * @author Andrea Cavalli + * + */ +public class ExponentRule3 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule3"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter2().equals(new Number(f.getMathContext(), 0))) { + isExecutable = true; + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new Number(f.getMathContext(), 1)); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/ExponentRule4.java b/src/main/resources/rules/ExponentRule4.java new file mode 100644 index 00000000..39616d19 --- /dev/null +++ b/src/main/resources/rules/ExponentRule4.java @@ -0,0 +1,79 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule4 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +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.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * (a*b)^n=a^n*b^n + * + * @author Andrea Cavalli + * + */ +public class ExponentRule4 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule4"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Multiplication && fnc.getParameter2() instanceof Number) { + isExecutable = true; + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + FunctionOperator mult = (FunctionOperator) fnc.getParameter1(); + Function a = mult.getParameter1(); + Function b = mult.getParameter2(); + Function n = fnc.getParameter2(); + Function p1 = new Power(root, a, n); + Function p2 = new Power(root, b, n); + Function retMult = new Multiplication(root, p1, p2); + result.add(retMult); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/ExponentRule8.java b/src/main/resources/rules/ExponentRule8.java new file mode 100644 index 00000000..84c044f4 --- /dev/null +++ b/src/main/resources/rules/ExponentRule8.java @@ -0,0 +1,70 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule8 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +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.Power; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * (a) ^ (b+c) = a ^ b + a ^ c + * + * @author Andrea Cavalli + * + */ +public class ExponentRule8 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule8"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter2() instanceof Sum) { + Sum sum = (Sum) fnc.getParameter2(); + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + Function a = fnc.getParameter1(); + Function b = sum.getParameter1(); + Function c = sum.getParameter2(); + result.add(new Multiplication(root, new Power(root, a, b), new Power(root, a, c))); + return result; + } + } + + return null; + } +} diff --git a/src/main/resources/rules/ExponentRule9.java b/src/main/resources/rules/ExponentRule9.java new file mode 100644 index 00000000..525aa7e3 --- /dev/null +++ b/src/main/resources/rules/ExponentRule9.java @@ -0,0 +1,72 @@ +/* +SETTINGS: (please don't move this part) + PATH=ExponentRule9 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +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.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Exponent rule + * (a ^ b) ^ c = a ^ (b * c) + * + * @author Andrea Cavalli + * + */ +public class ExponentRule9 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "ExponentRule9"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Power) { + isExecutable = true; + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator powC = (FunctionOperator) f; + FunctionOperator powB = (FunctionOperator) powC.getParameter1(); + Function p = new Power(root, powB.getParameter1(), new Multiplication(root, powB.getParameter2(), powC.getParameter2())); + result.add(p); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule1.java b/src/main/resources/rules/FractionsRule1.java new file mode 100644 index 00000000..dad56511 --- /dev/null +++ b/src/main/resources/rules/FractionsRule1.java @@ -0,0 +1,71 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule1 +*/ + +//Imports +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.MathContext; + +/** + * Fractions rule + * 0 / a = 0 + * + * @author Andrea Cavalli + * + */ +public class FractionsRule1 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule1"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + MathContext root = f.getMathContext(); + if (f instanceof Division) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Number) { + Function numb1 = fnc.getParameter1(); + if (numb1.equals(new Number(root, 0))) { + if (fnc.getParameter2() instanceof Number) { + Function numb2 = fnc.getParameter2(); + if (numb2.equals(new Number(root, 0)) == false) { + isExecutable = true; + } + } else { + isExecutable = true; + } + } + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new Number(f.getMathContext(), 0)); + return result; + } else { + return null; + } + } +} \ No newline at end of file diff --git a/src/main/resources/rules/FractionsRule10.java b/src/main/resources/rules/FractionsRule10.java new file mode 100644 index 00000000..f366a966 --- /dev/null +++ b/src/main/resources/rules/FractionsRule10.java @@ -0,0 +1,67 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule10 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + +import java.math.BigDecimal; + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a/(-b) = -(a/b) + * + * @author Andrea Cavalli + * + */ +public class FractionsRule10 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule10"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof Division) { + MathContext root = f.getMathContext(); + Division div = (Division) f; + if (div.getParameter2() instanceof Multiplication && ((Multiplication)div.getParameter2()).isNegative()) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(Multiplication.newNegative(root, new Division(root, div.getParameter1(), ((Multiplication)div.getParameter2()).toPositive()))); + return result; + } + } + + return null; + } +} diff --git a/src/main/resources/rules/FractionsRule11.java b/src/main/resources/rules/FractionsRule11.java new file mode 100644 index 00000000..16570f34 --- /dev/null +++ b/src/main/resources/rules/FractionsRule11.java @@ -0,0 +1,84 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule11 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Fractions rule + * a / (b / c) = (a * c) / b + * + * @author Andrea Cavalli + * + */ +public class FractionsRule11 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule11"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Division) { + FunctionOperator fnc = (FunctionOperator) f; + Function a; + Function c; + FunctionOperator div2; + if (fnc.getParameter2() instanceof Division) { + div2 = (FunctionOperator) fnc.getParameter2(); + a = fnc.getParameter1(); + c = div2.getParameter2(); + isExecutable = true; + } else { + isExecutable = false; + } + } + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + Function a; + Function b; + Function c; + + FunctionOperator div2 = (FunctionOperator) fnc.getParameter2(); + + a = fnc.getParameter1(); + b = div2.getParameter1(); + c = div2.getParameter2(); + result.add(new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), b)); + + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule12.java b/src/main/resources/rules/FractionsRule12.java new file mode 100644 index 00000000..340021ba --- /dev/null +++ b/src/main/resources/rules/FractionsRule12.java @@ -0,0 +1,82 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule12 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Fractions rule + * (b / c) / a = b / (a * c) + * + * @author Andrea Cavalli + * + */ +public class FractionsRule12 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule12"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Division) { + FunctionOperator fnc = (FunctionOperator) f; + Function a; + Function c; + if (fnc.getParameter1() instanceof Division) { + FunctionOperator div2 = (FunctionOperator) fnc.getParameter1(); + a = fnc.getParameter1(); + c = div2.getParameter2(); + isExecutable = true; + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + Function a; + Function b; + Function c; + + FunctionOperator div2 = (FunctionOperator) fnc.getParameter1(); + a = fnc.getParameter2(); + b = div2.getParameter1(); + c = div2.getParameter2(); + result.add(new Division(fnc.getMathContext(), b, new Multiplication(fnc.getMathContext(), c, a))); + + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule14.java b/src/main/resources/rules/FractionsRule14.java new file mode 100644 index 00000000..15ca607a --- /dev/null +++ b/src/main/resources/rules/FractionsRule14.java @@ -0,0 +1,118 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule14 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Fractions rule + * (a / b) * (c / d) = (a * c) / (b * d) + * + * @author Andrea Cavalli + * + */ +public class FractionsRule14 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule14"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Multiplication) { + FunctionOperator fnc = (FunctionOperator) f; + Function a; + Function b; + Function c; + Function d; + if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Division) { + FunctionOperator div1 = (FunctionOperator) fnc.getParameter1(); + FunctionOperator div2 = (FunctionOperator) fnc.getParameter2(); + a = div1.getParameter1(); + b = div1.getParameter2(); + c = div2.getParameter1(); + d = div2.getParameter2(); + isExecutable = true; + } else if (fnc.getParameter1() instanceof Division) { + FunctionOperator div1 = (FunctionOperator) fnc.getParameter1(); + a = div1.getParameter1(); + b = div1.getParameter2(); + c = fnc.getParameter2(); + isExecutable = true; + } else if (fnc.getParameter2() instanceof Division) { + FunctionOperator div2 = (FunctionOperator) fnc.getParameter2(); + a = fnc.getParameter1(); + c = div2.getParameter1(); + d = div2.getParameter2(); + isExecutable = true; + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + Function a; + Function b; + Function c; + Function d; + + if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Division) { + FunctionOperator div1 = (FunctionOperator) fnc.getParameter1(); + FunctionOperator div2 = (FunctionOperator) fnc.getParameter2(); + a = div1.getParameter1(); + b = div1.getParameter2(); + c = div2.getParameter1(); + d = div2.getParameter2(); + Function div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), new Multiplication(fnc.getMathContext(), b, d)); + result.add(div); + } else if (fnc.getParameter1() instanceof Division) { + FunctionOperator div1 = (FunctionOperator) fnc.getParameter1(); + a = div1.getParameter1(); + b = div1.getParameter2(); + c = fnc.getParameter2(); + Function div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), b); + result.add(div); + } else if (fnc.getParameter2() instanceof Division) { + FunctionOperator div2 = (FunctionOperator) fnc.getParameter2(); + a = fnc.getParameter1(); + c = div2.getParameter1(); + d = div2.getParameter2(); + Function div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), d); + result.add(div); + } + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule2.java b/src/main/resources/rules/FractionsRule2.java new file mode 100644 index 00000000..ac2494dc --- /dev/null +++ b/src/main/resources/rules/FractionsRule2.java @@ -0,0 +1,66 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule2 +*/ + +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Fractions rule + * a / 1 = a + * + * @author Andrea Cavalli + * + */ +public class FractionsRule2 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule2"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Division) { + Division fnc = (Division) f; + if (fnc.getParameter2() instanceof Number) { + Number numb = (Number) fnc.getParameter2(); + if (numb.equals(new Number(f.getMathContext(), 1))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + Division fnc = (Division) f; + result.add(fnc.getParameter1()); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule3.java b/src/main/resources/rules/FractionsRule3.java new file mode 100644 index 00000000..cdb0d870 --- /dev/null +++ b/src/main/resources/rules/FractionsRule3.java @@ -0,0 +1,67 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule3 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Fractions rule + * a / a = 1 + * + * @author Andrea Cavalli + * + */ +public class FractionsRule3 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule3"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Division) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1().equals(fnc.getParameter2())) { + isExecutable = true; + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new Number(f.getMathContext(), 1)); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule4.java b/src/main/resources/rules/FractionsRule4.java new file mode 100644 index 00000000..f0bee9a5 --- /dev/null +++ b/src/main/resources/rules/FractionsRule4.java @@ -0,0 +1,75 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule4 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Fractions rule + * (a / b) ^ -1 = b / a + * + * @author Andrea Cavalli + * + */ +public class FractionsRule4 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule4"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Division && fnc.getParameter2() instanceof Number) { + Function n2 = fnc.getParameter2(); + if (n2.equals(new Number(f.getMathContext(), -1))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + Function a = ((FunctionOperator) fnc.getParameter1()).getParameter1(); + Function b = ((FunctionOperator) fnc.getParameter1()).getParameter2(); + Function res = new Division(f.getMathContext(), b, a); + result.add(res); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule5.java b/src/main/resources/rules/FractionsRule5.java new file mode 100644 index 00000000..8c3980e8 --- /dev/null +++ b/src/main/resources/rules/FractionsRule5.java @@ -0,0 +1,91 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule5 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import java.math.BigDecimal; + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Fractions rule + * (a / b) ^ -c = (b / a) ^ c + * + * @author Andrea Cavalli + * + */ +public class FractionsRule5 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule5"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) throws Error { + boolean isExecutable = false; + if (f instanceof Power) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Division) { + if (fnc.getParameter2() instanceof Multiplication && ((FunctionOperator) fnc.getParameter2()).getParameter1().equals(new Number(f.getMathContext(), -1))) { + isExecutable = true; + } else if (fnc.getParameter2() instanceof Number) { + Number n2 = (Number) fnc.getParameter2(); + if (n2.getTerm().compareTo(BigDecimal.ZERO) < 0) { + isExecutable = true; + } + } + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + Function a = ((FunctionOperator) fnc.getParameter1()).getParameter1(); + Function b = ((FunctionOperator) fnc.getParameter1()).getParameter2(); + Function c; + if (fnc.getParameter2() instanceof Multiplication) { + c = ((FunctionOperator) fnc.getParameter2()).getParameter2(); + } else { + c = ((Number) fnc.getParameter2()).multiply(new Number(root, "-1")); + } + Function dv = new Division(root, b, a); + Function pow = new Power(root, dv, c); + result.add(pow); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule6.java b/src/main/resources/rules/FractionsRule6.java new file mode 100644 index 00000000..488ccada --- /dev/null +++ b/src/main/resources/rules/FractionsRule6.java @@ -0,0 +1,76 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule6 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a ^ -1 = 1/a + * + * @author Andrea Cavalli + * + */ +public class FractionsRule6 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule6"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + MathContext root = f.getMathContext(); + Power pow = (Power) f; + if (pow.getParameter2() instanceof Number) { + Function numb = pow.getParameter2(); + if (numb.equals(new Number(root, -1))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + Function a = new Division(root, new Number(root, 1), ((Power) f).getParameter1()); + result.add(a); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/FractionsRule7.java b/src/main/resources/rules/FractionsRule7.java new file mode 100644 index 00000000..69d0bf8c --- /dev/null +++ b/src/main/resources/rules/FractionsRule7.java @@ -0,0 +1,77 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule7 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + +import java.math.BigDecimal; + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a ^ -b = 1/(a^b) + * + * @author Andrea Cavalli + * + */ +public class FractionsRule7 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule7"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + MathContext root = f.getMathContext(); + Power pow = (Power) f; + if (pow.getParameter2() instanceof Number) { + Number numb = (Number) pow.getParameter2(); + if (numb.getTerm().compareTo(BigDecimal.ZERO) < 0) { + ObjectArrayList result = new ObjectArrayList<>(); + Function a = new Division(root, new Number(root, 1), new Power(root, ((Power) f).getParameter1(), ((Number)((Power)f).getParameter2()).multiply(new Number(root, -1)))); + result.add(a); + return result; + } + } else if (pow.getParameter2() instanceof Multiplication && ((Multiplication)pow.getParameter2()).getParameter1().equals(new Number(root, -1))) { + ObjectArrayList result = new ObjectArrayList<>(); + Function a = new Division(root, new Number(root, 1), new Power(root, ((Power) f).getParameter1(), ((Multiplication)((Power)f).getParameter2()).getParameter2())); + result.add(a); + return result; + } + } + + return null; + } +} diff --git a/src/main/resources/rules/FractionsRule8.java b/src/main/resources/rules/FractionsRule8.java new file mode 100644 index 00000000..932e2fa1 --- /dev/null +++ b/src/main/resources/rules/FractionsRule8.java @@ -0,0 +1,69 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule8 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + +import java.math.BigDecimal; + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * -a/-b = a/b + * + * @author Andrea Cavalli + * + */ +public class FractionsRule8 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule8"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof Division) { + MathContext root = f.getMathContext(); + Division div = (Division) f; + if (div.getParameter1() instanceof Multiplication && ((Multiplication)div.getParameter1()).isNegative()) { + if (div.getParameter2() instanceof Multiplication && ((Multiplication)div.getParameter2()).isNegative()) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new Division(root, ((Multiplication)div.getParameter1()).toPositive(), ((Multiplication)div.getParameter2()).toPositive())); + return result; + } + } + } + + return null; + } +} diff --git a/src/main/resources/rules/FractionsRule9.java b/src/main/resources/rules/FractionsRule9.java new file mode 100644 index 00000000..4bfe2ed5 --- /dev/null +++ b/src/main/resources/rules/FractionsRule9.java @@ -0,0 +1,67 @@ +/* +SETTINGS: (please don't move this part) + PATH=FractionsRule9 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + +import java.math.BigDecimal; + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * (-a)/b = -(a/b) + * + * @author Andrea Cavalli + * + */ +public class FractionsRule9 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "FractionsRule9"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof Division) { + MathContext root = f.getMathContext(); + Division div = (Division) f; + if (div.getParameter1() instanceof Multiplication && ((Multiplication)div.getParameter1()).isNegative()) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(Multiplication.newNegative(root, new Division(root, ((Multiplication)div.getParameter1()).toPositive(), div.getParameter2()))); + return result; + } + } + + return null; + } +} diff --git a/src/main/resources/rules/NumberRule1.java b/src/main/resources/rules/NumberRule1.java new file mode 100644 index 00000000..1e8bb7b8 --- /dev/null +++ b/src/main/resources/rules/NumberRule1.java @@ -0,0 +1,78 @@ +/* +SETTINGS: (please don't move this part) + PATH=NumberRule1 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a * 0 = 0 + * + * @author Andrea Cavalli + * + */ +public class NumberRule1 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "NumberRule1"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Multiplication) { + MathContext root = f.getMathContext(); + FunctionOperator mult = (FunctionOperator) f; + if (mult.getParameter1() instanceof Number) { + Function numb = mult.getParameter1(); + if (numb.equals(new Number(root, 0))) { + isExecutable = true; + } + } + if (mult.getParameter2() instanceof Number) { + Function numb = mult.getParameter2(); + if (numb.equals(new Number(root, 0))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new Number(f.getMathContext(), 0)); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/NumberRule2.java b/src/main/resources/rules/NumberRule2.java new file mode 100644 index 00000000..6020915f --- /dev/null +++ b/src/main/resources/rules/NumberRule2.java @@ -0,0 +1,97 @@ +/* +SETTINGS: (please don't move this part) + PATH=NumberRule2 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a * 1 = a + * + * @author Andrea Cavalli + * + */ +public class NumberRule2 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "NumberRule2"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Multiplication) { + MathContext root = f.getMathContext(); + Multiplication mult = (Multiplication) f; + if (mult.getParameter1() instanceof Number) { + Function numb = mult.getParameter1(); + if (numb.equals(new Number(root, 1))) { + isExecutable = true; + } + } + if (mult.getParameter2() instanceof Number) { + Function numb = mult.getParameter2(); + if (numb.equals(new Number(root, 1))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + Function a = null; + boolean aFound = false; + Multiplication mult = (Multiplication) f; + if (aFound == false & mult.getParameter1() instanceof Number) { + Function numb = mult.getParameter1(); + if (numb.equals(new Number(root, 1))) { + a = mult.getParameter2(); + aFound = true; + } + } + if (aFound == false && mult.getParameter2() instanceof Number) { + Function numb = mult.getParameter2(); + if (numb.equals(new Number(root, 1))) { + a = mult.getParameter1(); + aFound = true; + } + } + + result.add(a); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/NumberRule3.java b/src/main/resources/rules/NumberRule3.java new file mode 100644 index 00000000..7800db09 --- /dev/null +++ b/src/main/resources/rules/NumberRule3.java @@ -0,0 +1,94 @@ +/* +SETTINGS: (please don't move this part) + PATH=NumberRule3 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Negative; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a - a = 0 + * -a + a = 0 + * a ± a = {0, 2a} + * + * @author Andrea Cavalli + * + */ +public class NumberRule3 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "NumberRule3"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Subtraction) { + FunctionOperator sub = (FunctionOperator) f; + if (sub.getParameter1().equals(sub.getParameter2())) { + isExecutable = true; + } + } else if (f instanceof Sum) { + FunctionOperator sub = (FunctionOperator) f; + if (sub.getParameter1() instanceof Multiplication) { + if (((FunctionOperator) sub.getParameter1()).getParameter1() instanceof Number && ((FunctionOperator) sub.getParameter1()).getParameter1().equals(new Number(f.getMathContext(), -1))) { + Function neg = ((FunctionOperator) sub.getParameter1()).getParameter2(); + if (neg.equals(sub.getParameter2())) { + isExecutable = true; + } + } + } + } else if (f instanceof SumSubtraction) { + FunctionOperator sub = (FunctionOperator) f; + if (sub.getParameter1().equals(sub.getParameter2())) { + isExecutable = true; + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + if (f instanceof SumSubtraction) { + Function mul = new Multiplication(root, new Number(root, 2), ((FunctionOperator) f).getParameter1()); + result.add(mul); + } + result.add(new Number(root, 0)); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/NumberRule4.java b/src/main/resources/rules/NumberRule4.java new file mode 100644 index 00000000..ad722b28 --- /dev/null +++ b/src/main/resources/rules/NumberRule4.java @@ -0,0 +1,69 @@ +/* +SETTINGS: (please don't move this part) + PATH=NumberRule4 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a ± b = {a+b, a-b} + * + * @author Andrea Cavalli + * + */ +public class NumberRule4 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "NumberRule4"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof SumSubtraction) { + isExecutable = true; + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator ss = (FunctionOperator) f; + result.add(new Sum(root, ss.getParameter1(), ss.getParameter2())); + result.add(new Subtraction(root, ss.getParameter1(), ss.getParameter2())); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/NumberRule5.java b/src/main/resources/rules/NumberRule5.java new file mode 100644 index 00000000..66aaab42 --- /dev/null +++ b/src/main/resources/rules/NumberRule5.java @@ -0,0 +1,89 @@ +/* +SETTINGS: (please don't move this part) + PATH=NumberRule5 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +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.Number; +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.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a + 0 = a + * 0 + a = a + * a - 0 = a + * 0 - a = -a + * a ± 0 = a + * + * @author Andrea Cavalli + * + */ +public class NumberRule5 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "NumberRule5"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Sum || f instanceof Subtraction || f instanceof SumSubtraction) { + MathContext root = f.getMathContext(); + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1().equals(new Number(root, 0)) || fnc.getParameter2().equals(new Number(root, 0))) { + if (!(fnc.getParameter1().equals(new Number(root, 0)) && f instanceof SumSubtraction)) { + isExecutable = true; + } + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator fnc = (FunctionOperator) f; + Function a = fnc.getParameter1(); + if (a.equals(new Number(root, 0))) { + if (f instanceof Subtraction) { + a = new Multiplication(root, new Number(root, -1), fnc.getParameter2()); + } else { + a = fnc.getParameter2(); + } + } + result.add(a); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/NumberRule7.java b/src/main/resources/rules/NumberRule7.java new file mode 100644 index 00000000..74b2be67 --- /dev/null +++ b/src/main/resources/rules/NumberRule7.java @@ -0,0 +1,68 @@ +/* +SETTINGS: (please don't move this part) + PATH=NumberRule7 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Number rule + * a + a = 2a + * + * @author Andrea Cavalli + * + */ +public class NumberRule7 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "NumberRule7"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXPANSION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Sum) { + isExecutable = ((FunctionOperator) f).getParameter1().equals(((FunctionOperator) f).getParameter2()); + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + Function mult = new Multiplication(root, new Number(root, 2), ((FunctionOperator) f).getParameter1()); + result.add(mult); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/UndefinedRule1.java b/src/main/resources/rules/UndefinedRule1.java new file mode 100644 index 00000000..29f27e52 --- /dev/null +++ b/src/main/resources/rules/UndefinedRule1.java @@ -0,0 +1,71 @@ +/* +SETTINGS: (please don't move this part) + PATH=UndefinedRule1 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Power; +import org.warp.picalculator.math.functions.Undefined; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Undefined rule + * 0^0=undefined + * + * @author Andrea Cavalli + * + */ +public class UndefinedRule1 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "UndefinedRule1"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXISTENCE; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Power) { + MathContext root = f.getMathContext(); + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1().equals(new Number(root, 0)) && fnc.getParameter2().equals(new Number(root, 0))) { + isExecutable = true; + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new Undefined(root)); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/UndefinedRule2.java b/src/main/resources/rules/UndefinedRule2.java new file mode 100644 index 00000000..5e61c2e9 --- /dev/null +++ b/src/main/resources/rules/UndefinedRule2.java @@ -0,0 +1,74 @@ +/* +SETTINGS: (please don't move this part) + PATH=UndefinedRule2 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +import org.warp.picalculator.Error; +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Undefined; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Undefined rule + * a / 0 = undefined + * + * @author Andrea Cavalli + * + */ +public class UndefinedRule2 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "UndefinedRule2"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.EXISTENCE; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Division) { + MathContext root = f.getMathContext(); + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter2() instanceof Number) { + Number numb = (Number) fnc.getParameter2(); + if (numb.equals(new Number(root, 0))) { + isExecutable = true; + } + } + } + + if (isExecutable) { + MathContext root = f.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + result.add(new Undefined(root)); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/VariableRule1.java b/src/main/resources/rules/VariableRule1.java new file mode 100644 index 00000000..2729978e --- /dev/null +++ b/src/main/resources/rules/VariableRule1.java @@ -0,0 +1,98 @@ +/* +SETTINGS: (please don't move this part) + PATH=VariableRule1 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +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.Subtraction; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Variable rule + * ax+bx=(a+b)*x (a,b NUMBER; x VARIABLE|MULTIPLICATION) + * + * @author Andrea Cavalli + * + */ +public class VariableRule1 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "VariableRule1"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.REDUCTION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Subtraction || f instanceof Sum) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Multiplication & fnc.getParameter2() instanceof Multiplication) { + FunctionOperator m1 = (FunctionOperator) fnc.getParameter1(); + FunctionOperator m2 = (FunctionOperator) fnc.getParameter2(); + if (m1.getParameter1().equals(m2.getParameter1()) || m1.getParameter2().equals(m2.getParameter2())) { + isExecutable = true; + } + } + } + + if (isExecutable) { + FunctionOperator fnc = (FunctionOperator) f; + MathContext root = fnc.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator m1 = (FunctionOperator) fnc.getParameter1(); + FunctionOperator m2 = (FunctionOperator) fnc.getParameter2(); + Function a; + Function b; + Function x; + if (m1.getParameter2().equals(m2.getParameter2())) { + x = m1.getParameter2(); + a = m1.getParameter1(); + b = m2.getParameter1(); + } else { + x = m1.getParameter1(); + a = m1.getParameter2(); + b = m2.getParameter2(); + } + + Function rets; + if (fnc instanceof Sum) { + rets = new Sum(root, a, b); + } else { + rets = new Subtraction(root, a, b); + } + Function retm = new Multiplication(root, rets, x); + result.add(retm); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/VariableRule2.java b/src/main/resources/rules/VariableRule2.java new file mode 100644 index 00000000..838b0b3f --- /dev/null +++ b/src/main/resources/rules/VariableRule2.java @@ -0,0 +1,87 @@ +/* +SETTINGS: (please don't move this part) + PATH=VariableRule2 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +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.Number; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Variable rule + * ax+x=(a+1)*x (a,b NUMBER; x VARIABLES) + * + * @author Andrea Cavalli + * + */ +public class VariableRule2 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "VariableRule2"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.REDUCTION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Sum || f instanceof Subtraction) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter1() instanceof Multiplication) { + FunctionOperator m1 = (FunctionOperator) fnc.getParameter1(); + if (m1.getParameter2().equals(fnc.getParameter2())) { + isExecutable = true; + } + } + } + + if (isExecutable) { + FunctionOperator fnc = (FunctionOperator) f; + MathContext root = fnc.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator m1 = (FunctionOperator) fnc.getParameter1(); + Function a = m1.getParameter1(); + Function x = fnc.getParameter2(); + + Function rets; + if (fnc instanceof Sum) { + rets = new Sum(root, a, new Number(root, 1)); + } else { + rets = new Subtraction(root, a, new Number(root, 1)); + } + Function retm = new Multiplication(root, rets, x); + result.add(retm); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/VariableRule3.java b/src/main/resources/rules/VariableRule3.java new file mode 100644 index 00000000..60557558 --- /dev/null +++ b/src/main/resources/rules/VariableRule3.java @@ -0,0 +1,88 @@ +/* +SETTINGS: (please don't move this part) + PATH=VariableRule3 +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; +//Imports + + +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.Number; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +/** + * Variable rule + * x+ax=(a+1)*x (a,b NUMBER; x VARIABLES) + * + * @author Andrea Cavalli + * + */ +public class VariableRule3 implements Rule { + // Rule name + @Override + public String getRuleName() { + return "VariableRule3"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.REDUCTION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + + @Override + public ObjectArrayList execute(Function f) { + boolean isExecutable = false; + if (f instanceof Sum || f instanceof Subtraction) { + FunctionOperator fnc = (FunctionOperator) f; + if (fnc.getParameter2() instanceof Multiplication) { + FunctionOperator m2 = (FunctionOperator) fnc.getParameter2(); + if (m2.getParameter2().equals(fnc.getParameter1())) { + isExecutable = true; + } + } + } + + if (isExecutable) { + FunctionOperator fnc = (FunctionOperator) f; + MathContext root = fnc.getMathContext(); + ObjectArrayList result = new ObjectArrayList<>(); + FunctionOperator m2 = (FunctionOperator) fnc.getParameter2(); + Function a = m2.getParameter1(); + Function x = fnc.getParameter1(); + + Function rets; + if (fnc instanceof Sum) { + rets = new Sum(root, new Number(root, 1), a); + } else { + rets = new Subtraction(root, new Number(root, 1), a); + } + + Function retm = new Multiplication(root, rets, x); + result.add(retm); + return result; + } else { + return null; + } + } +} diff --git a/src/main/resources/rules/functions/DivisionRule.java b/src/main/resources/rules/functions/DivisionRule.java new file mode 100644 index 00000000..421e8845 --- /dev/null +++ b/src/main/resources/rules/functions/DivisionRule.java @@ -0,0 +1,93 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.DivisionRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +import java.math.BigInteger; +import java.util.LinkedList; + +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.Error; + +/** + * Division + * a/b = c + * + * @author Andrea Cavalli + * + */ +public class DivisionRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Division"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) throws Error { + if (f instanceof Division) { + ObjectArrayList result = new ObjectArrayList<>(); + Function variable1 = ((FunctionOperator) f).getParameter1(); + Function variable2 = ((FunctionOperator) f).getParameter2(); + MathContext mathContext = f.getMathContext(); + if (variable1 instanceof Number && variable2 instanceof Number) { + if (mathContext.exactMode) { + if (((Number)variable1).isInteger() && ((Number)variable2).isInteger()) { + LinkedList factors1, factors2, mcm; + try { + factors1 = ((Number)variable1).getFactors(); + factors2 = ((Number)variable2).getFactors(); + mcm = ScriptUtils.mcm(factors1, factors2); + } catch (Exception ex) { + return null; + } + if (mcm.size() > 0) { //true if there is at least one common factor + //divide by the common factor (ab/cb = a/c) + BigInteger nmb1 = ((Number)variable1).getTerm().toBigIntegerExact(); + BigInteger nmb2 = ((Number)variable2).getTerm().toBigIntegerExact(); + for (BigInteger integerNumber : mcm) { + nmb1 = nmb1.divide(integerNumber); + 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(((Number)variable1).divide((Number)variable2)); + return result; + } + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/EmptyNumberRule.java b/src/main/resources/rules/functions/EmptyNumberRule.java new file mode 100644 index 00000000..cc16c080 --- /dev/null +++ b/src/main/resources/rules/functions/EmptyNumberRule.java @@ -0,0 +1,47 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.EmptyNumberRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; + +/** + * EmptyNumber + * + * + * @author Andrea Cavalli + * + */ +public class EmptyNumberRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "EmptyNumber"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + return null; + } +} diff --git a/src/main/resources/rules/functions/ExpressionRule.java b/src/main/resources/rules/functions/ExpressionRule.java new file mode 100644 index 00000000..77e4e23a --- /dev/null +++ b/src/main/resources/rules/functions/ExpressionRule.java @@ -0,0 +1,58 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.ExpressionRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Expression; + +/** + * Expression + * (x) = x + * + * @author Andrea Cavalli + * + */ +public class ExpressionRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Expression"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof Expression) { + ObjectArrayList result = new ObjectArrayList<>(); + result.add(f.getParameter(0)); + return result; + } + return null; + } +} diff --git a/src/main/resources/rules/functions/JokeRule.java b/src/main/resources/rules/functions/JokeRule.java new file mode 100644 index 00000000..8fd724a1 --- /dev/null +++ b/src/main/resources/rules/functions/JokeRule.java @@ -0,0 +1,47 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.JokeRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; + +/** + * Joke + * + * + * @author Andrea Cavalli + * + */ +public class JokeRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Joke"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + return null; + } +} diff --git a/src/main/resources/rules/functions/MultiplicationRule.java b/src/main/resources/rules/functions/MultiplicationRule.java new file mode 100644 index 00000000..5c584a88 --- /dev/null +++ b/src/main/resources/rules/functions/MultiplicationRule.java @@ -0,0 +1,64 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.MultiplicationRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Division; + +/** + * Multiplication + * a*b = c + * + * @author Andrea Cavalli + * + */ +public class MultiplicationRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Multiplication"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof Multiplication) { + ObjectArrayList result = new ObjectArrayList<>(); + Function variable1 = ((Multiplication) f).getParameter1(); + Function variable2 = ((Multiplication) f).getParameter2(); + MathContext mathContext = f.getMathContext(); + if (variable1 instanceof Number && variable2 instanceof Number) { + //multiply a by b (a*b = c) + result.add(((Number)variable1).multiply((Number)variable2)); + return result; + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/NegativeRule.java b/src/main/resources/rules/functions/NegativeRule.java new file mode 100644 index 00000000..a0276af2 --- /dev/null +++ b/src/main/resources/rules/functions/NegativeRule.java @@ -0,0 +1,74 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.NegativeRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Negative; +import org.warp.picalculator.Error; +import org.warp.picalculator.Errors; +import java.lang.NullPointerException; +import java.lang.NumberFormatException; +import java.lang.ArithmeticException; + +/** + * Negative + * -a = b + * + * @author Andrea Cavalli + * + */ +public class NegativeRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Negative"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) throws Error { + if (f instanceof Negative) { + ObjectArrayList result = new ObjectArrayList<>(); + Function variable = ((Negative)f).getParameter(); + MathContext mathContext = f.getMathContext(); + if (variable instanceof Number) { + //-a = a*-1 = b + try { + result.add(((Number)variable).multiply(new Number(mathContext, -1))); + } catch (Exception ex) { + if (ex instanceof NullPointerException) { + throw new Error(Errors.ERROR); + } else if (ex instanceof NumberFormatException) { + throw new Error(Errors.SYNTAX_ERROR); + } else if (ex instanceof ArithmeticException) { + throw new Error(Errors.NUMBER_TOO_SMALL); + } + } + return result; + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/NumberRule.java b/src/main/resources/rules/functions/NumberRule.java new file mode 100644 index 00000000..2f262ca7 --- /dev/null +++ b/src/main/resources/rules/functions/NumberRule.java @@ -0,0 +1,63 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.NumberRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Number; +import java.math.BigInteger; + +/** + * Number + * + * + * @author Andrea Cavalli + * + */ +public class NumberRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Number"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof Number) { + ObjectArrayList result = new ObjectArrayList<>(); + MathContext mathContext = f.getMathContext(); + if (mathContext.exactMode) { + if (((Number)f).isInteger() == false) { + Number divisor = new Number(mathContext, BigInteger.TEN.pow(((Number)f).getNumberOfDecimalPlaces())); + Function number = new Number(mathContext, ((Number)f).getTerm().multiply(divisor.getTerm())); + Function div = new Division(mathContext, number, divisor); + result.add(div); + return result; + } + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/PowerRule.java b/src/main/resources/rules/functions/PowerRule.java new file mode 100644 index 00000000..04d1e1bd --- /dev/null +++ b/src/main/resources/rules/functions/PowerRule.java @@ -0,0 +1,69 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.PowerRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Power; + +/** + * Power + * a^b = c + * + * @author Andrea Cavalli + * + */ +public class PowerRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Power"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) throws org.warp.picalculator.Error, InterruptedException { + if (f instanceof Power) { + ObjectArrayList result = new ObjectArrayList<>(); + Function variable1 = ((FunctionOperator)f).getParameter1(); + Function variable2 = ((FunctionOperator)f).getParameter2(); + MathContext mathContext = f.getMathContext(); + if (variable1 instanceof Number && variable2 instanceof Number) { + //a^b = c + Number out = ((Number)variable1).pow((Number)variable2); + if (mathContext.exactMode && !out.isInteger()) { + return null; + } + result.add(out); + return result; + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/RootRule.java b/src/main/resources/rules/functions/RootRule.java new file mode 100644 index 00000000..243c817a --- /dev/null +++ b/src/main/resources/rules/functions/RootRule.java @@ -0,0 +1,97 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.RootRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +import org.warp.picalculator.Error; +import org.warp.picalculator.Errors; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Division; +import org.warp.picalculator.math.functions.Root; +import org.warp.picalculator.math.functions.RootSquare; +import java.math.BigDecimal; +import java.math.BigInteger; + +/** + * Root + * a√b = c + * + * @author Andrea Cavalli + * + */ +public class RootRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Root"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) throws Error, InterruptedException { + boolean isSquare = false; + if ((isSquare = f instanceof RootSquare) || f instanceof Root) { + ObjectArrayList result = new ObjectArrayList<>(); + MathContext mathContext = f.getMathContext(); + Function variable1 = ((FunctionOperator)f).getParameter1(); + Function variable2 = ((FunctionOperator)f).getParameter2(); + boolean isSolvable = false, canBePorted = false; + if (variable1 instanceof Number && variable2 instanceof Number) { + if (mathContext.exactMode) { + result.add(((Number)variable1).pow(new Number(mathContext, BigDecimal.ONE).divide(((Number)variable1)))); + return result; + } + isSolvable = isSolvable|!mathContext.exactMode; + if (!isSolvable) { + try { + Function resultVar = ((Number)variable2).pow(new Number(mathContext, BigDecimal.ONE).divide(((Number)variable1))); + Function originalVariable = ((Number)resultVar).pow(new Number(mathContext, 2)); + if ((originalVariable).equals(((FunctionOperator)f).getParameter2())) { + isSolvable = true; + } + } catch (Exception ex) { + throw (Error) new Error(Errors.ERROR, ex.getMessage()).initCause(ex); + } + } + } + if (!isSquare && !isSolvable && variable1 instanceof Number && variable1.equals(new Number(mathContext, 2))) { + canBePorted = true; + } + + if (isSolvable) { + result.add(((Number)variable2).pow(new Number(mathContext, BigInteger.ONE).divide((Number)variable1))); + return result; + } + if (canBePorted) { + result.add(new RootSquare(mathContext, variable2)); + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/SubtractionRule.java b/src/main/resources/rules/functions/SubtractionRule.java new file mode 100644 index 00000000..483f332a --- /dev/null +++ b/src/main/resources/rules/functions/SubtractionRule.java @@ -0,0 +1,64 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.SubtractionRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Division; + +/** + * Subtraction + * a-b = c + * + * @author Andrea Cavalli + * + */ +public class SubtractionRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Subtraction"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof Subtraction) { + ObjectArrayList result = new ObjectArrayList<>(); + Function variable1 = ((FunctionOperator)f).getParameter1(); + Function variable2 = ((FunctionOperator)f).getParameter2(); + MathContext mathContext = f.getMathContext(); + if (variable1 instanceof Number && variable2 instanceof Number) { + //a-b = a+(b*-1) = c + result.add(((Number)variable1).add(((Number)variable2).multiply(new Number(mathContext, -1)))); + return result; + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/SumRule.java b/src/main/resources/rules/functions/SumRule.java new file mode 100644 index 00000000..6a97c737 --- /dev/null +++ b/src/main/resources/rules/functions/SumRule.java @@ -0,0 +1,64 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.SumRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Division; + +/** + * Sum + * a+b = c + * + * @author Andrea Cavalli + * + */ +public class SumRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Sum"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof Sum) { + ObjectArrayList result = new ObjectArrayList<>(); + Function variable1 = ((FunctionOperator)f).getParameter1(); + Function variable2 = ((FunctionOperator)f).getParameter2(); + MathContext mathContext = f.getMathContext(); + if (variable1 instanceof Number && variable2 instanceof Number) { + //a+b = c + result.add(((Number)variable1).add(((Number)variable2))); + return result; + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/SumSubtractionRule.java b/src/main/resources/rules/functions/SumSubtractionRule.java new file mode 100644 index 00000000..7c78a526 --- /dev/null +++ b/src/main/resources/rules/functions/SumSubtractionRule.java @@ -0,0 +1,65 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.SumSubtractionRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.SumSubtraction; +import org.warp.picalculator.math.functions.Number; +import org.warp.picalculator.math.functions.Division; + +/** + * SumSumbraction + * a±b = c, d + * + * @author Andrea Cavalli + * + */ +public class SumSubtractionRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "SumSubtraction"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) { + if (f instanceof SumSubtraction) { + ObjectArrayList result = new ObjectArrayList<>(); + Function variable1 = ((FunctionOperator)f).getParameter1(); + Function variable2 = ((FunctionOperator)f).getParameter2(); + MathContext mathContext = f.getMathContext(); + if (variable1 instanceof Number && variable2 instanceof Number) { + //a±b = c, d + result.add(((Number)variable1).add((Number)variable2)); + result.add(((Number)variable1).add(((Number)variable2).multiply(new Number(mathContext, -1)))); + return result; + } + } + return null; + } +} diff --git a/src/main/resources/rules/functions/VariableRule.java b/src/main/resources/rules/functions/VariableRule.java new file mode 100644 index 00000000..1044be58 --- /dev/null +++ b/src/main/resources/rules/functions/VariableRule.java @@ -0,0 +1,69 @@ +/* +SETTINGS: (please don't move this part) + PATH=functions.VariableRule +*/ + +import org.warp.picalculator.math.Function; +import org.warp.picalculator.math.FunctionOperator; +import org.warp.picalculator.math.FunctionDynamic; +import org.warp.picalculator.math.FunctionSingle; +import org.warp.picalculator.math.MathContext; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.nevec.rjm.BigDecimalMath; +import org.warp.picalculator.Utils; +import org.warp.picalculator.math.MathematicalSymbols; +import org.warp.picalculator.Error; +import org.warp.picalculator.ScriptUtils; +import org.warp.picalculator.math.rules.Rule; +import org.warp.picalculator.math.rules.RuleType; +import org.warp.picalculator.math.rules.RulesManager; +import org.warp.picalculator.math.functions.Multiplication; +import org.warp.picalculator.math.functions.Sum; +import org.warp.picalculator.math.functions.Subtraction; +import org.warp.picalculator.math.functions.Variable; +import org.warp.picalculator.math.functions.Variable.V_TYPE; +import org.warp.picalculator.math.functions.Number; + +/** + * Variable + * a = n + * + * @author Andrea Cavalli + * + */ +public class VariableRule implements Rule { + // Rule name + @Override + public String getRuleName() { + return "Variable"; + } + + // Rule type + @Override + public RuleType getRuleType() { + return RuleType.CALCULATION; + } + + /* Rule function + Returns: + - null if it's not executable on the function "f" + - An ObjectArrayList if it did something + */ + @Override + public ObjectArrayList execute(Function f) throws Error { + if (f instanceof Variable) { + ObjectArrayList result = new ObjectArrayList<>(); + Character variable = ((Variable)f).getChar(); + MathContext mathContext = f.getMathContext(); + if (mathContext.exactMode == false) { + if (variable.equals(MathematicalSymbols.PI)) { + //a = n + result.add(new Number(mathContext, BigDecimalMath.pi(new java.math.MathContext(Utils.scale, Utils.scaleMode2)))); + return result; + } + } + } + return null; + } +} diff --git a/src/main/resources/skin.png b/src/main/resources/skin.png index ccb300f0..0acf4d2a 100755 Binary files a/src/main/resources/skin.png and b/src/main/resources/skin.png differ diff --git a/src/main/resources/skin.xcf b/src/main/resources/skin.xcf index a60a5df5..f1d9b9b0 100755 Binary files a/src/main/resources/skin.xcf and b/src/main/resources/skin.xcf differ