Browse Source

added DSL example

Bart Meyers 4 years ago
parent
commit
f35065e0db
47 changed files with 1997 additions and 0 deletions
  1. 9 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/.classpath
  2. 34 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/.project
  3. 2 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/.settings/org.eclipse.core.resources.prefs
  4. 7 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/.settings/org.eclipse.jdt.core.prefs
  5. 22 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/META-INF/MANIFEST.MF
  6. 5 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/build.properties
  7. 23 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/plant.sa
  8. 32 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow.sa
  9. 12 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_algebraic_loop_delay.sa
  10. 23 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_algebraic_loop_delay_BASE.sa
  11. 17 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_algebraic_loop_iteration.sa
  12. 49 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_algebraic_loop_iteration_BASE.sa
  13. 21 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_controller_delay.sa
  14. 48 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_controller_delay_BASE.sa
  15. 32 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_model_only.sa
  16. 9 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_multi_rate.sa
  17. 28 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_multi_rate_BASE.sa
  18. 29 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/test1.sa
  19. 22 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/window_obstacle_sa_loop_BASE.sa
  20. 20 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/window_obstacle_sa_loop_BASE_new.sa
  21. 16 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/window_obstacle_sa_multirate_BASE.sa
  22. 5 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/window_sa_BASE.sa
  23. 1 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/oracles/test1.txt
  24. 57 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/AbstractSemanticAdaptationGeneratorTest.xtend
  25. 26 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/AbstractSemanticAdaptationParserTest.xtend
  26. 120 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/AbstractSemanticAdaptationTest.xtend
  27. 36 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationGeneratorTest.xtend
  28. 97 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationParsingTest.xtend
  29. BIN
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.antlr-generator-3.2.0-patch.jar
  30. 9 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.classpath
  31. 34 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.project
  32. 2 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.settings/org.eclipse.core.resources.prefs
  33. 7 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.settings/org.eclipse.jdt.core.prefs
  34. 29 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/META-INF/MANIFEST.MF
  35. 18 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/build.properties
  36. 10 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/plugin.xml
  37. 10 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/plugin.xml_gen
  38. 43 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/GenerateSemanticAdaptation.mwe2
  39. 365 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/SemanticAdaptation.xtext
  40. 24 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/SemanticAdaptationRuntimeModule.xtend
  41. 15 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/SemanticAdaptationStandaloneSetup.xtend
  42. 25 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationGenerator.xtend
  43. 111 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationPythonGenerator.xtend
  44. 68 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/interpreter/Interpreter.xtend
  45. 315 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/scoping/SemanticAdaptationScopeProvider.xtend
  46. 61 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/validation/SemanticAdaptationValidator.xtend
  47. 49 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/valueconverter/SemanticAdaptationValueConverters.xtend

+ 9 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/.classpath

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="src-gen"/>
+	<classpathentry kind="src" path="xtend-gen"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 34 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/.project

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>be.uantwerpen.ansymo.semanticadaptation.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>

+ 2 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/.settings/org.eclipse.core.resources.prefs

@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=windows-1252

+ 7 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8

+ 22 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/META-INF/MANIFEST.MF

@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: be.uantwerpen.ansymo.semanticadaptation.tests
+Bundle-Vendor: My Company
+Bundle-Version: 1.0.0.qualifier
+Bundle-SymbolicName: be.uantwerpen.ansymo.semanticadaptation.tests; singleton:=true
+Bundle-ActivationPolicy: lazy
+Require-Bundle: be.uantwerpen.ansymo.semanticadaptation,
+ org.junit;bundle-version="4.7.0",
+ org.eclipse.xtext.junit4,
+ org.eclipse.xtext.xbase.junit,
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.jdt.core
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: be.uantwerpen.ansymo.semanticadaptation.tests
+Import-Package: org.hamcrest.core,
+ org.junit;version="4.5.0",
+ org.junit.runners.model;version="4.5.0",
+ org.junit.runner;version="4.5.0",
+ org.junit.runners;version="4.5.0",
+ org.junit.runner.manipulation;version="4.5.0",
+ org.junit.runner.notification;version="4.5.0"

+ 5 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/build.properties

@@ -0,0 +1,5 @@
+source.. = src/,\
+           src-gen/,\
+           xtend-gen/
+bin.includes = .,\
+               META-INF/

+ 23 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/plant.sa

@@ -0,0 +1,23 @@
+semantic adaptation power_sa
+for continuous time
+input ports up, down, reaction_torque
+output ports armature_current, motor_speed
+in rules {} // needs to be detected exactly when reaction_torque starts to change rapidly -> zero crossing on derivative abs(reaction_torque') >! 100
+out rules {}
+control rules {}
+
+semantic adaptation window_sa
+for continuous time
+input ports motor_speed
+output ports height, window_reaction_torque
+in rules {}
+out rules {}
+control rules {}
+
+semantic adaptation obstacle_sa
+for continuous time
+input ports height
+output ports obstacle_reaction_torque
+in rules {}
+out rules {}
+control rules {}

+ 32 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow.sa

@@ -0,0 +1,32 @@
+import PowerWindowModel
+
+semantic adaptation controller_sa
+for fmu controller
+input ports armature_current -> obj_detected, passenger_up, passenger_down, driver_up, driver_down, next
+output ports up, down
+control rules { triggered by signal == true or t >= next_transition }
+in rules with crossing absolute tolerance = 1e-8 and relative tolerance = 0.0001, no hold {
+	armature_current >! 5 -> obj_detected := true;
+	otherwise(armature_current) -> obj_detected := false;
+}
+out rules with zero order hold {
+	"up" -> up := 1;
+	"stop" -> { up := 0; down := 0; };
+	"down" -> down := 1;
+	delay at up and down;
+}
+
+semantic adaptation window_sa
+for fmu window
+out rules {
+	reaction_torque := -reaction_torque;
+}
+
+semantic adaptation window_obstacle_sa with master
+for fmu window_sa, obstacle
+multiply rate 10 times with first order interpolation
+successive substitution starts at height with absolute tolerance = 1e-8 and relative tolerance = 0.0001
+
+semantic adaptation plant_sa
+for fmu power, window_obstacle_sa
+successive substitution starts at reaction_torque with absolute tolerance = 1e-6 and relative tolerance = 1e-6

+ 12 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_algebraic_loop_delay.sa

@@ -0,0 +1,12 @@
+import PowerWindowModel
+import Controller_SA
+
+module Algebraic_Loop_SA
+
+// this one could be joined with the one below, if we assume certain priorities in executing the rules
+semantic adaptation window_sa
+for fmu window
+out rules {
+	reaction_torque := -reaction_torque;
+	delay at reaction_torque and height;
+}

+ 23 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_algebraic_loop_delay_BASE.sa

@@ -0,0 +1,23 @@
+import PowerWindowModel
+import Controller_SA
+
+// this one could be joined with the one below, if we assume certain priorities in executing the rules
+semantic adaptation window_sa
+for fmu window
+out rules {
+	true -> {reaction_torque := -reaction_torque; } --> { };
+}
+
+// algebraic loop, simply use delay... written in baseDSL
+semantic adaptation window_sa_delay with master
+for fmu window_sa // inner SA, makes it possible to enforce order among adaptations this way
+param init_height = 0;
+param init_reaction_torque = 0;
+control rules { implied }
+out var stored_height := init_height;
+out var stored_reaction_torque := init_reaction_torque;
+out rules {
+	true -> { var temp_height := height; height := stored_height; stored_height := temp_height; } --> { };
+	true -> { var temp_reaction_torque := reaction_torque; reaction_torque := stored_reaction_torque; stored_reaction_torque := temp_reaction_torque; } --> { }; 
+}
+

+ 17 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_algebraic_loop_iteration.sa

@@ -0,0 +1,17 @@
+import PowerWindowModel
+import Controller_SA
+
+// this one could be joined with the one below, if we assume certain priorities in executing the rules
+semantic adaptation window_sa
+for fmu window
+out rules {
+	reaction_torque := -reaction_torque;
+}
+
+// algebraic loop
+semantic adaptation power_window_obstacle_sa
+for fmu power, window_sa, obstacle
+input ports up, down // optional, can be figured out from model
+output ports armature_current // optional, can be figured out from model
+successive substitution starts at reaction_torque and height with absolute tolerance = 1e-8 and relative tolerance = 0.0001
+

+ 49 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_algebraic_loop_iteration_BASE.sa

@@ -0,0 +1,49 @@
+import PowerWindowModel
+import Controller_SA
+
+// this one could be joined with the one below, if we assume certain priorities in executing the rules
+semantic adaptation window_sa
+for fmu window
+out rules {
+	true -> {reaction_torque := -reaction_torque; } --> { };
+}
+
+// algebraic loop
+semantic adaptation power_window_obstacle_sa // without master -> not necessary: custom control rules override master
+for fmu power, window_sa, obstacle
+input ports up (m/s^2), down
+output ports armature_current
+//algebraic loop fix point iteration at reaction_torque and height with absolute tolerance = 1e-8 and relative tolerance = 0.0001
+param MAXITER = 100;
+param REL_TOL = 1e-8;
+param ABS_TOL = 1e-8;
+control rules {
+	// do_step will always use the last values, do_step does not advance time so will replace the last signal values! 
+	// therefore, we must set the signal at time t+h of reaction_torque and height
+	// this is done by a very weird statement:
+	reaction_torque := reaction_torque;
+	height := height;
+	// and just initialise other values at time t+h
+	armature_current := 0;
+	motor_speed := 0;
+	reaction_force := 0;
+	// now, all inputs are set at time t+h and we can start substituting them
+	var converged := false;
+	var temp_height; // to compare new value with previous value
+	var temp_reaction_torque; // to compare new value with previous value
+	for (var iter in 0 .. MAXITER) {
+		if (converged) {
+			break;
+		}
+		temp_height := height;
+		temp_reaction_torque := reaction_torque;
+		//local_step(power); // with delayed input for reaction_torque
+		//local_step(obstacle); // with delayed input for height
+		local_step(h, power, obstacle, window_sa); // acts like the Local master but cannot not advance time, so will always roll-back for safety (must be in one statements because a full step is done here), but how do we get the inner
+		if (is_close(temp_height, height, REL_TOL, ABS_TOL) and is_close(temp_reaction_torque, reaction_torque, REL_TOL, ABS_TOL)) { // todo: set tolerance
+			converged := true;
+		}
+	}
+}
+
+

