WarpPI/core/src/main/java/it/cavallium/warppi/math/rules/RulesManager.java

142 lines
4.6 KiB
Java
Raw Normal View History

package it.cavallium.warppi.math.rules;
2017-12-21 23:21:29 +01:00
2019-08-09 20:51:31 +02:00
import it.cavallium.warppi.Platform;
import it.cavallium.warppi.Platform.ConsoleUtils;
import it.cavallium.warppi.WarpPI;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.functions.Expression;
import it.cavallium.warppi.math.functions.Variable;
import it.cavallium.warppi.math.functions.Variable.V_TYPE;
import it.cavallium.warppi.math.rules.dsl.DslAggregateException;
2019-01-28 18:19:27 +01:00
import it.cavallium.warppi.math.rules.dsl.RulesDsl;
2019-08-06 19:01:00 +02:00
import it.cavallium.warppi.math.rules.dsl.errorutils.DslFilesException;
2019-02-10 19:59:38 +01:00
import it.cavallium.warppi.math.rules.functions.*;
import it.cavallium.warppi.math.solver.MathSolver;
import it.cavallium.warppi.util.Error;
2017-12-21 23:21:29 +01:00
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
2019-08-09 20:51:31 +02:00
import java.io.IOException;
import java.io.InputStream;
import java.util.stream.Stream;
2017-12-21 23:21:29 +01:00
public class RulesManager {
2018-05-12 21:18:29 +02:00
2017-12-21 23:21:29 +01:00
public static ObjectArrayList<Rule>[] rules;
2018-05-12 21:18:29 +02:00
private RulesManager() {
}
2017-12-21 23:21:29 +01:00
@SuppressWarnings({"unchecked"})
2017-12-21 23:21:29 +01:00
public static void initialize() {
2019-02-27 23:29:03 +01:00
WarpPI.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Loading the rules");
2018-09-22 11:17:30 +02:00
RulesManager.rules = new ObjectArrayList[RuleType.values().length];
2018-09-28 11:39:28 +02:00
for (final RuleType val : RuleType.values()) {
2018-09-22 11:17:30 +02:00
RulesManager.rules[val.ordinal()] = new ObjectArrayList<>();
2018-09-28 11:39:28 +02:00
}
2019-01-28 18:19:27 +01:00
2019-02-10 19:59:38 +01:00
loadBuiltinRules();
2019-08-09 20:51:31 +02:00
try {
loadDslRules();
} catch (IOException | DslFilesException e) {
e.printStackTrace();
if (e instanceof DslFilesException) {
System.err.println();
2019-08-09 20:51:31 +02:00
System.err.print(((DslFilesException) e).format());
2018-09-28 11:39:28 +02:00
}
2019-11-01 18:04:01 +01:00
WarpPI.getPlatform().exit(1);
2017-12-21 23:21:29 +01:00
}
}
2018-05-12 21:18:29 +02:00
2019-02-10 19:59:38 +01:00
private static void loadBuiltinRules() {
Stream.of(
new DivisionRule(),
new EmptyNumberRule(),
new ExpressionRule(),
new JokeRule(),
new MultiplicationRule(),
new NegativeRule(),
new NumberRule(),
new PowerRule(),
new RootRule(),
new RootSquareRule(),
new SubtractionRule(),
new SumRule(),
new SumSubtractionRule(),
new VariableRule()
2019-02-10 19:59:38 +01:00
).forEach(RulesManager::addRule);
}
2019-08-06 19:01:00 +02:00
private static void loadDslRules() throws IOException, DslFilesException {
2019-11-01 18:04:01 +01:00
final Platform platform = WarpPI.getPlatform();
2019-01-28 18:19:27 +01:00
2019-08-06 19:01:00 +02:00
final DslFilesException fileErrors = new DslFilesException();
2019-08-09 20:51:31 +02:00
for (final String path : platform.getRuleFilePaths()) {
platform.getConsoleUtils().out().println(
ConsoleUtils.OUTPUTLEVEL_NODEBUG,
"RulesManager",
"Found DSL rules file: " + path
2019-01-28 18:19:27 +01:00
);
final String source;
2019-08-09 20:51:31 +02:00
try (final InputStream resource = platform.getStorageUtils().getResourceStream(path)) {
source = platform.getStorageUtils().read(resource);
2019-01-28 18:19:27 +01:00
}
2019-08-06 19:01:00 +02:00
try {
2019-08-09 20:51:31 +02:00
// This loop used to be written as RulesDsl.makeRules(source).forEach(RulesManager::addRule),
// but the forEach method hangs on TeaVM.
for (Rule rule : RulesDsl.makeRules(source)) {
addRule(rule);
}
2019-08-06 19:01:00 +02:00
} catch (DslAggregateException e) {
2019-08-09 20:51:31 +02:00
fileErrors.addFileErrors(path, source, e.getErrors());
2019-08-06 19:01:00 +02:00
}
}
if (fileErrors.hasErrors()) {
throw fileErrors;
2019-01-28 18:19:27 +01:00
}
}
public static void warmUp() throws Error, InterruptedException {
2017-12-23 15:20:42 +01:00
ObjectArrayList<Function> uselessResult = null;
boolean uselessVariable = false;
2018-05-12 21:18:29 +02:00
for (final RuleType val : RuleType.values()) {
2018-09-22 11:17:30 +02:00
final ObjectArrayList<Rule> ruleList = RulesManager.rules[val.ordinal()];
2017-12-23 15:20:42 +01:00
for (final Rule rule : ruleList) {
String ruleName = "<null>";
try {
ruleName = rule.getRuleName();
2018-09-22 11:17:30 +02:00
final ObjectArrayList<Function> uselessResult2 = rule.execute(RulesManager.generateUselessExpression());
uselessVariable = (uselessResult == null ? new ObjectArrayList<>() : uselessResult).equals(uselessResult2);
uselessResult = uselessResult2;
2018-05-12 21:18:29 +02:00
} catch (final Exception e) {
if (uselessVariable || true) {
System.err.println("Exception thrown by rule '" + ruleName + "'!");
e.printStackTrace();
}
}
2017-12-23 15:20:42 +01:00
}
}
try {
2018-09-22 11:17:30 +02:00
new MathSolver(RulesManager.generateUselessExpression()).solveAllSteps();
2017-12-23 15:20:42 +01:00
} catch (InterruptedException | Error e) {
e.printStackTrace();
}
}
2018-05-12 21:18:29 +02:00
2017-12-24 11:59:09 +01:00
private static Function generateUselessExpression() {
2018-05-12 21:18:29 +02:00
final 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;
}
2018-05-12 21:18:29 +02:00
2018-09-22 11:17:30 +02:00
public static void addRule(final Rule rule) {
RulesManager.rules[rule.getRuleType().ordinal()].add(rule);
2019-02-27 23:29:03 +01:00
WarpPI.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", rule.getRuleName(), "Loaded as " + rule.getRuleType() + " rule");
2017-12-21 23:21:29 +01:00
}
}