2017-12-21 23:21:29 +01:00
|
|
|
package org.warp.picalculator.math.rules;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileNotFoundException;
|
|
|
|
import java.io.FileReader;
|
|
|
|
import java.io.IOException;
|
2017-12-23 01:14:38 +01:00
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.io.Reader;
|
|
|
|
import java.io.Writer;
|
|
|
|
import java.net.URI;
|
2017-12-21 23:21:29 +01:00
|
|
|
import java.net.URISyntaxException;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.nio.file.Paths;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
2017-12-23 01:14:38 +01:00
|
|
|
import javax.script.Bindings;
|
|
|
|
import javax.script.ScriptContext;
|
2017-12-21 23:21:29 +01:00
|
|
|
import javax.script.ScriptEngine;
|
|
|
|
import javax.script.ScriptEngineManager;
|
|
|
|
import javax.script.ScriptException;
|
|
|
|
|
2017-12-23 15:20:42 +01:00
|
|
|
import org.warp.picalculator.Error;
|
2017-12-21 23:21:29 +01:00
|
|
|
import org.warp.picalculator.StaticVars;
|
2017-12-22 22:39:58 +01:00
|
|
|
import org.warp.picalculator.Utils;
|
2017-12-23 15:20:42 +01:00
|
|
|
import org.warp.picalculator.math.Function;
|
2017-12-21 23:21:29 +01:00
|
|
|
import org.warp.picalculator.math.MathContext;
|
2017-12-23 15:20:42 +01:00
|
|
|
import org.warp.picalculator.math.functions.Expression;
|
2017-12-21 23:21:29 +01:00
|
|
|
import org.warp.picalculator.math.functions.Subtraction;
|
|
|
|
import org.warp.picalculator.math.functions.Sum;
|
|
|
|
import org.warp.picalculator.math.functions.SumSubtraction;
|
|
|
|
import org.warp.picalculator.math.functions.Variable;
|
|
|
|
import org.warp.picalculator.math.functions.Variable.V_TYPE;
|
2018-03-01 09:54:14 +01:00
|
|
|
import org.warp.picalculator.math.solver.MathSolver;
|
2017-12-21 23:21:29 +01:00
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
|
|
|
|
|
|
public class RulesManager {
|
|
|
|
|
|
|
|
public static ObjectArrayList<Rule>[] rules;
|
|
|
|
|
|
|
|
private RulesManager() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
public static void initialize() {
|
|
|
|
rules = new ObjectArrayList[RuleType.values().length];
|
|
|
|
for (RuleType val : RuleType.values()) {
|
|
|
|
rules[val.ordinal()] = new ObjectArrayList<Rule>();
|
|
|
|
}
|
|
|
|
try {
|
2017-12-23 01:14:38 +01:00
|
|
|
final Path rulesPath = Utils.getResource("/rules.csv");
|
2017-12-21 23:21:29 +01:00
|
|
|
if (!Files.exists(rulesPath)) {
|
|
|
|
throw new FileNotFoundException("rules.csv not found!");
|
|
|
|
}
|
|
|
|
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
|
|
|
|
List<String> ruleLines = Files.readAllLines(rulesPath);
|
2017-12-24 11:59:09 +01:00
|
|
|
ruleLines.remove(0); //Remove the headers
|
2017-12-21 23:21:29 +01:00
|
|
|
for (String rulesLine : ruleLines) {
|
2017-12-24 11:59:09 +01:00
|
|
|
if (rulesLine.length() > 0) {
|
|
|
|
String[] ruleDetails = rulesLine.split(",", 1);
|
|
|
|
String ruleName = ruleDetails[0];
|
|
|
|
Utils.out.println("Evaluating /rules/" + ruleName + ".js");
|
|
|
|
InputStream resourcePath = Utils.getResourceStream("/rules/" + ruleName.replace(".", "_") + ".js");
|
|
|
|
if (resourcePath == null) {
|
|
|
|
System.err.println(new FileNotFoundException("/rules/" + ruleName + ".js not found!"));
|
|
|
|
} else {
|
|
|
|
engine.eval(new InputStreamReader(resourcePath));
|
|
|
|
}
|
2017-12-21 23:21:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (URISyntaxException | IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
System.exit(1);
|
|
|
|
} catch (ScriptException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
2017-12-23 15:20:42 +01:00
|
|
|
|
|
|
|
public static void warmUp() {
|
|
|
|
ObjectArrayList<Function> uselessResult = null;
|
2018-02-05 00:05:31 +01:00
|
|
|
boolean uselessVariable = false;
|
2017-12-23 15:20:42 +01:00
|
|
|
for (RuleType val : RuleType.values()) {
|
|
|
|
final ObjectArrayList<Rule> ruleList = rules[val.ordinal()];
|
|
|
|
for (final Rule rule : ruleList) {
|
2018-02-05 00:05:31 +01:00
|
|
|
String ruleName = "<null>";
|
|
|
|
try {
|
|
|
|
ruleName = rule.getRuleName();
|
|
|
|
ObjectArrayList<Function> uselessResult2 = rule.execute(generateUselessExpression());
|
|
|
|
uselessVariable = (uselessResult == null ? new ObjectArrayList<>() : uselessResult).equals(uselessResult2);
|
|
|
|
uselessResult = uselessResult2;
|
|
|
|
} catch (Exception e) {
|
|
|
|
if (uselessVariable || true) {
|
|
|
|
System.err.println("Exception thrown by rule '" + ruleName + "'!");
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
2017-12-23 15:20:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
new MathSolver(generateUselessExpression()).solveAllSteps();
|
|
|
|
} catch (InterruptedException | Error e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-24 11:59:09 +01:00
|
|
|
private static Function generateUselessExpression() {
|
2017-12-23 15:20:42 +01:00
|
|
|
MathContext mc = new MathContext();
|
2017-12-24 11:59:09 +01:00
|
|
|
Function expr = new Expression(mc);
|
|
|
|
expr = expr.setParameter(0, new Variable(mc, 'x', V_TYPE.VARIABLE));
|
2017-12-23 15:20:42 +01:00
|
|
|
return expr;
|
|
|
|
}
|
2017-12-21 23:21:29 +01:00
|
|
|
|
|
|
|
public static void addRule(Rule rule) {
|
2017-12-22 22:39:58 +01:00
|
|
|
rules[rule.getRuleType().ordinal()].add(rule);
|
2018-02-07 22:06:40 +01:00
|
|
|
Utils.out.println(Utils.OUTPUTLEVEL_NODEBUG, "Loaded rule " + rule.getRuleName() + " as " + rule.getRuleType() + " rule.");
|
2017-12-21 23:21:29 +01:00
|
|
|
}
|
|
|
|
}
|