+ 21 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_controller_delay.sa

@@ -0,0 +1,21 @@
+import PowerWindowModel
+
+module Controller_SA
+
+semantic adaptation armature_current_sa
+for fmu controller
+control rules { triggered by signal == true }
+in rules with crossing absolute tolerance = 1e-8 and relative tolerance = 0.0001, no hold {
+	armature_current >! 5 -> obj_detected := true;
+	otherwise(armature_current) -> obj_detected := false;
+}
+
+semantic adaptation in_out_sa
+for fmu controller
+out rules with zero order hold {
+	"up" -> up := 1;
+	"stop" -> { up := 0; down := 0; };
+	"down" -> down := 1;
+	delay at up and down;
+}
+

+ 48 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_controller_delay_BASE.sa

@@ -0,0 +1,48 @@
+import PowerWindowModel
+
+module Controller_SA
+
+semantic adaptation controller_sa
+for fmu controller
+input ports armature_current -> obj_detected, passenger_up, passenger_down, driver_up, driver_down, next
+output ports up, down
+param REL_TOL = 0.0001;
+param ABS_TOL = 1e-8;
+param CROSSING = 5;
+param init_armature_current = CROSSING;
+param init_up = 0;
+param init_down = 0;
+control rules { triggered by signal == true or t >= next_transition }
+in var next_transition := -1;
+in var stored_armature_current := init_armature_current;
+in rules {
+	true -> {
+		obj_detected := false;
+		if (not (not is_close(stored_armature_current, CROSSING, REL_TOL, ABS_TOL) and stored_armature_current > CROSSING)
+					and (not is_close(armature_current, CROSSING, REL_TOL, ABS_TOL) and armature_current > CROSSING)) { // crossing, but not within tolerance
+			var negative_value := stored_armature_current - CROSSING;
+			var positive_value := armature_current - CROSSING;
+			var new_step_size := (h * (- negative_value)) / (positive_value - negative_value);
+			discard(new_step_size);
+		} else {
+			if (not (not is_close(stored_armature_current, CROSSING, REL_TOL, ABS_TOL) and stored_armature_current > CROSSING)
+						and is_close(armature_current, CROSSING, REL_TOL, ABS_TOL)) { // crossing within tolerance found
+				obj_detected := true;
+			}
+		}
+		stored_armature_current := armature_current;
+	} --> { };
+	next > 0 -> { next_transition := t + next; } --> { };
+}
+out var stored_up := init_up;
+out var stored_down := init_down;
+out rules {
+	up == true -> { up := 1; } --> { };
+	otherwise up -> { } --> { };
+	down == true -> { down := 1; } --> { };
+	otherwise down -> { } --> { };
+	stop == true -> { up := 0; down := 0; } --> { };
+	otherwise stop -> { } --> { };
+	true -> { up := stored_up; stored_up := up; } --> { };
+	true -> { down := stored_down; stored_down := down; } --> { }; 
+}

+ 32 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_model_only.sa

@@ -0,0 +1,32 @@
+module PowerWindowModel
+
+fmu environment
+type discrete event
+output ports passenger_up, passenger_down, driver_up, driver_down
+full internal dependencies
+
+fmu controller
+type discrete event
+input ports obj_detected, passenger_up, passenger_down, driver_up, driver_down
+output ports up, down, stop, next
+full internal dependencies
+
+fmu power
+type continuous time
+input ports up, down, reaction_torque (N.m)
+output ports armature_current (mA), motor_speed (m/s)
+full internal dependencies
+
+fmu window
+type continuous time
+input ports motor_speed (m/s), reaction_force (N)
+output ports height (cm), window_reaction_torque (N.m)
+full internal dependencies
+
+fmu obstacle
+type continuous time
+input ports height (m)
+output ports reaction_force (N)
+full internal dependencies
+
+armature_current -> obj_detected // only ports that change names need to be connected

+ 9 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_multi_rate.sa

@@ -0,0 +1,9 @@
+import PowerWindowModel
+import Controller_SA
+import Algebraic_Loop_SA
+
+// multi-rate for window and object
+semantic adaptation window_obstacle_sa with master
+for fmu window_sa, obstacle
+multiply rate 10 times with first order interpolation
+successive substitution starts at height with absolute tolerance = 1e-8 and relative tolerance = 0.0001

+ 28 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/powerwindow_multi_rate_BASE.sa

@@ -0,0 +1,28 @@
+import PowerWindowModel
+
+semantic adaptation window_sa
+for fmu window
+out rules {
+	true -> { } --> { reaction_torque := -reaction_torque; };
+}
+
+semantic adaptation window_obstacle_sa_loop
+for fmu window_sa, obstacle
+// just for the sake of declaring this, look at algebraic loop iteration
+
+semantic adaptation window_obstacle_sa_multirate with master // multi-rate for window and object
+for fmu window_obstacle_sa_loop
+input ports motor_speed
+output ports reaction_torque
+param init_motor_speed = 0;
+control rules { multiplied 10 times }
+in var stored_motor_speed := init_motor_speed;
+in var linear_increment;
+in rules {
+	true -> {
+		linear_increment := (motor_speed - stored_motor_speed) / 10;
+		stored_motor_speed := motor_speed;
+	} --> {
+		motor_speed := motor_speed + linear_increment;
+	};
+}

+ 29 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/test1.sa

@@ -0,0 +1,29 @@
+semantic adaptation TEST
+for discrete event
+input ports x[1 .. 2] (kg.m/s 2), y, z
+output ports a, b, c
+extract directionalderivative 
+{= (signal-signal[prev]) / h }
+{
+	def firstorder(s) {
+		var temp;
+		temp = s-s[prev];
+		return temp / h;
+	}
+	return firstorder(x);
+}
+
+in rules with zero crossing tolerance = 0.001, no hold { // for CT to inner DE
+	not x[prev]+3 > 2+2*floor(y[now]+round(8.2)) and y < 4 -> todo --> todo;
+	x >! 2 with tolerance = 0.0001 -> "high" --> no hold; // means condition -> IN action -> UPDATE IN action
+	x >! 1 or x <! 2 -> "low" --> no hold;
+	x <! 1 -> "off"; // i.e., no hold is the default
+	otherwise(x) -> null --> zero order hold;
+	quantize(y, "off", 1, "low", 2, "high") --> no hold;
+	quantize(z, ="event"+floor(z + 0.5)) --> no hold;
+	quantize(z, ="event"+round(z)) --> no hold;
+	quantize z every 2 offset 1 --> no hold;
+}
+//out rules with buffer[10] {}
+out rules {}
+control rules {}

+ 22 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/window_obstacle_sa_loop_BASE.sa

@@ -0,0 +1,22 @@
+semantic adaptation window_obstacle_sa_loop overrides master
+for fmu window_sa, obstacle
+input ports motor_speed
+output ports reaction_torque
+param MAXITER = 100;
+param REL_TOL = 1e-8;
+param ABS_TOL = 1e-8;
+in rules {
+	true -> {
+		height := height; // do_step will always use the last values, local_step does not advance time so will replace the last signal values! therefore, we must set the signal at time t+h of reaction_torque and height. this is done by a very weird statement:
+		reaction_force := 0; // and just initialise other values at time t+h
+		var prev_height; // to compare new value with previous value
+		for (var iter in 0 .. MAXITER) {
+			prev_height := height;
+			local_step(obstacle); // with delayed input for height
+			local_step(window_sa);
+			if (is_close(prev_height, height, REL_TOL, ABS_TOL)) {
+				break;
+			}
+		}
+	} --> { };
+}

+ 20 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/window_obstacle_sa_loop_BASE_new.sa

@@ -0,0 +1,20 @@
+semantic adaptation window_obstacle_sa_loop// overrides master -> not necessary: custom control rules override master
+for fmu window_sa, obstacle
+input ports motor_speed
+output ports reaction_torque
+param MAXITER = 100;
+param REL_TOL = 1e-8;
+param ABS_TOL = 1e-8;
+control rules {
+	height := height; // do_step will always use the last values, local_step does not advance time so will replace the last signal values! therefore, we must set the signal at time t+h of reaction_torque and height. this is done by a very weird statement:
+	reaction_force := 0; // and just initialise other values at time t+h
+	var prev_height; // to compare new value with previous value
+	for (var iter in 0 .. MAXITER) {
+		prev_height := height;
+		local_step(obstacle); // with delayed input for height
+		local_step(window_sa);
+		if (is_close(prev_height, height, REL_TOL, ABS_TOL)) {
+			break;
+		}
+	}
+}

+ 16 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/window_obstacle_sa_multirate_BASE.sa

@@ -0,0 +1,16 @@
+semantic adaptation window_obstacle_sa_multirate
+for fmu window_obstacle_sa_loop
+input ports motor_speed
+output ports reaction_torque
+param init_motor_speed = 0;
+control rules { multiplied 10 times }
+in var stored_motor_speed := init_motor_speed;
+in var linear_increment;
+in rules {
+	true -> {
+		linear_increment := (motor_speed - stored_motor_speed) / 10;
+		stored_motor_speed := motor_speed;
+	} --> {
+		motor_speed := motor_speed + linear_increment;
+	};
+}

+ 5 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/window_sa_BASE.sa

@@ -0,0 +1,5 @@
+semantic adaptation window_sa
+for fmu window
+out rules {
+	true -> { } --> { reaction_torque := -reaction_torque; };
+}

+ 1 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/oracles/test1.txt

@@ -0,0 +1 @@
+Classes encountered: SemanticAdaptation, Definition, NumberLiteral, Evaluation, Multi, FunctionCall, NumberLiteral

+ 57 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/AbstractSemanticAdaptationGeneratorTest.xtend

