From d74325cbe24bc9b8010c241906d4b79c6bc3dab6 Mon Sep 17 00:00:00 2001 From: "Bernhard J. Berger" <bernhard.berger@uni-bremen.de> Date: Mon, 13 Feb 2023 21:11:09 +0100 Subject: [PATCH] Towards tests. --- src/core/de.evoal.core.junit/pom.xml | 119 ++++++++- src/core/de.evoal.core.main/pom.xml | 7 + .../evoal/core/api/utils/LanguageHelper.java | 77 ++++-- .../main/java/de/evoal/core/main/Evoal.java | 22 +- .../main/language/ModuleBuiltinProvider.java | 3 +- .../core/api/utils/LanguageHelperTest.java | 182 +++++++++++++ .../core/api/utils/LanguageHelperTest.dl | 12 + .../core/api/utils/LanguageHelperTest.ol | 16 ++ .../generator/main/benchmarks/Ackley.java | 10 +- .../main/functions/NormalNoiseFunction.java | 4 +- ...ELHelper.java => ConfigurationHelper.java} | 17 +- .../META-INF/specifications/generator/main.dl | 250 ++++++++++++++++++ .../META-INF/definitions/optimisation/api.dl | 58 ++++ .../META-INF/definitions/surrogate/api.dl | 7 + .../META-INF/definitions/surrogate/simple.dl | 15 ++ .../src/main/java/module-info.java | 2 + .../META-INF/definitions/surrogate/svr.dl | 48 ++++ 17 files changed, 808 insertions(+), 41 deletions(-) create mode 100644 src/core/de.evoal.core.main/src/test/java/de/evoal/core/api/utils/LanguageHelperTest.java create mode 100644 src/core/de.evoal.core.main/src/test/resources/de/evoal/core/api/utils/LanguageHelperTest.dl create mode 100644 src/core/de.evoal.core.main/src/test/resources/de/evoal/core/api/utils/LanguageHelperTest.ol rename src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/utils/{ELHelper.java => ConfigurationHelper.java} (57%) create mode 100644 src/core/de.evoal.generator.main/src/main/resources/META-INF/specifications/generator/main.dl create mode 100644 src/core/de.evoal.surrogate.api/src/main/resources/META-INF/definitions/surrogate/api.dl create mode 100644 src/core/de.evoal.surrogate.simple/src/main/resources/META-INF/definitions/surrogate/simple.dl create mode 100644 src/core/de.evoal.surrogate.svr/src/main/resources/META-INF/definitions/surrogate/svr.dl diff --git a/src/core/de.evoal.core.junit/pom.xml b/src/core/de.evoal.core.junit/pom.xml index 759ecbe3..18a5e744 100644 --- a/src/core/de.evoal.core.junit/pom.xml +++ b/src/core/de.evoal.core.junit/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>de.evoal</groupId> - <artifactId>core.plugin</artifactId> + <artifactId>releng.parent</artifactId> <version>0.9.0-SNAPSHOT</version> </parent> @@ -13,5 +13,122 @@ <name>EvoAl - Core - JUnit Helpers</name> <dependencies> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.api.version}</version> + </dependency> + + <dependency> + <groupId>org.eclipse.xtext</groupId> + <artifactId>org.eclipse.xtext</artifactId> + <version>2.29.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>antlr-runtime</artifactId> + <version>3.2</version> + <scope>compile</scope> + </dependency> + + <!-- DSL dependencies --> + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.ddl</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.dl</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.el</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.generator</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.instance</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.mll</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.ol</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.ddl.dsl</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.dl.dsl</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.el.dsl</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.mll.dsl</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.ol.dsl</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.generator.dsl</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>de.evoal.languages</groupId> + <artifactId>de.evoal.languages.model.utils</artifactId> + <version>${evoal.languages.version}</version> + <scope>compile</scope> + </dependency> </dependencies> </project> diff --git a/src/core/de.evoal.core.main/pom.xml b/src/core/de.evoal.core.main/pom.xml index 20a852e0..2a8dd29c 100644 --- a/src/core/de.evoal.core.main/pom.xml +++ b/src/core/de.evoal.core.main/pom.xml @@ -284,6 +284,13 @@ <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>core.junit</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/utils/LanguageHelper.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/utils/LanguageHelper.java index 2e3d9a37..cd8daffb 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/utils/LanguageHelper.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/api/utils/LanguageHelper.java @@ -1,14 +1,19 @@ package de.evoal.core.api.utils; -import de.evoal.languages.model.el.*; +import de.evoal.languages.model.dl.*; import de.evoal.languages.model.instance.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.DoubleToIntFunction; import java.util.function.Predicate; +import java.util.stream.Collectors; /** - * Helper class for processing eal files. + * Helper class for processing instances. */ public final class LanguageHelper { /** @@ -25,15 +30,25 @@ public final class LanguageHelper { public static <T> T lookup(final Instance instance, final String path) { log.debug("Locking up '{}':", path); + if(path == null) { + log.warn("Asking for a null-path."); + throw new IllegalArgumentException("Path is not allowed to be null"); + } else if(path.isEmpty()) { + return (T)instance; + } + final String [] parts = path.split("\\."); Object current = instance; for(final String part : parts) { try { - if(!(current instanceof Instance)) { + if(current == null) { + log.error("Unable to select child on null value."); + throw new IllegalStateException("Unable to select child on null value."); + } else if(!(current instanceof Instance)) { log.error("Failed to lookup part '{}' of path '{}' in '{}'.", part, path, current); - throw new IllegalStateException("EA configuration is not valid."); + throw new IllegalStateException("Configuration is not valid."); } final Attribute attribute = ((Instance)current).findAttribute(part); @@ -49,7 +64,12 @@ public final class LanguageHelper { for(final Attribute a : ((Instance) current).getAttributes()) { log.warn(" {}", ((Name)a.getName()).getName().getName()); } - return null; + + log.error("Selecting non-existing path '{}'.", path); + throw new IllegalStateException("Selecting non-existing field: " + part); + } + if(attribute != null) { + current = convertToJava(current, ((Name) attribute.getName()).getName().getType()); } } catch(final NullPointerException e) { log.error("Failed to lookup part '{}' of path '{}'.", part, path); @@ -57,20 +77,6 @@ public final class LanguageHelper { } } - if(current instanceof LiteralValue) { - Literal literal = ((LiteralValue)current).getLiteral(); - - if(literal instanceof StringLiteral) { - current = ((StringLiteral)literal).getValue(); - } else if(literal instanceof IntegerLiteral) { - current = ((IntegerLiteral)literal).getValue(); - } else if(literal instanceof DoubleLiteral) { - current = ((DoubleLiteral)literal).getValue(); - } else if(literal instanceof BooleanLiteral) { - current = ((BooleanLiteral)literal).isValue(); - } - } - if(current instanceof Instance) { log.debug("Mapping '{}' to instance with name '{}'.", path, ((Instance)current).getName().getName()); } else { @@ -79,6 +85,39 @@ public final class LanguageHelper { return (T) current; } + private static Object convertToJava(final Object current, final Type type) { + if(current instanceof LiteralValue) { + return readLiteral(current, type); + } else if(current instanceof Array) { + return readArray(current, type); + } + + return current; + } + + private static Object readArray(final Object current, final Type type) { + final Array array = (Array)current; + + return array.getValues() + .stream() + .map(current1 -> convertToJava(current1, ((ArrayType)type).getElements().get(0))) + .toArray(); + } + + private static Object readLiteral(final Object current, final Type type) { + if(type instanceof FloatType) { + return ((Number)((LiteralValue)current).getLiteral().getValue()).doubleValue(); + } else if(type instanceof IntType) { + return ((Number)((LiteralValue)current).getLiteral().getValue()).intValue(); + } else if(type instanceof StringType) { + return Objects.toString(((LiteralValue)current).getLiteral().getValue()); + } else if(type instanceof BooleanType) { + return Boolean.TRUE.equals(((LiteralValue)current).getLiteral().getValue()); + } + + throw new UnsupportedOperationException("Type " + type.toString() + " is not supported."); + } + public static Predicate<? super Value> filterInstanceByType(final String instanceTypeName) { return i -> instanceTypeName.equals(((Instance)i).getName().getName()); } diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/Evoal.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/Evoal.java index eee035a3..c7cc28ce 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/Evoal.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/Evoal.java @@ -16,6 +16,10 @@ import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.slf4j.bridge.SLF4JBridgeHandler; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.module.ModuleReader; +import java.lang.module.ResolvedModule; import java.lang.reflect.Field; import java.util.*; @@ -27,7 +31,23 @@ import java.util.*; public final class Evoal { public static void main(final String ... args) { installJavaLoggingToSLF4JBridge(); - +/* + final ModuleLayer layer = ModuleLayer.boot(); + ModuleLayer.boot().configuration().modules().stream() + .map(ResolvedModule::reference) + .forEach(mref -> { + + System.out.println(mref.descriptor().name() + " --> " + mref.location().get()); + try (ModuleReader reader = mref.open()) { + reader.list().forEach(f -> System.out.println(" " + f)); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + }); + + + System.exit(1); +*/ log.info("Starting up EvoAl"); log.info("Booting CDI container"); diff --git a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/language/ModuleBuiltinProvider.java b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/language/ModuleBuiltinProvider.java index 698635a6..bc783c43 100644 --- a/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/language/ModuleBuiltinProvider.java +++ b/src/core/de.evoal.core.main/src/main/java/de/evoal/core/main/language/ModuleBuiltinProvider.java @@ -10,8 +10,7 @@ import java.util.Collections; @Slf4j public class ModuleBuiltinProvider implements BuiltinProvider { @Override - public Collection<URI> findBuiltins(String name) { - System.err.println("Builtins"); + public Collection<URI> findBuiltins(final String name) { return Collections.emptyList(); } } diff --git a/src/core/de.evoal.core.main/src/test/java/de/evoal/core/api/utils/LanguageHelperTest.java b/src/core/de.evoal.core.main/src/test/java/de/evoal/core/api/utils/LanguageHelperTest.java new file mode 100644 index 00000000..cb4ef4a1 --- /dev/null +++ b/src/core/de.evoal.core.main/src/test/java/de/evoal/core/api/utils/LanguageHelperTest.java @@ -0,0 +1,182 @@ +package de.evoal.core.api.utils; + +import de.evoal.languages.model.instance.Instance; +import de.evoal.languages.model.ol.OptimisationModel; +import org.junit.jupiter.api.*; + +import static de.evoal.core.api.utils.LanguageHelper.*; + +public class LanguageHelperTest { + @Order(1) + @Test + public void testLoading() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + Assertions.assertNotNull(instance); + } + + @Test + public void testLookupForNullInstance() { + Assertions.assertThrows(IllegalStateException.class, () -> lookup(null, "child")); + } + + @Test + public void testLookupForNullPath() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + Assertions.assertThrows(IllegalArgumentException.class, () -> lookup(instance, null)); + } + + @Test + public void testLookupForEmptyPath() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, ""); + + Assertions.assertNotNull(result); + Assertions.assertTrue(instance == result); + } + + @Test + public void testLookupForExistingChild() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, "child"); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result instanceof Instance); + + final Instance child = (Instance)result; + Assertions.assertEquals("A", child.getName().getName()); + } + + @Test + public void testLookupName() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, "name"); + + Assertions.assertNotNull(result); + Assertions.assertEquals("parent", result); + } + + @Test + public void testLookupChildOfLiteral() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + Assertions.assertThrows(IllegalStateException.class, () -> lookup(instance, "child.string-field.non-existing")); + } + + @Test + public void testLookupNonExistingChild() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + Assertions.assertThrows(IllegalStateException.class, () -> lookup(instance, "child.non-existing")); + } + + @Test + public void testLookupBooleanField() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, "child.boolean-field"); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result instanceof Boolean); + Assertions.assertEquals(true, result); + } + + @Test + public void testLookupFlotField() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, "child.float-field"); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result instanceof Double); + Assertions.assertEquals(1.3, result); + } + + @Test + public void testLookupIntegerField() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, "child.integer-field"); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result instanceof Integer); + Assertions.assertEquals(4, result); + } + + @Test + public void testLookupStringField() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, "child.string-field"); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result instanceof String); + Assertions.assertEquals("FOOBAR", result); + } + + @Test + public void testLookup1DArrayField() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, "child.array-1D-float"); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result instanceof Object []); + + final Object [] array = (Object[]) result; + Assertions.assertEquals(3, array.length); + Assertions.assertEquals(4.2, array[0]); + Assertions.assertEquals(3.1, array[1]); + Assertions.assertEquals(1.0, array[2]); + } + + @Test + public void testLookup2DArrayField() { + final OptimisationModel model = de.evoal.core.junit.dsl.LanguageHelper.loadFromClasspath("de/evoal/core/api/utils/LanguageHelperTest.ol"); + final Instance instance = model.getInstance(); + + final Object result = lookup(instance, "child.array-2D-int"); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result instanceof Object []); + + final Object [] array = (Object[]) result; + Assertions.assertEquals(3, array.length); + + final Object [] array0 = (Object[]) array[0]; + final Object [] array1 = (Object[]) array[1]; + final Object [] array2 = (Object[]) array[2]; + + Assertions.assertEquals(5, array0.length); + Assertions.assertEquals(3, array1.length); + Assertions.assertEquals(1, array2.length); + + Assertions.assertEquals(1, array0[0]); + Assertions.assertEquals(2, array0[1]); + Assertions.assertEquals(3, array0[2]); + Assertions.assertEquals(4, array0[3]); + Assertions.assertEquals(5, array0[4]); + + Assertions.assertEquals(3, array1[0]); + Assertions.assertEquals(2, array1[1]); + Assertions.assertEquals(1, array1[2]); + + Assertions.assertEquals(42, array2[0]); + } +} diff --git a/src/core/de.evoal.core.main/src/test/resources/de/evoal/core/api/utils/LanguageHelperTest.dl b/src/core/de.evoal.core.main/src/test/resources/de/evoal/core/api/utils/LanguageHelperTest.dl new file mode 100644 index 00000000..bde38ea5 --- /dev/null +++ b/src/core/de.evoal.core.main/src/test/resources/de/evoal/core/api/utils/LanguageHelperTest.dl @@ -0,0 +1,12 @@ +type 'parent' { + child : instance A; +} + +type A { + 'float-field' : float; + 'string-field' : string; + 'integer-field' : int; + 'boolean-field' : boolean; + 'array-1D-float' : array float; + 'array-2D-int' : array array int; +} \ No newline at end of file diff --git a/src/core/de.evoal.core.main/src/test/resources/de/evoal/core/api/utils/LanguageHelperTest.ol b/src/core/de.evoal.core.main/src/test/resources/de/evoal/core/api/utils/LanguageHelperTest.ol new file mode 100644 index 00000000..59094313 --- /dev/null +++ b/src/core/de.evoal.core.main/src/test/resources/de/evoal/core/api/utils/LanguageHelperTest.ol @@ -0,0 +1,16 @@ +use "LanguageHelperTest.dl"; + +parent { + child := A { + 'boolean-field' := true; + 'float-field' := 1.3; + 'integer-field' := 4; + 'string-field' := "FOOBAR"; + 'array-1D-float' := [4.2, 3.1, 1.0]; + 'array-2D-int' := [ + [ 1, 2, 3, 4, 5], + [ 3, 2, 1], + [42] + ]; + }; +} \ No newline at end of file diff --git a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/benchmarks/Ackley.java b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/benchmarks/Ackley.java index 6ab9d66a..5010c555 100644 --- a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/benchmarks/Ackley.java +++ b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/benchmarks/Ackley.java @@ -3,10 +3,10 @@ package de.evoal.generator.main.benchmarks; import de.evoal.core.api.properties.Properties; import de.evoal.core.api.properties.PropertySpecification; import de.evoal.core.api.utils.InitializationException; -import de.evoal.core.api.utils.Requirements; +import de.evoal.core.api.utils.LanguageHelper; import de.evoal.generator.api.AbstractGeneratorFunction; import de.evoal.generator.api.GeneratorFunction; -import de.evoal.generator.main.utils.ELHelper; +import de.evoal.generator.main.utils.ConfigurationHelper; import de.evoal.languages.model.generator.Step; import lombok.extern.slf4j.Slf4j; @@ -50,9 +50,9 @@ public class Ackley extends AbstractGeneratorFunction { public GeneratorFunction init(final Step configuration) throws InitializationException { super.init(configuration); - a = ELHelper.readDouble(configuration.getInstance(), "a"); - b = ELHelper.readDouble(configuration.getInstance(), "b"); - c = ELHelper.readDouble(configuration.getInstance(), "c"); + a = LanguageHelper.lookup(configuration.getInstance(), "a"); + b = LanguageHelper.lookup(configuration.getInstance(), "b"); + c = LanguageHelper.lookup(configuration.getInstance(), "c"); return this; } diff --git a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/functions/NormalNoiseFunction.java b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/functions/NormalNoiseFunction.java index 914acb27..5df70fe2 100644 --- a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/functions/NormalNoiseFunction.java +++ b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/functions/NormalNoiseFunction.java @@ -8,7 +8,7 @@ import de.evoal.core.api.properties.PropertySpecification; import de.evoal.core.api.utils.InitializationException; import de.evoal.generator.api.AbstractGeneratorFunction; import de.evoal.generator.api.GeneratorFunction; -import de.evoal.generator.main.utils.ELHelper; +import de.evoal.generator.main.utils.ConfigurationHelper; import de.evoal.languages.model.generator.Step; import org.apache.commons.math3.distribution.NormalDistribution; import org.apache.commons.math3.distribution.RealDistribution; @@ -28,7 +28,7 @@ public class NormalNoiseFunction extends AbstractGeneratorFunction { public GeneratorFunction init(final Step configuration) throws InitializationException { super.init(configuration); - ELHelper.readDistributions(configuration.getInstance(), "distributions") + ConfigurationHelper.readDistributions(configuration.getInstance(), "distributions") .stream() .map(d -> new NormalDistribution(d.μ(), d.σ())) .forEach(distributions::add); diff --git a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/utils/ELHelper.java b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/utils/ConfigurationHelper.java similarity index 57% rename from src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/utils/ELHelper.java rename to src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/utils/ConfigurationHelper.java index 17aac76b..30aa736f 100644 --- a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/utils/ELHelper.java +++ b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/utils/ConfigurationHelper.java @@ -1,35 +1,30 @@ package de.evoal.generator.main.utils; -import de.evoal.languages.model.el.DoubleLiteral; +import de.evoal.core.api.utils.LanguageHelper; import de.evoal.languages.model.instance.Array; import de.evoal.languages.model.instance.Instance; -import de.evoal.languages.model.instance.LiteralValue; import java.util.List; import java.util.stream.Collectors; -public final class ELHelper { - private ELHelper() {} +public final class ConfigurationHelper { + private ConfigurationHelper() {} public record Distribution(double μ, double σ) {} - public static double readDouble(final Instance instance, final String name) { - return ((DoubleLiteral)((LiteralValue)instance.findAttribute(name).getValue()).getLiteral()).getValue(); - } - public static List<Distribution> readDistributions(final Instance instance, final String name) { final Array array = (Array)instance.findAttribute(name).getValue(); return array.getValues() .stream() .map(Instance.class::cast) - .map(ELHelper::readDistribution) + .map(ConfigurationHelper::readDistribution) .collect(Collectors.toUnmodifiableList()); } private static Distribution readDistribution(final Instance instance) { - final double μ = ELHelper.readDouble(instance, "μ"); - final double σ = ELHelper.readDouble(instance, "σ"); + final double μ = LanguageHelper.lookup(instance, "μ"); + final double σ = LanguageHelper.lookup(instance, "σ"); return new Distribution(μ, σ); } diff --git a/src/core/de.evoal.generator.main/src/main/resources/META-INF/specifications/generator/main.dl b/src/core/de.evoal.generator.main/src/main/resources/META-INF/specifications/generator/main.dl new file mode 100644 index 00000000..b6d41817 --- /dev/null +++ b/src/core/de.evoal.generator.main/src/main/resources/META-INF/specifications/generator/main.dl @@ -0,0 +1,250 @@ +/** + * In mathematical optimization, the Ackley function is a non-convex function + * used as a performance test problem for optimization algorithms. It was proposed + * by David Ackley in his 1987 PhD dissertation. ... <a href="https://en.wikipedia.org/wiki/Ackley_function">Wikipedia</a>. + * + * <math display="block"> + * <mrow> + * <mi>f</mi> + * <mo form="prefix" stretchy="false">(</mo> + * <mi>w</mi> + * <mi>r</mi> + * <mi>i</mi> + * <mi>t</mi> + * <msub> + * <mi>e</mi> + * <mn>0</mn> + * </msub> + * <mo form="postfix" stretchy="false">)</mo> + * <mo>=</mo> + * <mo>−</mo> + * <mi>a</mi> + * <mo>⋅</mo> + * <mi>e</mi> + * <mi>x</mi> + * <mi>p</mi> + * <mo form="prefix" stretchy="false">(</mo> + * <mo>−</mo> + * <mi>b</mi> + * <msqrt> + * <mrow> + * <mfrac> + * <mn>1</mn> + * <mi>n</mi> + * </mfrac> + * <mrow> + * <munderover> + * <mo movablelimits="false">∑</mo> + * <mrow> + * <mi>i</mi> + * <mo>=</mo> + * <mn>1</mn> + * </mrow> + * <mi>n</mi> + * </munderover> + * </mrow> + * <mi>r</mi> + * <mi>e</mi> + * <mi>a</mi> + * <msub> + * <mi>d</mi> + * <mi>i</mi> + * </msub> + * </mrow> + * </msqrt> + * <mo form="postfix" stretchy="false">)</mo> + * <mo>−</mo> + * <mi>e</mi> + * <mi>x</mi> + * <mi>p</mi> + * <mo form="prefix" stretchy="false">(</mo> + * <mfrac> + * <mn>1</mn> + * <mi>n</mi> + * </mfrac> + * <mrow> + * <munderover> + * <mo movablelimits="false">∑</mo> + * <mrow> + * <mi>i</mi> + * <mo>=</mo> + * <mn>1</mn> + * </mrow> + * <mi>n</mi> + * </munderover> + * </mrow> + * <mi>c</mi> + * <mi>o</mi> + * <mi>s</mi> + * <mo form="prefix" stretchy="false">(</mo> + * <mi>c</mi> + * <mo>⋅</mo> + * <mi>r</mi> + * <mi>e</mi> + * <mi>a</mi> + * <msub> + * <mi>d</mi> + * <mi>i</mi> + * </msub> + * <mo form="postfix" stretchy="false">)</mo> + * <mo form="postfix" stretchy="false">)</mo> + * <mo>+</mo> + * <mi>a</mi> + * <mo>+</mo> + * <mi>e</mi> + * <mi>x</mi> + * <mi>p</mi> + * <mo form="prefix" stretchy="false">(</mo> + * <mn>1</mn> + * <mo form="postfix" stretchy="false">)</mo> + * </mrow> + * </math> + * + * According to this specification, the function only generates a single output + * variable out of a n input variables. + */ +type ackley { + /** + * The constant a is set to 20 in the original Ackley function. + */ + a : float; + + /** + * The constant b is set to 0.2 in the original Ackley function. + */ + b : float; + + /** + * The constant c is set to 2π in the original Ackley function. + */ + c : float; +} + +/** + * In mathematical optimization, the Rastrigin function is a non-convex function + * used as a performance test problem for optimization algorithms. ... <a href="https://en.wikipedia.org/wiki/Rastrigin_function">Wikipedia</a> + * + * <math display="block"> + * <mrow> + * <mi>w</mi> + * <mi>r</mi> + * <mi>i</mi> + * <mi>t</mi> + * <msub> + * <mi>e</mi> + * <mn>0</mn> + * </msub> + * <mo>=</mo> + * <mi>a</mi> + * <mo>⋅</mo> + * <mi>n</mi> + * <mo>+</mo> + * <mrow> + * <munderover> + * <mo movablelimits="false">∑</mo> + * <mrow> + * <mi>i</mi> + * <mo>=</mo> + * <mn>1</mn> + * </mrow> + * <mi>n</mi> + * </munderover> + * </mrow> + * <mo form="prefix" stretchy="false">(</mo> + * <mi>r</mi> + * <mi>e</mi> + * <mi>a</mi> + * <msubsup> + * <mi>d</mi> + * <mi>i</mi> + * <mn>2</mn> + * </msubsup> + * <mo>−</mo> + * <mi>A</mi> + * <mo>⋅</mo> + * <mi>c</mi> + * <mi>o</mi> + * <mi>s</mi> + * <mo form="prefix" stretchy="false">(</mo> + * <mn>2</mn> + * <mi>π</mi> + * <mo>⋅</mo> + * <mi>r</mi> + * <mi>e</mi> + * <mi>a</mi> + * <msub> + * <mi>d</mi> + * <mi>i</mi> + * </msub> + * <mo form="postfix" stretchy="false">)</mo> + * <mo form="postfix" stretchy="false">)</mo> + * </mrow> + * </math> + * + */ +type rastrigin { + /** + * Constant a, which is typically 10. + */ + a : float; +} + +/** + * TODO Document me + */ +type 'weighted-sphere' { +} + +/** + * TODO Document me + */ +type 'rosenbrock' { +} + +/** + * Adds constant values for the specified data. + */ +type constants { + /** + * The constant values to append. + */ + constants : array float; +} + + +type 'multivariate-normal-distribution' { + means : array float; + covariance : array array float; +} + +/** + * Adds normally distributed noise to data. For each data to noise, you can + * specify a separate distribution. + */ +type 'normally-distributed-noise' { + /** + * The different distributions to use. Make sure it matches the size of + * the data the function writes. + */ + distributions : array instance distribution; +} + +/** + * A distribution specification. + */ +type distribution { + /** + * The distribution's expected value. + */ + 'μ' : float; + + /** + * The distribution's standard deviation. + */ + 'σ' : float; +} + + +type 'constraint-validation' { + +} diff --git a/src/core/de.evoal.surrogate.api/src/main/resources/META-INF/definitions/optimisation/api.dl b/src/core/de.evoal.surrogate.api/src/main/resources/META-INF/definitions/optimisation/api.dl index e69de29b..c7ff7d47 100644 --- a/src/core/de.evoal.surrogate.api/src/main/resources/META-INF/definitions/optimisation/api.dl +++ b/src/core/de.evoal.surrogate.api/src/main/resources/META-INF/definitions/optimisation/api.dl @@ -0,0 +1,58 @@ +/** + * Calculating fitness value by using a surrogate function:<br/> + * + * <mathml> + * <math> + * <mrow> + * <mi>f</mi> + * <mi>i</mi> + * <mi>t</mi> + * <mi>n</mi> + * <mi>e</mi> + * <mi>s</mi> + * <mi>s</mi> + * <mo>=</mo> + * <mi>s</mi> + * <mi>u</mi> + * <mi>r</mi> + * <mi>r</mi> + * <mi>o</mi> + * <mi>g</mi> + * <mi>a</mi> + * <mi>t</mi> + * <mi>e</mi> + * <mo form="prefix" stretchy="false">(</mo> + * <mi>i</mi> + * <mi>n</mi> + * <mi>d</mi> + * <mo form="postfix" stretchy="false">)</mo> + * </mrow> + * </math> + * </mathml> + */ +type surrogate extends 'goal-function' { +} + +/** + * Use training data as initial population. + */ +type training extends 'initial-population' { +} + +/** + * Repair individuals with training data. + */ +type 'repair-with-training' extends 'repair-strategy' { +} + +type 'constraint-statistics' extends 'statistics-writer' { +} + +type 'correlated' extends 'statistics-writer' { +} + +type 'range-correlated' extends 'statistics-writer' { +} + +type 'prediction-per-individual' extends 'statistics-writer' { +} \ No newline at end of file diff --git a/src/core/de.evoal.surrogate.api/src/main/resources/META-INF/definitions/surrogate/api.dl b/src/core/de.evoal.surrogate.api/src/main/resources/META-INF/definitions/surrogate/api.dl new file mode 100644 index 00000000..99d2cd42 --- /dev/null +++ b/src/core/de.evoal.surrogate.api/src/main/resources/META-INF/definitions/surrogate/api.dl @@ -0,0 +1,7 @@ +abstract type surrogate {} + +def void 'cross-validation'(int times); +def void 'R²'(); +def void rmse(); +def void rrse(); + diff --git a/src/core/de.evoal.surrogate.simple/src/main/resources/META-INF/definitions/surrogate/simple.dl b/src/core/de.evoal.surrogate.simple/src/main/resources/META-INF/definitions/surrogate/simple.dl new file mode 100644 index 00000000..09542705 --- /dev/null +++ b/src/core/de.evoal.surrogate.simple/src/main/resources/META-INF/definitions/surrogate/simple.dl @@ -0,0 +1,15 @@ +/** + * An exemplary identity function. + */ +type identity extends surrogate { +} + +type 'linear-regression' extends surrogate { + intercept : float; + slope : float; +} + +type 'simple-quadratic-regression' extends surrogate { + intercept : float; + slope : float; +} \ No newline at end of file diff --git a/src/core/de.evoal.surrogate.svr/src/main/java/module-info.java b/src/core/de.evoal.surrogate.svr/src/main/java/module-info.java index 2fbb6082..e8e35aa8 100644 --- a/src/core/de.evoal.surrogate.svr/src/main/java/module-info.java +++ b/src/core/de.evoal.surrogate.svr/src/main/java/module-info.java @@ -16,4 +16,6 @@ module de.evoal.surrogate.svr { requires de.evoal.surrogate.api; opens de.evoal.surrogate.svr; + + exports de.evoal.surrogate.svr to de.evoal.approximative.interval; } diff --git a/src/core/de.evoal.surrogate.svr/src/main/resources/META-INF/definitions/surrogate/svr.dl b/src/core/de.evoal.surrogate.svr/src/main/resources/META-INF/definitions/surrogate/svr.dl new file mode 100644 index 00000000..ce22f767 --- /dev/null +++ b/src/core/de.evoal.surrogate.svr/src/main/resources/META-INF/definitions/surrogate/svr.dl @@ -0,0 +1,48 @@ +abstract type 'svr-surrogate' extends surrogate {} + +abstract type 'epsilon-svr' extends surrogate { + /** + * Some totally <b>accurate</b> description of a very soft margin. + */ + 'soft-margin' : float; + tolerance : float; + 'ε' : float; +} + +type 'gaussian-svr' extends 'epsilon-svr' { + 'σ' : float; +} + +type 'hellinger-svr' extends 'epsilon-svr' { + 'σ' : float; +} + +type 'hyperbolic-tangent-svr' extends 'epsilon-svr' { + 'σ' : float; + scale : float; + offset : float; +} + +type 'laplacian-svr' extends 'epsilon-svr' { + 'σ' : float; +} + +type 'linear-svr' extends 'epsilon-svr' { + 'σ' : float; +} + +type 'pearson-svr' extends 'epsilon-svr' { + 'σ' : float; + 'ω' : float; +} + +type 'polynomial-svr' extends 'epsilon-svr' { + 'σ' : float; + 'degree' : int; + 'scale' : float; + 'offset' : float; +} + +type 'thin-plate-spline-svr' extends 'epsilon-svr' { + 'σ' : float; +} -- GitLab