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