@@ -0,0 +1,57 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.tests
+
+import com.google.inject.Inject
+import org.eclipse.xtext.generator.IGenerator2
+import org.junit.Assert
+import org.eclipse.xtext.generator.InMemoryFileSystemAccess
+import org.eclipse.xtext.generator.IFileSystemAccess
+import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationPythonGenerator
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
+
+abstract class AbstractSemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationParserTest {
+
+	@Inject IGenerator2 generator
+	
+	InMemoryFileSystemAccess fsa = new InMemoryFileSystemAccess()
+	
+	/**
+	 * Generates an output file in the file system using the DSL's code generation
+	 */
+	def void generateOutputFile(SemanticAdaptation root) {
+		//println(root.statements)
+		//println(root.imports)
+		generator.doGenerate(root.eResource, this.fsa, null)
+	}
+	
+	/**
+	 * Compares the default file in memory to the given oracle file
+	 */
+	def void compareFiles(String oraclefilename) {
+		val inmemoryfilename = IFileSystemAccess::DEFAULT_OUTPUT+SemanticAdaptationPythonGenerator::FILENAME
+		compareFiles(inmemoryfilename, oraclefilename)
+	}
+	
+	/**
+	 * Compares a given file in memory to the given oracle file
+	 */
+	def void compareFiles(String inmemoryfilename, String oraclefilename) {
+		//println(this.fsa.allFiles)
+		Assert.assertTrue(inmemoryfilename + " not found", this.fsa.allFiles.containsKey(inmemoryfilename))
+		val actualtext = fsa.allFiles.get(inmemoryfilename)
+		val expectedtext = readFile('oracles/'+oraclefilename)
+		Assert.assertEquals(expectedtext, actualtext)
+	}
+	
+	/**
+	 * Parses a given input file, generates code, and compares this to the given oracle file
+	 */
+	def void parseAndGenerateAndCompare(String inputfilename, String oraclefilename) {
+		val root = parseInputFile(inputfilename)
+		generateOutputFile(root)
+		compareFiles(oraclefilename)
+	}
+
+}

+ 26 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/AbstractSemanticAdaptationParserTest.xtend

@@ -0,0 +1,26 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.tests
+
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
+import com.google.inject.Inject
+import org.eclipse.xtext.junit4.InjectWith
+import org.eclipse.xtext.junit4.XtextRunner
+import org.eclipse.xtext.junit4.util.ParseHelper
+import org.junit.runner.RunWith
+
+@RunWith(XtextRunner)
+@InjectWith(SemanticAdaptationInjectorProvider)
+abstract class AbstractSemanticAdaptationParserTest extends AbstractSemanticAdaptationTest {
+
+	@Inject extension ParseHelper<SemanticAdaptation>
+	
+	/**
+	 * parses from an input file
+	 */
+	def SemanticAdaptation parseInputFile(String filename) {
+		return readFile('input/'+filename).parse()
+	}
+
+}

+ 120 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/AbstractSemanticAdaptationTest.xtend

@@ -0,0 +1,120 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.tests
+
+import org.eclipse.xtext.junit4.InjectWith
+import org.eclipse.xtext.junit4.XtextRunner
+import org.junit.runner.RunWith
+import java.io.FileReader
+import static extension com.google.common.io.CharStreams.*
+import java.util.ArrayList
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.common.util.BasicEList
+import org.eclipse.emf.ecore.util.EDataTypeEList
+import org.eclipse.emf.ecore.util.EObjectEList
+import org.eclipse.emf.common.util.EList
+import org.eclipse.xtext.generator.InMemoryFileSystemAccess
+import javax.inject.Inject
+import java.io.File
+import org.eclipse.emf.ecore.resource.ResourceSet
+
+@RunWith(XtextRunner)
+@InjectWith(SemanticAdaptationInjectorProvider)
+abstract class AbstractSemanticAdaptationTest {
+	
+	ArrayList<Integer> visited = new ArrayList<Integer>
+	
+	/*@Inject
+    private InMemoryFileSystemAccess fsa
+	
+	def __setUp(File dir) {
+		for (File f : dir.listFiles()) {
+			if (f.name.endsWith(".sa") && !fsa.isFile(f.name)) {
+				//println("adding " + f.name)
+				fsa.generateFile(f.name, new FileReader(f).readLines.join("\n"))
+			}
+		}
+		//println(fsa.allFiles.keySet)
+	}*/
+	
+	/**
+	 * reads a file from the permanent file system
+	 */
+	def String readFile(String basefilename) {
+		val f = new File(basefilename)
+		//println("testing " + f.name)
+		//__setUp(f.parentFile)
+		//return fsa.readTextFile(f.name).toString()
+		return new FileReader(f).readLines.join("\n")
+	}
+	
+	def print_ast(EObject root) {
+		visited.clear
+		println(root.eClass.name)
+		print_ast_element(root, 0)
+	}
+	
+	private def void print_ast_element(EObject element, int indent) {
+		if (visited.contains(element.hashCode)) {
+			return
+		}
+		visited.add(element.hashCode)
+		element.eClass.EAllStructuralFeatures.forEach[f | 
+			val feature = element.eGet(f)
+			if (feature != null) {
+				if (feature instanceof EList<?>) {
+					(feature as EObjectEList<?>).forEach[e | 
+						print(ind(indent+1) + f.name + "(" + feature.indexOf(e) + "): ")
+						//println("List<" + f.EType.name + ">")
+						if (feature instanceof EObjectEList<?>) {
+							print((e as EObject).class.simpleName.substring(0, (e as EObject).class.simpleName.length-4))
+							printObject((e as EObject), indent+1)
+						} else if (feature instanceof EDataTypeEList<?>) { // in case of enums
+							println(e.class.simpleName + " = " + e)
+						} else if (feature instanceof BasicEList<?>) {
+							throw new Exception(f.name + " other type of list: " + feature.class.name)
+						}
+					]
+				} else {
+					print(ind(indent+1) + f.name + ": ")
+					if (feature instanceof EObject) {
+						print(feature.class.simpleName.substring(0, feature.class.simpleName.length-4))
+						printObject((feature as EObject), indent+1)
+					} else if (feature instanceof String) {
+						println(feature.class.simpleName + " = '" + feature + "'")
+					} else {
+						println(feature.class.simpleName + " = " + feature)
+					}
+				}
+			} else { // filter out null values
+				print(ind(indent+1) + f.name + ": ")
+				println("null")
+			}
+		]
+		return
+	}
+	
+	private def void printObject(EObject element, int indent) {
+		if (visited.contains(element.hashCode)) {
+			val namelist = element.eClass.EAllStructuralFeatures.filter(e | e.name.equals("name"))
+			if (namelist.length == 0) {
+				throw new Exception("Reference " + element + " does not have a 'name' attribute")
+			}
+			println(" -> " + element.eGet(element.eClass.EAllStructuralFeatures.filter(e | e.name.equals("name")).get(0)))
+		} else {
+			println()
+			print_ast_element(element, indent)
+		}
+		return
+	}
+	
+	private def ind(int indent) {
+		var s = ""
+		for (var i = 0 ; i < indent ; i++) {
+			s += "|   "
+		}
+		return s
+	}
+
+}

+ 36 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationGeneratorTest.xtend

@@ -0,0 +1,36 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.tests
+
+import org.junit.Test
+import org.eclipse.xtext.xbase.compiler.CompilationTestHelper
+import com.google.inject.Inject
+import org.junit.runner.RunWith
+import org.eclipse.xtext.junit4.InjectWith
+import org.eclipse.xtext.junit4.XtextRunner
+import java.io.File
+
+@RunWith(XtextRunner)
+@InjectWith(SemanticAdaptationInjectorProvider)
+class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
+	
+	@Inject extension CompilationTestHelper
+	
+	//@Test def powerwindow_model_only() { __generate('input/powerwindow_model_only.sa') }
+	@Test def powerwindow_algebraic_loop_delay_BASE() { __generate('input/powerwindow_algebraic_loop_delay_BASE.sa') }
+	//@Test def powerwindow_algebraic_loop_delay() { __generate('input/powerwindow_algebraic_loop_delay.sa') }
+	@Test def powerwindow_algebraic_loop_iteration_BASE() { __generate('input/powerwindow_algebraic_loop_iteration_BASE.sa') }
+	//@Test def powerwindow_algebraic_loop_iteration() { __generate('input/powerwindow_algebraic_loop_iteration.sa') }
+	//@Test def powerwindow_controller_delay() { __generate('input/powerwindow_controller_delay.sa') }
+	@Test def powerwindow_controller_delay_BASE() { __generate('input/powerwindow_controller_delay_BASE.sa') }
+	//@Test def powerwindow_multi_rate() { __generate('input/powerwindow_multi_rate.sa') }
+	@Test def powerwindow_multi_rate_BASE() { __generate('input/powerwindow_multi_rate_BASE.sa') }
+	//@Test def powerwindow() { __generate('input/powerwindow.sa') }
+	
+	def void __generate(String filename) {
+		val f = new File(filename)
+		readFile(filename).assertCompilesTo('oracles/test1.txt'/*readFile('oracles/' + f.name)*/)
+	}
+
+}

+ 97 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationParsingTest.xtend

