2018-09-02 13:36:49 +02:00
package it.cavallium.warppi.math.rules ;
2017-12-21 23:21:29 +01:00
import java.io.File ;
import java.io.IOException ;
2017-12-23 01:14:38 +01:00
import java.io.InputStream ;
2019-02-10 19:59:38 +01:00
import java.util.stream.Stream ;
2018-05-09 22:54:00 +02:00
2018-09-04 12:12:41 +02:00
import it.cavallium.warppi.Engine ;
2018-09-12 22:16:33 +02:00
import it.cavallium.warppi.Platform.ConsoleUtils ;
2018-09-22 11:17:30 +02:00
import it.cavallium.warppi.Platform.StorageUtils ;
2018-09-02 13:36:49 +02:00
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 ;
2019-01-30 21:42:35 +01:00
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-02-10 19:59:38 +01:00
import it.cavallium.warppi.math.rules.functions.* ;
2018-09-02 13:36:49 +02:00
import it.cavallium.warppi.math.solver.MathSolver ;
2018-09-12 22:16:33 +02:00
import it.cavallium.warppi.util.Error ;
2017-12-21 23:21:29 +01:00
import it.unimi.dsi.fastutil.objects.ObjectArrayList ;
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
2018-09-22 11:17:30 +02:00
@SuppressWarnings ( { " unchecked " } )
2017-12-21 23:21:29 +01:00
public static void initialize ( ) {
2018-09-04 12:12:41 +02:00
Engine . 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-02-11 15:55:29 +01:00
if ( Engine . getPlatform ( ) . isJavascript ( ) ) {
Engine . getPlatform ( ) . loadPlatformRules ( ) ;
} else {
2018-06-11 22:41:11 +02:00
try {
2019-02-11 15:55:29 +01:00
loadDslRules ( ) ;
} catch ( IOException | DslAggregateException e ) {
e . printStackTrace ( ) ;
Engine . getPlatform ( ) . exit ( 1 ) ;
2018-09-28 11:39:28 +02:00
}
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 SubtractionRule ( ) ,
new SumRule ( ) ,
new SumSubtractionRule ( ) ,
new VariableRule ( )
) . forEach ( RulesManager : : addRule ) ;
}
2019-01-30 21:42:35 +01:00
private static void loadDslRules ( ) throws IOException , DslAggregateException {
2019-01-28 18:19:27 +01:00
final StorageUtils storageUtils = Engine . getPlatform ( ) . getStorageUtils ( ) ;
final File dslRulesPath = storageUtils . get ( " rules/dsl/ " ) ;
if ( ! dslRulesPath . exists ( ) ) {
return ;
}
for ( final File file : storageUtils . walk ( dslRulesPath ) ) {
if ( ! file . toString ( ) . endsWith ( " .rules " ) ) {
continue ;
}
Engine . getPlatform ( ) . getConsoleUtils ( ) . out ( ) . println (
ConsoleUtils . OUTPUTLEVEL_NODEBUG ,
" RulesManager " ,
" Found DSL rules file: " + file . getAbsolutePath ( )
) ;
final String source ;
try ( final InputStream resource = storageUtils . getResourceStream ( file . toString ( ) ) ) {
source = storageUtils . read ( resource ) ;
}
RulesDsl . makeRules ( source ) . forEach ( RulesManager : : addRule ) ;
}
}
2018-03-25 12:36:22 +02:00
public static void warmUp ( ) throws Error , InterruptedException {
2017-12-23 15:20:42 +01:00
ObjectArrayList < Function > uselessResult = null ;
2018-02-05 00:05:31 +01:00
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 ) {
2018-02-05 00:05:31 +01:00
String ruleName = " <null> " ;
try {
ruleName = rule . getRuleName ( ) ;
2018-09-22 11:17:30 +02:00
final ObjectArrayList < Function > uselessResult2 = rule . execute ( RulesManager . generateUselessExpression ( ) ) ;
2018-02-05 00:05:31 +01:00
uselessVariable = ( uselessResult = = null ? new ObjectArrayList < > ( ) : uselessResult ) . equals ( uselessResult2 ) ;
uselessResult = uselessResult2 ;
2018-05-12 21:18:29 +02:00
} catch ( final Exception e ) {
2018-02-05 00:05:31 +01:00
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 ) ;
2018-09-11 01:12:54 +02:00
Engine . getPlatform ( ) . getConsoleUtils ( ) . out ( ) . println ( ConsoleUtils . OUTPUTLEVEL_DEBUG_MIN , " RulesManager " , rule . getRuleName ( ) , " Loaded as " + rule . getRuleType ( ) + " rule " ) ;
2017-12-21 23:21:29 +01:00
}
}