@@ -0,0 +1,97 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.tests
+
+import org.eclipse.xtext.junit4.InjectWith
+import org.eclipse.xtext.junit4.XtextRunner
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.eclipse.xtext.junit4.util.ParseHelper
+import com.google.inject.Inject
+import org.eclipse.xtext.junit4.validation.ValidationTestHelper
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.*
+import org.eclipse.emf.ecore.EObject
+import java.util.regex.Pattern
+
+@RunWith(XtextRunner)
+@InjectWith(SemanticAdaptationInjectorProvider)
+class SemanticAdaptationParsingTest extends AbstractSemanticAdaptationTest{
+	
+	@Inject extension ParseHelper<SemanticAdaptation>
+	@Inject extension ValidationTestHelper
+
+//	@Test 
+//	def void loadModule() {
+//		//val root = this.parseInputFile('test1.sa')
+//		val root = readFile('input/test1.sa').parse
+//		root.assertNoErrors
+//		Assert.assertNotNull(root.adaptations.get(0))
+//		Assert.assertNotNull(root.adaptations.get(0).extractsensitivity)
+//		Assert.assertTrue(root.adaptations.get(0).extractsensitivity.length > 0)
+//		Assert.assertTrue(root.adaptations.get(0).inports.length > 0)
+//		Assert.assertEquals(root.adaptations.get(0).inports.get(0).name, 'x')
+//		print_ast(root)
+//	}
+
+	@Test def powerwindow_model_only() { __parseNoErrors('input/powerwindow_model_only.sa') }
+	@Test def powerwindow_algebraic_loop_delay_BASE() { __parseNoErrors('input/powerwindow_algebraic_loop_delay_BASE.sa') }
+	@Test def powerwindow_algebraic_loop_delay() { __parseNoErrors('input/powerwindow_algebraic_loop_delay.sa') }
+	@Test def powerwindow_algebraic_loop_iteration_BASE() { __parseNoErrors('input/powerwindow_algebraic_loop_iteration_BASE.sa') }
+	@Test def powerwindow_algebraic_loop_iteration() { __parseNoErrors('input/powerwindow_algebraic_loop_iteration.sa') }
+	@Test def powerwindow_controller_delay() { __parseNoErrors('input/powerwindow_controller_delay.sa') }
+	@Test def powerwindow_controller_delay_BASE() { __parseNoErrorsPrint('input/powerwindow_controller_delay_BASE.sa') }
+	@Test def powerwindow_multi_rate() { __parseNoErrors('input/powerwindow_multi_rate.sa') }
+	@Test def powerwindow_multi_rate_BASE() { __parseNoErrors('input/powerwindow_multi_rate_BASE.sa') }
+	@Test def powerwindow() { __parseNoErrors('input/powerwindow.sa') }
+	
+	def __parseNoErrors(String filename) {
+		val root = __parse(filename)
+		__assertNoParseErrors(root, filename)
+	}
+	
+	def __parseNoErrorsPrint(String filename) {
+		val root = __parse(filename)
+		print_ast(root)
+		__assertNoParseErrors(root, filename)
+	}
+	
+	def __parse(String filename) {
+		val model = readFile('input/powerwindow_controller_delay.sa').parse
+		val controller = readFile('input/powerwindow_model_only.sa').parse(model.eResource.resourceSet)
+		val algebraicloop = readFile('input/powerwindow_algebraic_loop_delay.sa').parse(controller.eResource.resourceSet)
+		return readFile(filename).parse(algebraicloop.eResource.resourceSet)
+	}
+	
+	def __assertNoParseErrors(EObject root, String filename) {
+		try {
+			root.assertNoErrors
+		} catch (AssertionError e) {
+			val p = Pattern.compile(".*, offset (?<offset>[0-9]+), length (?<length>[0-9]+)")
+			val code = readFile(filename)
+			for (String line : e.message.split("\n")) {
+				val m = p.matcher(line)
+				m.matches()
+				val count = __occurrencesInString(code.subSequence(0, Integer.valueOf(m.group("offset"))).toString(), "\n")
+				print(filename + " at line " + (count+1) + ": ")
+				println(line)
+			}
+			throw e
+		}
+	}
+	
+	def __occurrencesInString(String str, String findstr) {
+		var lastIndex = 0
+		var count = 0
+		while (lastIndex != -1) {
+			lastIndex = str.indexOf(findstr,lastIndex)
+			if (lastIndex != -1) {
+		        count ++
+		        lastIndex += findstr.length()
+		    }
+		}
+		return count
+	}
+
+}

BIN
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.antlr-generator-3.2.0-patch.jar


+ 9 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.classpath

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="src-gen"/>
+	<classpathentry kind="src" path="xtend-gen"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 34 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.project

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>be.uantwerpen.ansymo.semanticadaptation</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>

+ 2 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.settings/org.eclipse.core.resources.prefs

@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=windows-1252

+ 7 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8

+ 29 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/META-INF/MANIFEST.MF

@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: be.uantwerpen.ansymo.semanticadaptation
+Bundle-Vendor: University of Antwerp, Ansymo Lab
+Bundle-Version: 1.0.0.qualifier
+Bundle-SymbolicName: be.uantwerpen.ansymo.semanticadaptation; singleton:=true
+Bundle-ActivationPolicy: lazy
+Require-Bundle: org.eclipse.xtext,
+ org.eclipse.xtext.xbase,
+ org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.emf.ecore,
+ org.eclipse.xtext.xbase.lib,
+ org.antlr.runtime,
+ org.eclipse.xtext.util,
+ org.eclipse.xtend.lib,
+ org.eclipse.emf.common
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.util,
+ be.uantwerpen.ansymo.semanticadaptation.services,
+ be.uantwerpen.ansymo.semanticadaptation.scoping,
+ be.uantwerpen.ansymo.semanticadaptation,
+ be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.impl,
+ be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation,
+ be.uantwerpen.ansymo.semanticadaptation.parser.antlr.internal,
+ be.uantwerpen.ansymo.semanticadaptation.serializer,
+ be.uantwerpen.ansymo.semanticadaptation.validation,
+ be.uantwerpen.ansymo.semanticadaptation.parser.antlr,
+ be.uantwerpen.ansymo.semanticadaptation.generator
+Import-Package: org.apache.log4j

+ 18 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/build.properties

@@ -0,0 +1,18 @@
+source.. = src/,\
+           src-gen/,\
+           xtend-gen/
+bin.includes = model/generated/,\
+               .,\
+               META-INF/,\
+               plugin.xml
+additional.bundles = org.eclipse.xtext.xbase,\
+                     org.eclipse.xtext.common.types,\
+                     org.eclipse.xtext.xtext.generator,\
+                     org.eclipse.emf.codegen.ecore,\
+                     org.eclipse.emf.mwe.utils,\
+                     org.eclipse.emf.mwe2.launch,\
+                     org.eclipse.emf.mwe2.lib,\
+                     org.objectweb.asm,\
+                     org.apache.commons.logging,\
+                     org.apache.log4j,\
+                     com.ibm.icu

+ 10 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/plugin.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="windows-1252"?>
+<?eclipse version="3.0"?>
+<plugin>
+	<extension point="org.eclipse.emf.ecore.generated_package">
+		<package 
+			uri = "http://www.uantwerpen.be/ansymo/semanticadaptation/SemanticAdaptation"
+			class = "be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptationPackage"
+			genModel = "model/generated/SemanticAdaptation.genmodel" />
+	</extension>
+</plugin>

+ 10 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/plugin.xml_gen

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+	<extension point="org.eclipse.emf.ecore.generated_package">
+		<package 
+			uri = "http://www.uantwerpen.be/ansymo/semanticadaptation/SemanticAdaptation"
+			class = "be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptationPackage"
+			genModel = "model/generated/SemanticAdaptation.genmodel" />
+	</extension>
+</plugin>

+ 43 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/GenerateSemanticAdaptation.mwe2

@@ -0,0 +1,43 @@
+module be.uantwerpen.ansymo.semanticadaptation.GenerateSemanticAdaptation
+
+import org.eclipse.xtext.xtext.generator.*
+import org.eclipse.xtext.xtext.generator.model.project.*
+
+var rootPath = ".."
+
+Workflow {
+	
+	component = XtextGenerator {
+		configuration = {
+			project = StandardProjectConfig {
+				baseName = "be.uantwerpen.ansymo.semanticadaptation"
+				rootPath = rootPath
+				runtimeTest = {
+					enabled = true
+				}
+				eclipsePlugin = {
+					enabled = true
+				}
+				eclipsePluginTest = {
+					enabled = true
+				}
+				createEclipseMetaData = true
+			}
+			code = {
+				encoding = "UTF-8"
+				fileHeader = "/*\n * generated by Xtext \${version}\n */"
+			}
+		}
+		language = StandardLanguage {
+			name = "be.uantwerpen.ansymo.semanticadaptation.SemanticAdaptation"
+			fileExtensions = "sa"
+
+			serializer = {
+				generateStub = false
+			}
+			validator = {
+				// composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
+			}
+		}
+	}
+}

+ 365 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/SemanticAdaptation.xtext

@@ -0,0 +1,365 @@
+grammar be.uantwerpen.ansymo.semanticadaptation.SemanticAdaptation with org.eclipse.xtext.common.Terminals
+
+import "http://www.eclipse.org/emf/2002/Ecore" as ecore
+generate semanticAdaptation "http://www.uantwerpen.be/ansymo/semanticadaptation/SemanticAdaptation"
+
+SemanticAdaptation:
+	(imports+=Import)*
+	('module' name=ID)?
+	(elements+=Component)*;
+
+Import:
+	'import' module=[SemanticAdaptation];
+	
+Component:
+	FMU | Connection;
+
+Connection:
+	src=[SpecifiedPort] '->' tgt=[SpecifiedPort];
+
+FMU:
+	AtomicFMU | CompositeFMU | Adaptation;
+
+AtomicFMU:
+	'fmu' name=ID
+	('type' type=ModelType)?
+	('input' 'ports' inports+=Port ("," inports+=Port)*)?
+	('output' 'ports' outports+=Port ("," outports+=Port)* )?
+	('full' 'internal' 'dependencies')?
+	;
+
+CompositeFMU:
+	'fmu' name=ID
+	'composed' 'of' instances+=[FMU] (',' instances+=[FMU])*
+	('input' 'ports' inports+=Port ("," inports+=Port)*)?
+	('output' 'ports' outports+=Port ("," outports+=Port)* )?;
+
+Adaptation:
+	({Adaptation} 'semantic' 'adaptation' name=ID | 
+	{AdaptationWithSpecificMaster} 'semantic' 'adaptation' name=ID 'without' 'master')
+	/*'for' type=ModelType*/ ('for' ('fmu' instances+=[FMU] (',' instances+=[FMU])* /*| 'signal' ports+=[SpecifiedPort] (',' ports+=[SpecifiedPort])**/) )? // only multiple instances in case of CT because we only have CT master?
+	('input' 'ports' inports+=Port ("," inports+=Port)*)? // only in case of instance-specific SA
+	('output' 'ports' outports+=Port ("," outports+=Port)* )? // only in case of instance-specific SA
+	('param' params+=ParamDeclaration)*
+//	(globalvars+=Declaration)*
+	// algebraic loop generates an FMU encapsulating the loop
+	// note that the order of semantic adaptations is prefixed in case of a algebraic loop:
+	// adaptations on internal signals of the loop are inner most, then the algebraic loop iteration, then adaptations on external signals
+	(generalrules+=GeneraleRule)*
+	((in=InRulesBlock)? & (out=OutRulesBlock)? & (control=ControlRuleBlock)?)
+//	('contains' '{' adaptations+=Adaptation+ '}')? // I prefer no structural information here, this belongs to a graphical model
+	;
+	
+ModelType: DE | UT | CT | DT;
+	
+DE: 'DE' | 'de' | 'DiscreteEvent' | 'Discrete' 'Event' | 'discrete' 'event';
+UT: 'UT' | 'ut' | 'Untimed' | 'untimed';
+CT: 'CT' | 'ct' | 'ContinuousTime' | 'Continuous' 'Time' | 'continuous' 'time';
+DT: 'DT' | 'dt' | 'DiscreteTime' | 'Discrete' 'Time' | 'discrete' 'time';
+
+GeneraleRule:
+	AlgebraicLoopSolution | MultiRate | Derivative;
+
+AlgebraicLoopSolution:
+	{AlgebraicLoopSolutionFixPointIteration} 'successive' 'substitution' 'starts' 'at' signals+=[SpecifiedPort] (('and'|',') signals+=[SpecifiedPort])? 'with' params+=SettingAssignment ('and' params+=SettingAssignment)* | 
+	{AlgebraicLoopSolutionDelayIntroduction} 'delay' 'at' signals+=[SpecifiedPort] (('and'|',') signals+=[SpecifiedPort])?; // TODO: must be in in or out rule
+	
+MultiRate:
+	'multiply' 'rate' rate=INT 'times' ('with' interpolation=Interpolation)?; // default first order interpolation
+
+Interpolation:
+	({ZeroOrderInterpolation} 'no' | {FirstOrderInterpolation} 'first' 'order' | {SecondOrderInterpolation} 'second' 'order' | {ThirdOrderInterpolation} 'third' 'order' | {FourthOrderInterpolation} 'fourth' 'order') 'interpolation' | // automatically does lower order interpolation in the beginning of simulation when no previous signal values are available
+	{CustomOrderInterpolation} 'interpolation' 'of' 'order' order=INT | 
+	{CustomInterpolation} 'interpolation' function=AnonymousFunction;
+	
+Derivative:
+	{PredefinedDerivative} 'with' (directionalderivative?='directionalderivative'? & timederivative?='timederivative'?) |
+	{DefinedDerivative} 'extract' (extractdirectionalderivative?='directionalderivative'? & // decide sensitivity
+				extracttimederivative?='timederivative'? & // decide sensitivity
+				extractsensitivity+=AnonymousFunction* );  // new sensitivity definitions
+
+InOutRules:
+	InRulesBlock | OutRulesBlock;
+
+InRulesBlock:
+	{InRulesBlock} ('in' globalvars+=Declaration)* 'in' 'rules' ('with' setting+=GeneralSetting (',' setting+=GeneralSetting)*)? '{' iterationvars+=Declaration* rules+=DataRule* '}';
+
+OutRulesBlock:
+	{OutRulesBlock} ('out' globalvars+=Declaration)* 'out' 'rules' ('with' setting+=GeneralSetting (',' setting+=GeneralSetting)*)? '{' iterationvars+=Declaration* rules+=DataRule* '}';
+
+ControlRuleBlock:
+	{ControlRuleBlock} 'control' 'rules' '{' controlrule=ControlRule '}'; // TODO: multiple rules or just one?
+
+DataRule: // condition -> state transition --> output function
+	(((condition=RuleCondition "->" statetransitionfunction=StateTransitionFunction) | ConditionStateTransition | ConditionLessRule) ("-->" outputfunction=OutputFunction)? | AlgebraicLoopSolution) ';';
+
+GeneralSetting:
+	{GeneralVariableSetting} strategy=RuleStrategy params+=SettingAssignment ('and' params+=SettingAssignment)* | 
+	OutputFunction;
+	
+SettingAssignment:
+	setting=RuleSetting '=' expr=Expression;
+	
+RuleCondition:
+	{RuleCondition} condition=Expression (params+=SettingAssignment ('and' params+=SettingAssignment)*)? | 
+	{CompositeRuleCondition} '{' statements+=Statement* returnstatement=ReturnStatement '}';
+
+RuleSetting:
+	{AbsoluteTolerance} 'absolute' 'tolerance' | // todo relative/absolute tolerance (look up float equality)
+	{RelativeTolerance} 'relative' 'tolerance'; // todo relative/absolute tolerance (look up float equality)
+	// otherwise null
+	
+RuleStrategy:
+	{Crossing} 'crossing';
+	
+StateTransitionFunction:
+	{StateTransitionFunction} expression=Expression |
+	{StateTransitionFunction} '{' statements+=Statement* '}' |
+	{StateTransitionFunction} assignment=Assignment;// |
+	//{StoreNull} ('null' | 'nothing') |
+	//{StateTransitionFunction} 'todo';
+
+ConditionLessRule:
+	assignment=Assignment;
+
+ConditionStateTransition:
+	quantization=Quantize;
+
+Quantize returns ConditionStoreStrategy:
+	{FiniteQuantize} 'quantize' '(' signal=[SpecifiedPort] ',' zones+=StringLiteral (',' boundaries+=ArithmeticExpression ',' zones+=StringLiteral)* ')' |
+	{FunctionQuantize} 'quantize' '(' signal=[SpecifiedPort] ',' '=' function=ArithmeticExpression ')' |
+	{LinearQuantize} 'quantize' signal=[SpecifiedPort] 'every' steps=ArithmeticExpression ('with'? 'offset' offset=ArithmeticExpression)?;
+	
+OutputFunction:
+	{NoHold} 'no' 'hold' |
+	{ZeroOrderHold} (('zero' 'order' 'hold') | 'ZOH') |
+	{FirstOrderHold} (('first' 'order' 'hold') | 'FOH') |
+	{CustomOutputFunction} expr=Expression |
+	{CompositeOutputFunction} '{' statements+=Statement* (returnstatement=ReturnStatement)? '}';
+	
+ControlRule:
+	{TriggeredControlRule} 'triggered' 'by' condition=Expression |
+	{ImpliedControlRule} 'implied' | // the default
+	{PeriodicControlRule} 'periodic' ('at' init_time=REALTYPE)? 'every' period=REALTYPE | 
+	{MultipliedControlRule} 'multiplied' multiplication=INT 'times' | 
+	StateTransitionFunction;
+
+AnonymousFunction: // has access to ports
+	{FunctionExpression} '{=' code=Expression '}'| 
+	{FunctionBody} '{' statements+=Statement* returnstatement=ReturnStatement '}' |  // should return something
+	FunctionDeclaration; // TODO: should return something
+	
+/*[SpecifiedPort]: // if ports need owners
+	port=[Port] |
+	{Output[SpecifiedPort]} owner=[FMU] '.' port=[Port] | 
+	{Input[SpecifiedPort]} owner=[FMU] '<-' port=[Port];*/
+SpecifiedPort: Port;
+
+Port:
+	// TODO: add initial values to ports (to do 1st, 2nd, ... order stuff)
+	// TODO: add internal destination/source of port
+	// Unity conversions: https://pint.readthedocs.io/en/0.7.2/
+	name=ID (':=' initval=LiteralOrArray)? ( multiplicity=Multiplicity )? ( '(' unity=Unity ')' )? ('->' target=[SpecifiedPort] | '-->' dependency+=[SpecifiedPort] (dependency+=[SpecifiedPort])*)?;
+
+Multiplicity:
+	'[' (lower=INT '..')? upper=INT ']';
+
+Unity:
+	DivideUnity;
+	
+DivideUnity returns Unity:
+	MultiplyUnity (({DivideUnity.left=current} '/') right=MultiplyUnity)*;
+
+MultiplyUnity returns Unity:
+	AtomicUnity (({MultiplyUnity.left=current} '.') right=AtomicUnity)*;
+
+AtomicUnity:
+	name=ID ('^' (power=INT | power=INTTYPE))?; // somehow LETTERS as name does not work, so power will never be parsed...
+
+//FunctionBody:
+//	statements+=Statement* returnstatement=ReturnStatement;
+	
+Statement:
+	NestableStatement | FunctionDeclaration;
+
+NestableStatement:
+	Declaration | (Assignment  ';') | (Procedure  ';') | For | If | BreakStatement;
+	
+For:
+	'for' '(' 'var' iterator=DeclaredParameter 'in' iterable=Range ')' '{' (statements+=NestableStatement)* '}';
+	
+If:
+	'if' '(' ifcondition=Expression ')' '{' (ifstatements+=NestableStatement)* '}' ('else' '{' (elsestatements+=NestableStatement)* '}')?;
+	
+FunctionDeclaration:
+	'def' name=ID ('(' args+=DeclaredParameter (',' args+=DeclaredParameter)* ')')? 
+	'{' statements+=Statement* returnstatement=ReturnStatement '}';
+
+Declaration:
+	'var' name=ID (':=' expr=Expression)? ';';
+
+ParamDeclaration:
+	name=ID '=' expr=Expression ';';
+
+ReturnStatement:
+	'return' Expression ';';
+
+BreakStatement:
+	{BreakStatement} 'break' ';';
+
+DeclaredParameter:
+	name=ID;
+	
+AbstractDeclaration: // can contain overlapping elements as long as it is only used as reference
+	Port | ParamDeclaration | Declaration | DeclaredParameter | FunctionDeclaration;
+
+LValueDeclaration: // can contain overlapping elements as long as it is only used as reference
+	Port | ParamDeclaration | Declaration | DeclaredParameter;
+
+Assignment:
+	lvalue=Variable ':=' expr=Expression; // TODO: to what can be assigned? only local vars?
+
+Expression:
+	OrExpression;
+
+OrExpression returns Expression:
+	AndExpression ({Or.left=current} 'or' right=AndExpression)*;
+
+AndExpression returns Expression:
+	NotExpression ({And.left=current} 'and' right=NotExpression)*;
+	
+NotExpression returns Expression:
+	{Not} 'not' left=GreaterThanExpression | 
+	GreaterThanExpression;
+	
+GreaterThanExpression returns Expression:
+	LessThanExpression ({GreaterThan.left=current} '>' right=ArithmeticExpression)?;
+	
+LessThanExpression returns Expression:
+	GreaterThanOrEqualsExpression ({LessThan.left=current} '<' right=ArithmeticExpression)?;
+
+GreaterThanOrEqualsExpression returns Expression:
+	LessThanOrEqualsExpression ({GreaterThanOrEquals.left=current} '>=' right=ArithmeticExpression)?;
+	
+LessThanOrEqualsExpression returns Expression:
+	EqualsExpression ({LessThanOrEquals.left=current} '<=' right=ArithmeticExpression)?;
+
+EqualsExpression returns Expression:
+	NotEqualsExpression ({Equals.left=current} '==' right=ArithmeticExpression)?;
+	
+NotEqualsExpression returns Expression:
+	CrossesFromBelowExpression ({NotEquals.left=current} '!=' right=ArithmeticExpression)?;
+		
+CrossesFromBelowExpression returns Expression:
+	CrossesFromAboveExpression ({CrossesFromBelow.left=current} '>!' right=ArithmeticExpression)?;
+	
+CrossesFromAboveExpression returns Expression:
+	BooleanFunction ({CrossesFromAbove.left=current} '<!' right=BooleanFunction)?;
+	
+BooleanFunction returns Expression:
+	{Otherwise} 'otherwise' '(' ref=[SpecifiedPort] ')' |
+	{Otherwise} 'otherwise' ref=[SpecifiedPort] |
+	ArithmeticExpression;
+
+ArithmeticExpression returns Expression:
+	Addition;
+
+Addition returns Expression:
+	Multiplication (({Plus.left=current} '+' | {Minus.left=current} '-') right=Multiplication)*;
+
+Multiplication returns Expression:
+	Range (({Multi.left=current} '*' | {Div.left=current} '/') right=Range)*;
+
+Range returns Expression:
+	UnaryOrPrimaryExpression ({Range.left=current} '..' right=UnaryOrPrimaryExpression)?;
+
+UnaryOrPrimaryExpression returns Expression:
+	NegationExpression | PrimaryExpression;
+	
+NegationExpression returns Expression:
+	{Neg} '-' right=PrimaryExpression;
+
+PrimaryExpression returns Expression:
+	'(' Expression ')' | Literal | BuiltinFunction | Var;
+
+LiteralOrArray:
+	{ArrayLiteral} '[' elements+=Literal (',' elements+=Literal)* ']' |
+	Literal;
+
+Literal:
+	IntLiteral | RealLiteral | StringLiteral | BoolLiteral | NullLiteral; //| StepLiteral;
+
+IntLiteral:
+	value=INTTYPE | value=INT;
+	
+RealLiteral:
+	value=REALTYPE;
+	
+StringLiteral:
+	value=STRING;
+	
+BoolLiteral:
+	value=('true'|'false');
+	
+//StepLiteral:
+//	value=('accept'|'discard');
+	
+NullLiteral:
+	value='null';
+	
+BuiltinFunction:
+	{Floor} name='floor' '(' args+=ArithmeticExpression ')' | 
+	{Ceil} name='ceil' '(' args+=ArithmeticExpression ')' | 
+	{Round} name='round' '(' args+=ArithmeticExpression (',' args+=ArithmeticExpression)? ')' |
+	{Max} name='max' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' |
+	{Min} name='min' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' |
+	{Abs} name='abs' '(' args=ArithmeticExpression ')' |
+	{Close} name='is_close' '(' args+=ArithmeticExpression ',' args+=ArithmeticExpression ',' args+=ArithmeticExpression ',' args+=ArithmeticExpression ')' | 
+	{IsSet} name='is_set' '(' args=Variable ')'// a, b, relative tolerance, absolute tolerance 
+	;
+	
+Procedure:
+	{Reject} name='reject' |
+	{Step} name='local_step' '(' fmu=[FMU] ')' |
+	{Discard} name='discard' '(' args=Variable ')'; // arg: new proposed step size
+	
+Var:
+	{StepSize} name='h' | 
+	{CurrentTime} name='t' | 
+	{GenericSignal} name='signal' ('[' (
+		index=NOW | 
+		index=PREV | 
+		index=INTTYPE |
+		index=INT // TODO: int must be less than -1, TODO: expression
+		) ']')? |
+	Variable |
+	FunctionCall; // add "directionalderivative"
+	
+Variable:
+	ref=[LValueDeclaration] ('[' (
+		index=NOW | 
+		index=PREV | 
+		index=INTTYPE |
+		index=INT  // TODO: int must be less than -1, TODO: expression
+		) ']')?; // TODO: NO RECURSION (must terminate)
+
+FunctionCall:
+	ref=[FunctionDeclaration] '(' args+=ArithmeticExpression (',' args+=ArithmeticExpression)* ')'; // TODO: NO RECURSION (must terminate)
+
+//SignedInt returns ecore::EInt:
+//	('-'|'+')? INT;
+
+//SignedReal returns ecore::EBigDecimal:
+//	'-'? REAL;
+
+terminal INTTYPE returns ecore::EInt : '-' INT;
+	
+terminal REALTYPE returns ecore::EFloat : '-'? ((( INT '.' INT | '.' INT | INT '.') (('e'|'E') ('-'|'+') INT)?) | (INT ('e'|'E') ('-'|'+') INT));
+//terminal UNSREALTYPE returns ecore::EFloat : ((( INT '.' INT | '.' INT | INT '.') (('e'|'E') ('-'|'+') INT)?) | (INT ('e'|'E') ('-'|'+') INT));
+	
+terminal NOW returns ecore::EInt: 'now';
+terminal PREV returns ecore::EInt: 'prev';
+	
+//terminal REAL returns ecore::EBigDecimal: INT? '.' INT;
+
+//terminal LETTERS returns ecore::EString: ('a'..'z' | 'A'..'Z')+;

+ 24 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/SemanticAdaptationRuntimeModule.xtend

@@ -0,0 +1,24 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation
+
+import be.uantwerpen.ansymo.semanticadaptation.valueconverter.SemanticAdaptationValueConverters
+import be.uantwerpen.ansymo.semanticadaptation.scoping.SemanticAdaptationScopeProvider
+import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationPythonGenerator
+
+/**
+ * Use this class to register components to be used at runtime / without the Equinox extension registry.
+ */
+class SemanticAdaptationRuntimeModule extends AbstractSemanticAdaptationRuntimeModule {
+	
+	override bindIValueConverterService() {
+		return SemanticAdaptationValueConverters
+	}
+	override bindIScopeProvider() {
+		return SemanticAdaptationScopeProvider
+	}
+	override bindIGenerator2() {
+		return SemanticAdaptationPythonGenerator
+	}
+}

+ 15 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/SemanticAdaptationStandaloneSetup.xtend

@@ -0,0 +1,15 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation
+
+
+/**
+ * Initialization support for running Xtext languages without Equinox extension registry.
+ */
+class SemanticAdaptationStandaloneSetup extends SemanticAdaptationStandaloneSetupGenerated {
+
+	def static void doSetup() {
+		new SemanticAdaptationStandaloneSetup().createInjectorAndDoEMFRegistration()
+	}
+}

+ 25 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationGenerator.xtend

@@ -0,0 +1,25 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.generator
+
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.xtext.generator.AbstractGenerator
+import org.eclipse.xtext.generator.IFileSystemAccess2
+import org.eclipse.xtext.generator.IGeneratorContext
+
+/**
+ * Generates code from your model files on save.
+ * 
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
+ */
+class SemanticAdaptationGenerator extends AbstractGenerator {
+
+	override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
+//		fsa.generateFile('greetings.txt', 'People to greet: ' + 
+//			resource.allContents
+//				.filter(typeof(Greeting))
+//				.map[name]
+//				.join(', '))
+	}
+}

+ 111 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationPythonGenerator.xtend

@@ -0,0 +1,111 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.generator
+
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.xtext.generator.AbstractGenerator
+import org.eclipse.xtext.generator.IFileSystemAccess2
+import org.eclipse.xtext.generator.IGeneratorContext
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.*
+import org.eclipse.emf.ecore.EClass
+
+/**
+ * Generates code from your model files on save.
+ * 
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
+ */
+class SemanticAdaptationPythonGenerator extends AbstractGenerator {
+	
+	public final static String FILENAME = 'output.test.txt'
+
+	override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
+		for (Adaptation a : resource.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation)) {
+			fsa.generateFile(FILENAME, a.compile)
+			println(fsa.readTextFile(FILENAME))
+		}
+	}
+	
+	def compile(Adaptation a) '''
+import logging
+
+from abstract_units.AbstractSimulationUnit import AbstractSimulationUnit, \
+    STEP_ACCEPT
+«FOR fmu:a.instances.filter(AtomicFMU)»
+from case_study.units.ct_based.«fmu.name» import «fmu.name»
+«ENDFOR»
+«FOR i:a.instances.filter(Adaptation)»
+NOT YET IMPLEMENTED
+«ENDFOR»
+
+l = logging.getLogger()
+
+class PowerInputAdaptation_Event(AbstractSimulationUnit):
+    """
+    This is the adaptation of the events coming out of the Controller Statechart.
+    It gets as input an event, and output two signals, to be coupled to the power system.
+    Whenever it gets an input, it stores the appropriate signals for the output until another event comes along.
+    It's basically a ZOH.
+    
+    Example interaction:_______________
+    f = PowerInputAdaptation_Event(...)
+    f.enterInitMode()
+    f.setValues(...,"SomeInEvent")
+        This tells the FMU what the input is.
+        The sFMU will record this input (if not "") to the internal state. 
+        and initial input ("SomeInEvent").
+    (up,down) = f.getValues(...)
+        The values that can be returned are initial_up and initial_down
+    f.exitInitMode()
+    
+    f.setValues(..., "SomeInEvent")
+        The definition of a new event gets recorded by the fmu
+    f.doStep(..., H)
+        The internal state gets updated according to the new input event.
+        Or kept the same if the new event is ""
+    (up,down) = f.getValues(...)
+        The last event processed is in the output variable, ready to be collected.
+    ______________________________
+    
+    """
+    
+    def __init__(self, name):
+        
+        self.in_event = "in_event"
+        self.out_down = "out_down"
+        self.out_up = "out_up"
+        input_vars = [self.in_event]
+        state_vars = [self.out_down, self.out_up]
+        
+        algebraic_functions = {}
+        
+        AbstractSimulationUnit.__init__(self, name, algebraic_functions, state_vars, input_vars)
+    
+    def _doInternalSteps(self, time, step, iteration, step_size):
+        l.debug(">%s._doInternalSteps(%f, %d, %d, %f)", self._name, time, step, iteration, step_size)
+        
+        assert iteration == 0, "Fixed point iterations not supported yet."
+        
+        previous_output = self.getValues(step-1, iteration, self._getStateVars())
+        current_input = self.getValues(step, iteration, self._getInputVars())
+        
+        l.debug("%s.previous_output=%s", self._name, previous_output)
+        l.debug("%s.current_input=%s", self._name, current_input)
+        
+        next_output = previous_output
+        in_ev = current_input[self.in_event]
+        if in_ev != "":
+            l.debug("Updating internal state due to input %s...", in_ev)
+            next_out_up = 1.0 if in_ev=="up" else 0.0
+            next_out_down = 1.0 if in_ev=="down" else 0.0
+            next_output = {self.out_down: next_out_down, self.out_up: next_out_up}
+            
+        # Store the values into the state
+        self.setValues(step, iteration, {self.out_down: next_output[self.out_down],
+                                         self.out_up: next_output[self.out_up] })
+        
+        
+        l.debug("<%s._doInternalSteps() = (%s, %d)", self._name, STEP_ACCEPT, step_size)
+        return (STEP_ACCEPT, step_size)
+'''
+}

+ 68 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/interpreter/Interpreter.xtend

@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package be.uantwerpen.ansymo.semanticadaptation.interpreter
+
+import com.google.common.collect.ImmutableMap
+import com.google.common.collect.Maps
+import java.math.BigDecimal
+import java.math.RoundingMode
+
+/** 
+ * an interpreter for instances of EClasses of the {@link ArithmeticsPackage}.
+ * It internally uses a polymorphic dispatcher to dispatch between the implementations for the different EClasses.
+ */
+class Interpreter {
+
+//	def BigDecimal evaluate(Expression obj) {
+//		return evaluate(obj, ImmutableMap.<String, BigDecimal>of())
+//	}
+//
+//	def BigDecimal evaluate(Expression obj, ImmutableMap<String, BigDecimal> values) {
+//		return internalEvaluate(obj, values)
+//	}
+//
+//	def dispatch protected internalEvaluate(NumberLiteral e, ImmutableMap<String, BigDecimal> values) {
+//		e.value
+//	}
+//
+//	/** 
+//	 * @param values the currently known values by name 
+//	 */
+//	def dispatch protected BigDecimal internalEvaluate(FunctionCall e, ImmutableMap<String, BigDecimal> values) {
+//		if (e.func instanceof DeclaredParameter) {
+//			return values.get(e.func.name)
+//		}
+//		switch d : e.func {
+//			Definition: {
+//				var params = Maps.newHashMap
+//				for (var int i = 0; i < e.args.size; i++) {
+//					var declaredParameter = d.args.get(i)
+//					var evaluate = evaluate(e.args.get(i), values)
+//					params.put(declaredParameter.getName(), evaluate)
+//				}
+//				return evaluate(d.expr, ImmutableMap.copyOf(params))
+//			}
+//		}
+//	}
+//
+//	def dispatch protected BigDecimal internalEvaluate(Plus plus, ImmutableMap<String, BigDecimal> values) {
+//		evaluate(plus.left, values) + evaluate(plus.right, values)
+//	}
+//
+//	def dispatch protected BigDecimal internalEvaluate(Minus minus, ImmutableMap<String, BigDecimal> values) {
+//		evaluate(minus.left, values) - evaluate(minus.right, values)
+//	}
+//
+//	def dispatch protected BigDecimal internalEvaluate(Div div, ImmutableMap<String, BigDecimal> values) {
+//		evaluate(div.left, values).divide(evaluate(div.right, values), 20, RoundingMode.HALF_UP)
+//	}
+//
+//	def dispatch protected BigDecimal internalEvaluate(Multi multi, ImmutableMap<String, BigDecimal> values) {
+//		evaluate(multi.left, values) * evaluate(multi.right, values)
+//	}
+}

+ 315 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/scoping/SemanticAdaptationScopeProvider.xtend

@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package be.uantwerpen.ansymo.semanticadaptation.scoping
+
+import org.eclipse.emf.ecore.EReference
+import org.eclipse.xtext.EcoreUtil2
+import org.eclipse.xtext.scoping.IScope
+import org.eclipse.xtext.scoping.Scopes
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.*
+import org.eclipse.emf.common.util.BasicEList
+import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.scoping.IGlobalScopeProvider
+import com.google.inject.Inject
+import org.eclipse.emf.ecore.resource.Resource
+import com.google.common.base.Predicate
+import org.eclipse.xtext.resource.IEObjectDescription
+import org.eclipse.xtext.scoping.impl.IScopeWrapper
+import org.eclipse.emf.common.util.EList
+import java.util.List
+import java.util.LinkedList
+
+/**
+ * This class contains custom scoping description.
+ * 
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
+ * on how and when to use it.
+ */
+ 
+class SemanticAdaptationScopeProvider extends AbstractDeclarativeScopeProvider  {
+	// comment out getScope for per-type scope
+
+	/* provides a global scope for all elements!
+	 * overrides all the remainder of this class
+	 */
+	override getScope(EObject context, EReference reference) {
+		if (reference === SemanticAdaptationPackage.Literals.IMPORT__MODULE) {
+			return getGlobalScope(context.eResource, reference)
+		}
+		val module = EcoreUtil2.getContainerOfType(context, SemanticAdaptation)
+		var result = IScope.NULLSCOPE
+		for (import : module.imports) {
+			if (!import.module.eIsProxy)
+				result = getModuleScope(context, reference, import.module, result)
+		}
+		result = getModuleScope(context, reference, module, result)
+		//println(Scopes.scopeFor(context.eResource.allContents.toList, result))
+		return Scopes.scopeFor(context.eResource.allContents.toList, result)
+	}
+	
+	// todo: only correct src and tgt references
+	def scope_Connection_src(Connection context, EReference r) {
+		return __getImportedScope(context, r).__addScope(__getAllPorts(context))
+	}
+	
+	def scope_Connection_tgt(Connection context, EReference r) {
+		return __getImportedScope(context, r).__addScope(__getAllPorts(context))
+	}
+	
+	def scope_Port_target(Port context, EReference r) {
+		return __getImportedScope(context, r).__addScope(__getAllPorts(context))
+	}
+	
+	def scope_AlgebraicLoopSolution_signals(AlgebraicLoopSolution context, EReference r) {
+		return __getImportedScope(context, r).__addScope(__getAllPorts(context))
+	}
+	
+	def scope_Variable_ref(Variable context, EReference r) {
+		//println(context.eContainer())
+		//var scope = __getImportedScope(context, r)
+		var EList<EObject> elements = __getAllPorts(context)
+		val outputfunction = EcoreUtil2.getContainerOfType(context, OutputFunction)
+		if (outputfunction != null) {
+			val rule = outputfunction.eContainer as DataRule
+			if (rule.statetransitionfunction != null) {
+				elements += rule.statetransitionfunction.statements
+			}
+		}
+		elements += context.__getFrom(If, "ifstatements", Declaration, true).flatten
+		elements += context.__getFrom(If, "ifstatements", FunctionDeclaration, true).flatten
+		elements += context.__getFrom(For, "iterator", null, true).flatten
+		elements += context.__getFromElement(StateTransitionFunction, "statements", Declaration)
+		elements += context.__getFromElement(StateTransitionFunction, "statements", FunctionDeclaration)
+		elements += context.__getFromElement(InOutRules, "globalvars")
+		elements += context.__getFromElement(InOutRules, "iterationvars")
+		elements += context.__getFromElement(Adaptation, "params")
+		
+		return __getImportedScope(context, r).__addScope(elements)
+	}
+	
+	def scope_Adaptation_instances(Adaptation context, EReference r) {
+		return __getImportedScope(context, r)
+	}
+	
+	def scope_Adaptation_ports(Adaptation context, EReference r) {
+		return __getImportedScope(context, r)
+	}
+	
+	def scope_CompositeFMU_instances(SemanticAdaptation context, EReference r) {
+		return __getImportedScope(context, r)
+	}
+	
+	def scope_Step_fmu(Step context, EReference r) {
+		return Scopes.scopeFor(EcoreUtil2.getContainerOfType(context, Adaptation).instances, IScope.NULLSCOPE)
+	}
+	
+	/*def EObject __getAncestorOfType(EObject object, Class<?> type) { // same as EcoreUtil2.getContainerOfType
+		val parent = object.eContainer
+		if (parent == null) {
+			return null
+		}
+		if (type.isAssignableFrom(parent.class)) {
+			return parent
+		} else{
+			return __getAncestorOfType(object.eContainer, type)
+		}
+	}*/
+	
+	def __addScope(IScope scope, EList elements) {
+		return Scopes.scopeFor(elements, scope)
+	}
+	
+	def __getAllPorts(EObject context) {
+		val module = EcoreUtil2.getContainerOfType(context, SemanticAdaptation)
+		var elementlist = new BasicEList<EObject>;
+		for (Component element : module.elements) {
+			if (element instanceof FMU) {
+				elementlist += element.inports+element.outports
+			}
+		}
+		return elementlist
+	}
+	
+	def __getFromElement(EObject context, Class<? extends EObject> containertype, String featurename, Class<? extends EObject> featuretype) {
+		/*val object = EcoreUtil2.getContainerOfType(context, containertype)
+		if (object != null) {
+			val feature = object.eClass.EAllStructuralFeatures.findFirst(f | f.name.equals(featurename))
+			if (feature != null) {
+				val featurevalue = object.eGet(feature)
+				if (featurevalue instanceof EList) {
+					if (featuretype != null) {
+						return featurevalue.filter(v | featuretype.isInstance(v))
+					} else {
+						return featurevalue
+					}
+				} else {
+					if (featuretype == null || featuretype.isInstance(featurevalue)) {
+						val featurevaluelist = new BasicEList()
+						featurevaluelist.add(featurevalue)
+						return featurevaluelist
+					}
+				}
+			} else {
+				throw new Exception("Feature " + featurename + " not found in object of type " + containertype.name)
+			}
+		}
+		return new BasicEList<EObject>()*/
+		return context.__getFrom(containertype, featurename, featuretype, false).flatten
+	}
+	
+	def __getFromElement(EObject context, Class<? extends EObject> containertype, String featurename) {
+		return context.__getFromElement(containertype, featurename, null)
+	}
+	
+	/**
+	 * Look from context to root for elements
+	 * @params:
+	 * 		context: element to start from
+	 * 		containertype: type of elements that have a feature that needs to be found
+	 * 		featurename: name of feature that must be a feature of containertype
+	 * 		featuretype: only take features of featuretype
+	 * 		all: if true: go through all instances of container type; if false: only the first encounter from context to root 
+	 * 
+	 * @returns:
+	 * 		all: list of lists of found elements (from context to root)
+	 * 		!all: list of found elements (first encounter from context to root)
+	 */
+	def List<? extends List<? extends EObject>> __getFrom(EObject context, Class<? extends EObject> containertype, String featurename, Class<? extends EObject> featuretype, boolean all) {
+		val List<List<EObject>> listOfElementLists = new LinkedList<List<EObject>>()
+		for (object : EcoreUtil2.getAllContainers(context)) {
+			if (containertype.isInstance(object)) {
+				val List<EObject> listOfElements = new LinkedList<EObject>()
+				val feature = object.eClass.EAllStructuralFeatures.findFirst(f | f.name.equals(featurename))
+				if (feature != null) {
+					val featurevalue = object.eGet(feature)
+					if (featurevalue instanceof EList) {
+						if (featuretype != null) {
+							listOfElements.addAll(featurevalue.filter(v | featuretype.isInstance(v)).map(v | v as EObject))
+						} else {
+							listOfElements.addAll(featurevalue)
+						}
+					} else if (featurevalue instanceof EObject) {
+						if (featuretype == null || featuretype.isInstance(featurevalue)) {
+							listOfElements.add(featurevalue)
+						}
+					} else {
+						throw new Exception("todo")
+					}
+				} else {
+					throw new Exception("Feature " + featurename + " not found in object of type " + containertype.name)
+				}
+				listOfElementLists.add(listOfElements)
+				if (!all) {
+					return listOfElementLists
+				}
+			}
+		}
+		return listOfElementLists
+	}
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	@Inject
+	private IGlobalScopeProvider globalScopeProvider;
+
+	def protected IScope getGlobalScope(Resource context, EReference reference) {
+		return getGlobalScope(context, reference, null);
+	}
+	
+	def protected IScope getGlobalScope(Resource context, EReference reference, Predicate<IEObjectDescription> filter) {
+		return wrap(globalScopeProvider.getScope(context, reference, filter));
+	}
+	
+	private IScopeWrapper scopeWrapper;
+	
+	def public void setWrapper(IScopeWrapper wrapper) {
+		this.scopeWrapper = wrapper;
+	}
+
+	def protected IScope wrap(IScope scope) {
+		if (scopeWrapper!=null){
+			return scopeWrapper.wrap(scope)
+		} else {
+			return scope
+		}
+	}
+	
+	def __getImportedScope(EObject context, EReference reference) {
+		if (reference === SemanticAdaptationPackage.Literals.IMPORT__MODULE) {
+			return getGlobalScope(context.eResource, reference)
+		}
+		val module = EcoreUtil2.getContainerOfType(context, SemanticAdaptation)
+		var result = IScope.NULLSCOPE
+		for (import : module.imports) {
+			if (!import.module.eIsProxy)
+				result = getModuleScope(context, reference, import.module, result)
+		}
+		result = getModuleScope(context, reference, module, result)
+		return result//getDefinitionScope(context, reference, result)
+	}
+	
+	def getModuleScope(EObject context, EReference reference, SemanticAdaptation module, IScope parent) {
+		// FMUs and ports are visible
+		val allDefinitions = module.elements.filter(FMU) + __getAllPorts(module)
+		//println(allDefinitions)
+		return Scopes.scopeFor(allDefinitions, parent)
+	}
+	
+	/*def getDefinitionScope(EObject context, EReference reference, IScope parent) {
+		val containingDef = EcoreUtil2.getContainerOfType(context, Definition)
+		if (containingDef === null) {
+			return parent
+		}
+		return Scopes.scopeFor(containingDef.args, parent)
+	}*/
+
+	
+//class SemanticAdaptationScopeProvider extends AbstractGlobalScopeDelegatingScopeProvider {
+
+//	override getScope(EObject context, EReference reference) {
+//		if (reference === SemanticAdaptationPackage.Literals.IMPORT__MODULE) {
+//			return super.getGlobalScope(context.eResource, reference)
+//		}
+//		val module = EcoreUtil2.getContainerOfType(context, Module)
+//		var result = IScope.NULLSCOPE
+//		for (import : module.imports) {
+//			if (!import.module.eIsProxy)
+//				result = getModuleScope(context, reference, import.module, result)
+//		}
+//		result = getModuleScope(context, reference, module, result)
+//		return getDefinitionScope(context, reference, result)
+//	}
+//	
+//	def getModuleScope(EObject context, EReference reference, Module module, IScope parent) {
+//		val allDefinitions = module.statements.filter(Definition)
+//		if (context instanceof FunctionCall) {
+//			return Scopes.scopeFor(allDefinitions.filter[context.args.size == args.size], parent)
+//		} else {
+//			return Scopes.scopeFor(allDefinitions, parent)
+//		}
+//	}
+//	
+//	def getDefinitionScope(EObject context, EReference reference, IScope parent) {
+//		val containingDef = EcoreUtil2.getContainerOfType(context, Definition)
+//		if (containingDef === null) {
+//			return parent
+//		}
+//		return Scopes.scopeFor(containingDef.args, parent)
+//	}
+
+}

+ 61 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/validation/SemanticAdaptationValidator.xtend

@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package be.uantwerpen.ansymo.semanticadaptation.validation
+
+import com.google.inject.Inject
+import org.eclipse.xtext.EcoreUtil2
+import be.uantwerpen.ansymo.semanticadaptation.interpreter.Interpreter
+import org.eclipse.xtext.validation.Check
+import org.eclipse.xtext.validation.ValidationMessageAcceptor
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.*
+
+import static be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptationPackage.Literals.*
+
+/**
+ * Custom validation rules. 
+ *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
+ */
+class SemanticAdaptationValidator extends AbstractSemanticAdaptationValidator {
+//	@Inject Interpreter interpreter
+//
+//	@Check
+//	def checkDivByZero(Div div) {
+//		val bigDecimal = interpreter.evaluate(div.right)
+//		if (bigDecimal.doubleValue()==0.0) 
+//			error("Division by zero detected.", DIV__RIGHT)
+//	}
+//	
+//	public static val String NORMALIZABLE = "normalizable-expression"
+//
+//	@Check
+//	def void checkNormalizable(Expression expr) {
+//		// ignore literals
+//		if (expr instanceof NumberLiteral || expr instanceof FunctionCall) 
+//			return;
+//		// ignore evaluations
+//		if (EcoreUtil2.getContainerOfType(expr, Evaluation)!=null)
+//			return;
+//		
+//		val contents = expr.eAllContents
+//		while(contents.hasNext()) {
+//			val next = contents.next()
+//			if (next instanceof FunctionCall) 
+//				return
+//		}
+//		val decimal = interpreter.evaluate(expr)
+//		if (decimal.toString().length()<=8) {
+//			warning(
+//					"Expression could be normalized to constant '"+decimal+"'", 
+//					null,
+//					ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
+//					NORMALIZABLE,
+//					decimal.toString())
+//		}
+//	}
+}

+ 49 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/valueconverter/SemanticAdaptationValueConverters.xtend

@@ -0,0 +1,49 @@
+package be.uantwerpen.ansymo.semanticadaptation.valueconverter
+
+import org.eclipse.xtext.conversion.impl.AbstractDeclarativeValueConverterService
+import org.eclipse.xtext.conversion.ValueConverter
+import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter
+import org.eclipse.xtext.nodemodel.INode
+
+class SemanticAdaptationValueConverters extends AbstractDeclarativeValueConverterService {
+	@ValueConverter(rule = "PREV")
+	def PREV() {
+		return new AbstractLexerBasedConverter<Integer> {    
+		    override toValue(String string, INode node) {
+				return -1
+		    }
+		};
+	}
+	
+	@ValueConverter(rule = "NOW")
+	def NOW() {
+		return new AbstractLexerBasedConverter<Integer> {    
+		    override toValue(String string, INode node) {
+				return 0
+		    }
+		};
+	}
+	
+	@ValueConverter(rule = "REALTYPE")
+	def REALTYPE() {
+		return new AbstractLexerBasedConverter<Float> {    
+		    override toValue(String string, INode node) {
+				return Float.valueOf(string)
+		    }
+		};
+	}
+	
+	/*@ValueConverter(rule = "AtomicUnity")
+	def AtomicUnity() {
+		return new AbstractLexerBasedConverter<Integer> {    
+		    override toValue(String string, INode node) {
+		    	println(string)
+				if (string.equals("0")) {
+					return 1
+				} else {
+					return Integer.valueOf(string)
+				}
+		    }
+		};
+	}*/
+}