Browse Source

Merge remote-tracking branch 'origin/development' into development

# Conflicts:
#	DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical/META-INF/MANIFEST.MF
Kenneth Lausdahl 6 years ago
parent
commit
706e98f562
58 changed files with 1723 additions and 312 deletions
  1. 27 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/META-INF/MANIFEST.MF
  2. 5 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/build.properties
  3. 17 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/canonical_generation/sample1.sa
  4. 34 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/canonical_generation/sample2.sa
  5. 71 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/controller.sa
  6. 128 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/controller_sa_allInOne.sa
  7. 80 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/controller_sa_commented.sa
  8. 67 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/lazy.sa
  9. 108 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/lazy_sa_commented.sa
  10. 45 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/loop.sa
  11. 74 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/loop_canonical.sa
  12. 12 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/power.BASE.sa
  13. 36 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/rate.sa
  14. 108 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_obstacle_sa_flat.BASE.sa
  15. 17 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa.BASE.sa
  16. 56 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_canonical.BASE.sa
  17. 67 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_canonical_commented.BASE.sa
  18. 56 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_canonical_types.BASE.sa
  19. 79 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_commented.BASE.sa
  20. 17 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_comp_units.sa
  21. 68 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/pom.xml
  22. 15 4
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationGeneratorTest.xtend
  23. 3 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical/META-INF/MANIFEST.MF
  24. 1 4
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical/pom.xml
  25. 13 24
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationCanonicalGenerator.xtend
  26. 1 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/graph/DirectedGraph.java
  27. 1 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/graph/FMUGraph.java
  28. 1 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/graph/TopologicalSort.java
  29. 13 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/META-INF/MANIFEST.MF
  30. 16 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/build.properties
  31. 13 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/plugin.xml
  32. 35 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/pom.xml
  33. 30 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/src/be/uantwerpen/ansymo/semanticadaptation/cg/chain/SemanticAdaptationChainGenerator.xtend
  34. 1 2
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppAutoTest.xtend
  35. 7 8
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest.xtend
  36. 2 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/META-INF/MANIFEST.MF
  37. 8 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/pom.xml
  38. 3 8
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/BuildUtilities.java
  39. 33 9
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/CppGenerator.xtend
  40. 16 12
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ModelDescription.xtend
  41. 11 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.log/META-INF/MANIFEST.MF
  42. 20 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.log/build.properties
  43. 5 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.log/plugin.xml
  44. 34 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.log/pom.xml
  45. 63 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.log/src/be/uantwerpen/ansymo/semanticadaptation/log/Log.xtend
  46. 0 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/pom.xml
  47. 0 57
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/AbstractSemanticAdaptationGeneratorTest.xtend
  48. 12 10
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/META-INF/MANIFEST.MF
  49. 1 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/plugin.xml
  50. 102 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/schema/generator_extension.exsd
  51. 3 3
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/SemanticAdaptationRuntimeModule.xtend
  52. 1 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/formatting2/SemanticAdaptationFormatter.xtend
  53. 0 48
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/Log.xtend
  54. 14 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationCustomGenerator.java
  55. 69 5
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationGenerator.xtend
  56. 0 110
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationPythonGenerator.xtend
  57. 1 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/scoping/SemanticAdaptationScopeProvider.xtend
  58. 3 0
      DSL_SemanticAdaptation/pom.xml

+ 27 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/META-INF/MANIFEST.MF

@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests
+Bundle-Vendor: My Company
+Bundle-Version: 1.0.0.qualifier
+Bundle-SymbolicName: be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests; singleton:=true
+Bundle-ActivationPolicy: lazy
+Require-Bundle: 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,
+ org.eclipse.xtext.testing,
+ org.eclipse.xtext.xbase.testing,
+ be.uantwerpen.ansymo.semanticadaptation.cg.canonical;bundle-version="1.0.0",
+ be.uantwerpen.ansymo.semanticadaptation;bundle-version="1.0.0",
+ be.uantwerpen.ansymo.semanticadaptation.tests;bundle-version="1.0.0",
+ be.uantwerpen.ansymo.semanticadaptation.testframework;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests;x-internal=true
+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.cg.canonical.tests/build.properties

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

+ 17 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/canonical_generation/sample1.sa

@@ -0,0 +1,17 @@
+semantic adaptation reactive mealy OuterFMU outerFMU
+at "./path/to/FMU.fmu"
+
+	for inner fmu InnerFMU innerFMU1
+		at "./path/to/InnerFMU.fmu"
+		with input ports innerFMU1__input_port1(rad), Bool innerFMU1__input_port2, innerFMU1__input_port3 (N.m)
+		with output ports Real innerFMU1__outout_port1, Integer innerFMU1__output_port2
+
+	for inner fmu InnerFMU innerFMU2
+		at "./path/to/InnerFMU.fmu"
+		with input ports innerFMU2__input_port1(rad), Bool innerFMU2__input_port2, innerFMU2__input_port3 (N.m)
+		with output ports innerFMU2__outout_port1, String innerFMU2__output_port2
+	
+	coupled as innerFMU2.innerFMU2__outout_port1 -> innerFMU1.innerFMU1__input_port1
+	
+	input ports Real ext_input_port3 -> innerFMU1.innerFMU1__input_port3
+	output ports ext_output_port2 <- innerFMU1.innerFMU1__output_port2

+ 34 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/canonical_generation/sample2.sa

@@ -0,0 +1,34 @@
+semantic adaptation reactive mealy OuterFMU outerFMU
+at "./path/to/FMU.fmu"
+
+	for inner fmu reactive moore NA n1
+		at "./path/to/NA.fmu"
+		with input ports Real ip(m)
+		with output ports Real op(m)
+	
+	for inner fmu reactive mealy NA n2
+		at "./path/to/NA.fmu"
+		with input ports Real ip(m)
+		with output ports Real op(m)
+	
+	for inner fmu reactive mealy NA n3
+		at "./path/to/NA.fmu"
+		with input ports Real ip(m)
+		with output ports Real op(m)
+	
+	for inner fmu reactive mealy NA n4
+		at "./path/to/NA.fmu"
+		with input ports Real ip(m)
+		with output ports Real op(m)
+	
+	for inner fmu reactive mealy NB n5
+		at "./path/to/NB.fmu"
+		with input ports Real ip1(m), Real ip2(m)
+		with output ports Real op(m)
+	
+	coupled as n1.op -> n2.op, 
+				n2.op -> n3.ip, n2.op -> n4.ip,
+				n3.op -> n5.ip1,
+				n4.op -> n5.ip2,
+				n5.op -> n1.ip
+	

+ 71 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/controller.sa

@@ -0,0 +1,71 @@
+semantic adaptation reactive moore ControllerSA controller_sa
+at "./path/to/ControllerSA.fmu"
+
+	for inner fmu LazySA lazy
+	at "./path/to/LazySA.fmu"
+	with input ports obj_detected, passenger_up, passenger_down, passenger_stop, driver_up, driver_down, driver_stop
+	with output ports up, down, stop
+
+input ports armature_current -> lazy.obj_detected, 
+			passenger_up -> lazy.passenger_up, 
+			passenger_down -> lazy.passenger_down,
+			passenger_stop -> lazy.passenger_stop,
+			driver_up -> lazy.driver_up, 
+			driver_down -> lazy.driver_down,
+			driver_stop -> lazy.driver_stop
+
+output ports	u,
+				d
+
+param	RTOL := 0.0001,
+		ATOL := 1e-8,
+		T := 5.0,
+		INIT_V := 0.0;
+
+control var	c := false,
+			p_v := INIT_V;
+control rules {
+	var step_size := H;
+	var aux_obj_detected := false;
+	var crossedTooFar := false;
+	if ((not is_close(p_v, T, RTOL, ATOL) and p_v < T)
+				and (not is_close(f_v, T, RTOL, ATOL) and f_v > T)) {
+		crossedTooFar := true;
+		var negative_value := p_v - T;
+		var positive_value := f_v - T;
+		step_size := (H * (- negative_value)) / (positive_value - negative_value);
+	} else {
+		if ((not is_close(p_v, T, RTOL, ATOL) and p_v < T)
+					and is_close(f_v, T, RTOL, ATOL )) { 
+			c := true;
+		}
+	}
+	
+	if (not crossedTooFar){
+		step_size := do_step(lazy, t, H);
+	}
+	
+	if (is_close(step_size, H, RTOL, ATOL)) {
+		p_v := f_v;
+	}
+	return step_size;
+}
+
+in var	f_v := INIT_V;
+in rules {
+	true -> {
+		f_v := controller_sa.armature_current;
+	} --> {
+		lazy.obj_detected := c;
+	};
+}
+
+out rules {
+	lazy.up -> { } --> {controller_sa.u := 1.0; };
+	not lazy.up -> { } --> {controller_sa.u := 0.0; };
+	
+	lazy.down -> { } --> {controller_sa.d := 1.0; };
+	not lazy.down -> { } --> {controller_sa.d := 0.0; };
+	
+	lazy.stop -> { } --> {controller_sa.u := 0.0 ; controller_sa.d := 0.0; };
+}

+ 128 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/controller_sa_allInOne.sa

@@ -0,0 +1,128 @@
+module Controller_SA
+
+/*
+ * This file is not used in the case study.
+ * The adaptations it does have been split.
+ */
+
+semantic adaptation reactive moore ControllerSA controller_sa
+at "./path/to/ControllerSA.fmu"
+
+	for inner fmu Controller controller
+	at "./path/to/Controller.fmu"
+	with input ports obj_detected, passenger_up, passenger_down, passenger_stop, driver_up, driver_down, driver_stop
+	with output ports up, down, stop
+
+/*
+At some point in the future, we support for simple wildcars in the input ports.
+According to Casper and Kenneth, some FMUs have thousands of ports...
+*/
+input ports armature_current -> controller.obj_detected, 
+			passenger_up -> controller.passenger_up, // You could write passenger_* here.
+			passenger_down -> controller.passenger_down,
+			passenger_stop -> controller.passenger_stop,
+			driver_up -> controller.driver_up, // You could write driver_* here.
+			driver_down -> controller.driver_down,
+			driver_stop -> controller.driver_stop
+
+output ports	u,
+				d
+
+param	REL_TOL := 0.0001,
+		ABS_TOL := 1e-8,
+		CROSSING := 5.0,
+		INIT_ARMATURE_CURRENT := 0.0,
+		INIT_U := 0.0,
+		INIT_D := 0.0;
+
+control var	aux_obj_detected := 0,
+			get_next_step := true,
+			previous_arm_current := INIT_ARMATURE_CURRENT;
+control rules {
+	var step_size := H;
+	aux_obj_detected := false;
+	if ((not is_close(previous_arm_current, CROSSING, REL_TOL, ABS_TOL) and previous_arm_current < CROSSING)
+				and (not is_close(future_arm_current, CROSSING, REL_TOL, ABS_TOL) and future_arm_current > CROSSING)) { // crossing, but not within tolerance
+		var negative_value := previous_arm_current - CROSSING;
+		var positive_value := future_arm_current - CROSSING;
+		step_size := (H * (- negative_value)) / (positive_value - negative_value);
+	} else {
+		if ((not is_close(previous_arm_current, CROSSING, REL_TOL, ABS_TOL) and previous_arm_current < CROSSING)
+					and is_close(future_arm_current, CROSSING, REL_TOL, ABS_TOL )) { // crossing within tolerance found
+			aux_obj_detected := true;
+		}
+	}
+	
+	if (aux_obj_detected == true or t >= next_time_step) {
+		var aux_h := do_step(controller, t-e, e); // do a step, then decide next internal transition
+		//assert aux_h == e; this must always be the case, otherwise it is better not to use the timed transition adaptation.
+		get_next_step := true; // next time the setValues is called, the internal transition will be set again.
+	} else {
+		get_next_step := false;
+	}
+	if (is_close(step_size, H, REL_TOL, ABS_TOL)) {
+		// Step accepted, so store the known input.
+		// We cannot store the armature current at the in rules because we may not accept the step and because they may be called multiple times. 
+		// If that happens, we want to still have the old value of armature current, to compare it with the new one.
+		previous_arm_current := future_arm_current;
+	}
+	return step_size;
+}
+
+in var	next_time_step := -1.0,
+		future_arm_current := INIT_ARMATURE_CURRENT;
+in rules {
+	get_next_step -> {
+		next_time_step := get_next_time_step(controller) + last_execution_time(controller); 
+		/*
+		The get_next_time_step(controller) function is equivalent to the following snippet:
+		save_state(controller);
+		internal_transition := do_step(controller, last_execution_time(controller), MAX);
+		next_time_step := last_execution_time(controller) + internal_transition;
+		rollback(controller);
+		*/
+	} --> { };
+	
+	true -> {
+		future_arm_current := armature_current;
+	} --> {
+		obj_detected := aux_obj_detected; // Sets this input to the FMU 
+	};
+}
+
+out var stored_up := INIT_U,
+		stored_down := INIT_D;
+out rules {
+	true -> {
+		/*
+		Previously, there was this intruction here:
+		internal_transition := get_next_time_step(controller) + t
+		
+		However, it cannot be here, since there is no guarantee in the control rules block, that the doStep of the controller will be called.
+		*/
+	} --> {};
+	
+	/*
+	What does "otherwise var" mean?
+	Suppose I have the following rules:
+		var1 == true and var2 == false -> ...
+		otherwise var1 -> ...
+	
+	controller.up == true -> { stored_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; } --> { }; 
+	*/
+	controller.up -> {stored_up := 1; } --> {u := stored_up; };
+	not controller.up -> {stored_up := 0; } --> {u := stored_up; };
+	
+	controller.down -> {stored_down := 1; } --> {d := stored_down; };
+	not controller.down -> {stored_down := 0; } --> {d := stored_down; };
+	
+	controller.stop -> {stored_down := 0; stored_up :=0; } --> {u := stored_up ; d := stored_down; };
+	
+}

+ 80 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/controller_sa_commented.sa

@@ -0,0 +1,80 @@
+module Controller_SA
+
+semantic adaptation reactive moore ControllerSA controller_sa
+at "./path/to/ControllerSA.fmu"
+
+	for inner fmu LazySA lazy
+	at "./path/to/LazySA.fmu"
+	with input ports obj_detected, passenger_up, passenger_down, passenger_stop, driver_up, driver_down, driver_stop
+	with output ports up, down, stop
+
+/*
+At some point in the future, we support for simple wildcars in the input ports.
+According to Casper and Kenneth, some FMUs have thousands of ports...
+*/
+input ports armature_current -> lazy.obj_detected, 
+			passenger_up -> lazy.passenger_up, // You could write passenger_* here.
+			passenger_down -> lazy.passenger_down,
+			passenger_stop -> lazy.passenger_stop,
+			driver_up -> lazy.driver_up, // You could write driver_* here.
+			driver_down -> lazy.driver_down,
+			driver_stop -> lazy.driver_stop
+
+output ports	u,
+				d
+
+param	REL_TOL := 0.0001,
+		ABS_TOL := 1e-8,
+		CROSSING := 5.0,
+		INIT_ARMATURE_CURRENT := 0.0;
+
+control var	aux_obj_detected := 0,
+			previous_arm_current := INIT_ARMATURE_CURRENT;
+control rules {
+	var step_size := H;
+	var aux_obj_detected := false;
+	var crossedTooFar := false;
+	if ((not is_close(previous_arm_current, CROSSING, REL_TOL, ABS_TOL) and previous_arm_current < CROSSING)
+				and (not is_close(future_arm_current, CROSSING, REL_TOL, ABS_TOL) and future_arm_current > CROSSING)) { // crossing, but not within tolerance
+		crossedTooFar := true;
+		var negative_value := previous_arm_current - CROSSING;
+		var positive_value := future_arm_current - CROSSING;
+		step_size := (H * (- negative_value)) / (positive_value - negative_value);
+	} else {
+		if ((not is_close(previous_arm_current, CROSSING, REL_TOL, ABS_TOL) and previous_arm_current < CROSSING)
+					and is_close(future_arm_current, CROSSING, REL_TOL, ABS_TOL )) { // crossing within tolerance found
+			aux_obj_detected := true;
+		}
+	}
+	
+	if (not crossedTooFar){
+		step_size := do_step(lazy, t, H);
+	}
+	
+	if (is_close(step_size, H, REL_TOL, ABS_TOL)) {
+		// Step accepted, so store the known input.
+		// We cannot store the armature current at the in rules because we may not accept the step and because they may be called multiple times. 
+		// If that happens, we want to still have the old value of armature current, to compare it with the new one.
+		previous_arm_current := future_arm_current;
+	}
+	return step_size;
+}
+
+in var	future_arm_current := INIT_ARMATURE_CURRENT;
+in rules {
+	true -> {
+		future_arm_current := armature_current;
+	} --> {
+		obj_detected := aux_obj_detected; // Sets this input to the FMU 
+	};
+}
+
+out rules {
+	lazy.up -> { } --> {u := 1.0; };
+	not lazy.up -> { } --> {u := 0.0; };
+	
+	lazy.down -> { } --> {d := 1.0; };
+	not lazy.down -> { } --> {d := 0.0; };
+	
+	lazy.stop -> { } --> {u := 0.0 ; d := 0.0; };
+}

+ 67 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/lazy.sa

@@ -0,0 +1,67 @@
+semantic adaptation reactive moore LazySA lazy_sa
+at "./path/to/LazySA.fmu"
+
+	for inner fmu Controller controller
+	at "./path/to/Controller.fmu"
+	with input ports Bool obj_detected, Bool passenger_up, Bool passenger_down, Bool passenger_stop, Bool driver_up, Bool driver_down, Bool driver_stop
+	with output ports Bool up, Bool down, Bool stop
+
+input ports obj_detected -> controller.obj_detected,
+			passenger_up -> controller.passenger_up,
+			passenger_down -> controller.passenger_down,
+			passenger_stop -> controller.passenger_stop,
+			driver_up -> controller.driver_up,
+			driver_down -> controller.driver_down,
+			driver_stop -> controller.driver_stop
+
+param 	INIT_OBJ_DETECTED := false,
+		INIT_PASSENGER_UP := false,
+		INIT_PASSENGER_DOWN := false,
+		INIT_PASSENGER_STOP := false,
+		INIT_DRIVER_UP := false,
+		INIT_DRIVER_DOWN := false,
+		INIT_DRIVER_STOP := false;
+
+control var	tn := -1.0,
+			tl := -1.0,
+			prev_obj_detected := INIT_OBJ_DETECTED,
+			prev_passenger_up := INIT_PASSENGER_UP,
+			prev_passenger_down := INIT_PASSENGER_DOWN,
+			prev_passenger_stop := INIT_PASSENGER_STOP,
+			prev_driver_up := INIT_DRIVER_UP,
+			prev_driver_down := INIT_DRIVER_DOWN,
+			prev_driver_stop := INIT_DRIVER_STOP;
+
+control rules {
+	if (tl < 0.0){
+		tl := t;
+	}
+	
+	var step_size := min(H, tn - t); 
+	if (lazy_sa.obj_detected != prev_obj_detected or
+		lazy_sa.passenger_up != prev_passenger_up or
+		lazy_sa.passenger_down != prev_passenger_down or
+		lazy_sa.passenger_stop != prev_passenger_stop or
+		lazy_sa.driver_up != prev_driver_up or
+		lazy_sa.driver_down != prev_driver_down or
+		lazy_sa.driver_stop != prev_driver_stop or
+		(t+H) >= tn
+	){
+		var Real step_to_be_done := (t+H-tl);
+		var step_done := do_step(controller, t, step_to_be_done); 
+		tn := tl + step_done + get_next_time_step(controller); 
+		step_size := tl + step_done - t; 
+		tl := tl + step_done; 
+	}
+	
+	prev_obj_detected := lazy_sa.obj_detected;
+	prev_passenger_up := lazy_sa.passenger_up;
+	prev_passenger_down := lazy_sa.passenger_down;
+	prev_passenger_stop := lazy_sa.passenger_stop;
+	prev_driver_up := lazy_sa.driver_up;
+	prev_driver_down := lazy_sa.driver_down;
+	prev_driver_stop := lazy_sa.driver_stop;
+	
+	return step_size;
+}
+

+ 108 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/lazy_sa_commented.sa

@@ -0,0 +1,108 @@
+module Lazy_SA
+
+/*
+ * The purpose of this adaptation is to only run the internal FMU 
+ * 	when any of its inputs changes, or when it requests to be explicitly run.
+ */
+
+semantic adaptation reactive moore LazySA lazy_sa
+at "./path/to/LazySA.fmu"
+
+	for inner fmu Controller controller
+	at "./path/to/Controller.fmu"
+	with input ports obj_detected, passenger_up, passenger_down, passenger_stop, driver_up, driver_down, driver_stop
+	with output ports up, down, stop
+
+/*
+ * In addition, we do not need to do anything about the outputs of the inner FMU, because they are zero order holded by default.
+ */
+input ports obj_detected -> controller.obj_detected,
+			passenger_up -> controller.passenger_up,
+			passenger_down -> controller.passenger_down,
+			passenger_stop -> controller.passenger_stop,
+			driver_up -> controller.driver_up,
+			driver_down -> controller.driver_down,
+			driver_stop -> controller.driver_stop
+
+output ports up, down, stop
+
+param 	INIT_OBJ_DETECTED := false,
+		INIT_PASSENGER_UP := false,
+		INIT_PASSENGER_DOWN := false,
+		INIT_PASSENGER_STOP := false,
+		INIT_DRIVER_UP := false,
+		INIT_DRIVER_DOWN := false,
+		INIT_DRIVER_STOP := false;
+
+control var	tn := -1.0,
+			tl := -1.0,
+			prev_obj_detected := INIT_OBJ_DETECTED,
+			prev_passenger_up := INIT_PASSENGER_UP,
+			prev_passenger_down := INIT_PASSENGER_DOWN,
+			prev_passenger_stop := INIT_PASSENGER_STOP,
+			prev_driver_up := INIT_DRIVER_UP,
+			prev_driver_down := INIT_DRIVER_DOWN,
+			prev_driver_stop := INIT_DRIVER_STOP;
+
+control rules {
+	// This initialisation covers simulations that start at a non-zero time.
+	if (tl < 0.0){
+		tl := t;
+	}
+	
+	var step_size := min(H, tn - t); // In case tn < t, this ensures that the controller will be run at the right time.
+	// Note that the expression lazy_sa.obj_detected gets replaced by the corresponding storage var in the canonical version.
+	if (lazy_sa.obj_detected != prev_obj_detected or
+		lazy_sa.passenger_up != prev_passenger_up or
+		lazy_sa.passenger_down != prev_passenger_down or
+		lazy_sa.passenger_stop != prev_passenger_stop or
+		lazy_sa.driver_up != prev_driver_up or
+		lazy_sa.driver_down != prev_driver_down or
+		lazy_sa.driver_stop != prev_driver_stop or
+		(t+H) >= tn
+	){
+		var step_to_be_done := (t+H-tl);
+		var step_done := do_step(controller, t, step_to_be_done); // calls the mapIn function that will take care of forwarding the values of the input ports to the internal FMU.
+		// We calculate these as if step_done == step_to_be_done. If that is not the case, a rollback will be done anyway.
+		tn := tl + step_done + get_next_time_step(controller); // calculates the next time step that is tolerated by the controller.
+		/*
+			The get_next_time_step(controller) function is equivalent to the following snippet:
+			save_state(controller);
+			internal_transition := do_step(controller, last_execution_time(controller), MAX);
+			next_time_step := last_execution_time(controller) + internal_transition;
+			rollback(controller);
+		 */
+		// This is the actual step size taken, from the outside world:
+		step_size := tl + step_done - t; // assert step_size <= H
+		tl := tl + step_done; // assert tl == t+H
+	}
+	
+	// Store the previous values of the inputs
+	prev_obj_detected := lazy_sa.obj_detected;
+	prev_passenger_up := lazy_sa.passenger_up;
+	prev_passenger_down := lazy_sa.passenger_down;
+	prev_passenger_stop := lazy_sa.passenger_stop;
+	prev_driver_up := lazy_sa.driver_up;
+	prev_driver_down := lazy_sa.driver_down;
+	prev_driver_stop := lazy_sa.driver_stop;
+	
+	return step_size;
+}
+
+/*
+The following code is not needed because the outputs are zero order hold'ed by default:
+out var	stored_up := INIT_UP,
+		stored_down := INIT_DOWN,
+		stored_stop := INIT_STOP;
+out rules{
+	 true -> {
+		stored_up := controller.up;
+		stored_down := controller.down;
+		stored_stop := controller.stop;
+	} --> {
+		lazy_sa.up := stored_up;
+		lazy_sa.down := stored_down;
+		lazy_sa.stop := stored_stop;
+	};
+}
+ */

+ 45 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/loop.sa

@@ -0,0 +1,45 @@
+semantic adaptation reactive moore LoopSA loop_sa
+at "./path/to/LoopSA.fmu"
+
+	for inner fmu WindowSA window_sa
+		at "./path/to/WindowSA.fmu"
+		with input ports displacement (rad), speed (rad/s), reaction_force (N)
+		with output ports disp (m), tau (N.m)
+	
+	for inner fmu Obstacle obstacle
+		at "./path/to/Obstacle.fmu"
+		with input ports disp (m)
+		with output ports reaction_force (m)
+	
+	coupled as	window_sa.disp -> obstacle.disp,
+				obstacle.reaction_force -> window_sa.reaction_force
+
+output ports tau <- window_sa.tau
+
+param 	MAXITER := 10, 
+		REL_TOL := 1e-05, 
+		ABS_TOL := 1e-05;
+
+control var prev_disp := 0.0;
+control rules {
+	var repeat := false;
+	for (var iter in 0 .. MAXITER) {
+		save_state(obstacle);
+		save_state(window_sa);
+		obstacle.disp := prev_disp;
+		do_step(obstacle,t,H);
+		do_step(window_sa,t,H);
+		
+		repeat := is_close(prev_disp, window_sa.disp, REL_TOL, ABS_TOL);
+		prev_disp := window_sa.disp;
+		if (repeat) {
+			break;
+		} else {
+			rollback(obstacle);
+			rollback(window_sa);
+		}
+	}
+	return H;
+}
+
+

+ 74 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/loop_canonical.sa

@@ -0,0 +1,74 @@
+semantic adaptation reactive moore LoopSA loop_sa
+at "./path/to/LoopSA.fmu"
+	
+	for inner fmu WindowSA window_sa
+		at "./path/to/WindowSA.fmu"
+		with input ports displacement (rad), speed (rad/s), reaction_force (N)
+		with output ports disp (m), tau (N.m)
+	
+	for inner fmu Obstacle obstacle
+		at "./path/to/Obstacle.fmu"
+		with input ports disp (m)
+		with output ports reaction_force (m)
+	
+	coupled as window_sa.disp -> obstacle.disp, 
+				obstacle.reaction_force -> window_sa.reaction_force
+
+input ports displacement, speed
+
+output ports tau
+
+param 	MAXITER := 10, REL_TOL := 1e-05, ABS_TOL := 1e-05,
+		INIT_LOOP_SA_DISPLACEMENT := 0.0,
+		INIT_LOOP_SA_SPEED := 0.0,
+		INIT_WINDOW_SA_DISP := 0.0,
+		INIT_WINDOW_SA_TAU := 0.0,
+		INIT_OBSTACLE_REACTION_FORCE := 0.0;
+
+control var prev_disp := 0.0;
+control rules {
+	var repeat := false;
+	for (var iter in 0 .. MAXITER) {
+		save_state(obstacle);
+		save_state(window_sa);
+		obstacle.disp := prev_disp;
+		do_step(obstacle,t,H);
+		window_sa.reaction_force := stored_obstacle_reaction_force;
+		do_step(window_sa,t,H);
+		
+		repeat := is_close(prev_disp, stored_window_sa_disp, REL_TOL, ABS_TOL);
+		prev_disp := stored_window_sa_disp;
+		if (repeat) {
+			break;
+		} else {
+			rollback(obstacle);
+			rollback(window_sa);
+		}
+	}
+	return H;
+}
+
+in var 	stored_loop_sa_displacement := INIT_LOOP_SA_DISPLACEMENT,
+		stored_loop_sa_speed := INIT_LOOP_SA_SPEED;
+in rules {
+	true -> {
+		stored_loop_sa_displacement := loop_sa.displacement;
+		stored_loop_sa_speed := loop_sa.speed;
+	} --> {
+		window_sa.displacement := stored_loop_sa_displacement;
+		window_sa.speed := stored_loop_sa_speed;
+	};
+}
+
+out var	stored_window_sa_disp := INIT_WINDOW_SA_DISP,
+		stored_window_sa_tau := INIT_WINDOW_SA_TAU,
+		stored_obstacle_reaction_force := INIT_OBSTACLE_REACTION_FORCE;
+out rules{
+	true -> {
+		stored_window_sa_disp := window_sa.disp;
+		stored_window_sa_tau := window_sa.tau;
+		stored_obstacle_reaction_force := obstacle.tau;
+	} --> {
+		loop_sa.tau := stored_window_sa_tau;
+	};
+}

+ 12 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/power.BASE.sa

@@ -0,0 +1,12 @@
+semantic adaptation delayed moore PowerSA power_sa
+at "./path/to/PowerSA.fmu"
+
+	for inner fmu Power power
+	at "./path/to/Power.fmu"
+	with input ports u, d, tau (N.m)
+	with output ports armature_current (A), speed (rad/s), displacement (rad)
+
+output ports armature_current <- power.armature_current, 
+			speed <- power.speed,
+			displacement <- power.displacement
+

+ 36 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/rate.sa

@@ -0,0 +1,36 @@
+semantic adaptation reactive moore RateSA rate_sa
+at "./path/to/RateSA.fmu"
+
+	for inner fmu LoopSA loop_sa
+		at "./path/to/LoopSA.fmu"
+		with input ports displacement (rad), speed (rad/s)
+		with output ports tau (N.m)
+	
+input ports speed
+output ports tau <- loop_sa.tau
+
+param 	RATE := 10;
+
+control var previous_speed := 0;
+control rules {
+	var micro_step := H/RATE;
+	var inner_time := t;
+	
+	for (var iter in 0 .. RATE) { 
+		do_step(loop_sa,inner_time,micro_step);
+		inner_time := inner_time + micro_step;	
+	}
+	
+	previous_speed := current_speed;
+	return H;
+}
+
+in var current_speed := 0;
+in rules {
+	true -> {
+		current_speed := speed;
+	} --> {
+		loop_sa.speed := previous_speed + (current_speed - previous_speed)*(dt + h);
+	};
+}
+

+ 108 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_obstacle_sa_flat.BASE.sa

@@ -0,0 +1,108 @@
+module WindowObstacleLoop_SA
+
+semantic adaptation reactive mealy WindowObstableLoopSA adaptedFMU
+at "./path/to/WindowObstableLoopSA.fmu"
+
+	for inner fmu WindowSA window_sa
+		at "./path/to/WindowSA.fmu"
+		with input ports displacement (rad), speed (rad/s), reaction_force (N)
+		with output ports disp (m), tau (N.m)
+	
+	for inner fmu Obstacle obstacle
+		at "./path/to/Obstacle.fmu"
+		with input ports disp (m)
+		with output ports reaction_force (m)
+	
+	/*
+	This is the information that was missing before: how the semantic adaptation window_sa, which is an FMU, connects to the obstacle FMU.
+	*/
+	coupled as window_sa.disp -> obstacle.disp,	
+				obstacle.reaction_force -> window_sa.reaction_force
+
+/*
+Declares the external ports of the semantic adaptation
+Notice that window_sa.displacement is a dangling input port, so an extra input port will exist in the adapted FMU.
+*/
+input ports speed
+output ports tau 
+
+param 	RATE := 10, 
+		MAXITER := 10, 
+		REL_TOL := 1e-05, 
+		ABS_TOL := 1e-05;
+
+control var previous_speed := 0, future_speed := 0;
+control rules {
+	var inner_dt := H/RATE;
+	/*
+	The two instructions below need to be made, because previously they were made in the sa_in block, but multiple calls to the sa_in block would make them fail.
+	*/
+	previous_speed := future_speed;
+	future_speed := current_speed; // you cannot access input ports of the adapted FMU here.
+	
+	for (var iter in 0 .. RATE) { // multi-rate loop
+		var prev_disp := window_sa.disp;
+		var inner_time := t;
+		for (var iter in 0 .. MAXITER) {
+			save_state(obstacle);
+			save_state(window_sa);
+			do_step(obstacle,inner_time,inner_dt);
+			do_step(window_sa,inner_time,inner_dt);
+			
+			if (is_close(prev_disp, disp, REL_TOL, ABS_TOL)) {
+				break;
+			} else {
+				prev_disp := disp;
+				rollback(obstacle);
+				rollback(window_sa);
+			}
+			
+			/*
+			The above block of statements is equivalent to the following:
+			var obstacle_state := getState(obstacle)
+			var window_sa_state := getState(window_sa)
+			
+			obstacle.set("height", height)
+			obstacle.doStep(inner_time,h)
+			reaction_force := obstacle.get("reaction_force")
+			window_sa.set("reaction_force", reaction_force)
+			window_sa.doStep(inner_time,h)
+			height := window_sa.get("height")
+			if (is_close(prev_height, height, REL_TOL, ABS_TOL)) {
+				// The commits don't do anything, as far as I see. But they serve an analysis which ensures that states are correctly obtained and restored.
+				break;
+			} else {
+				prev_height := height;
+				obstacle.setState(obstacle_state);
+				window_sa.setState(window_sa_state);
+			}
+			*/
+		}
+		inner_time := t + inner_dt;	
+	}
+	return H;
+}
+
+in var current_speed := 0;
+in rules {
+	true -> {
+		/*
+		These instructions would violate the principle that multiple calls to setValues can be made:
+		previous_speed := future_speed;
+		future_speed := speed;
+		Upon execution, this block must call setValues of the original FMUs (window_sa and obstacle).
+		The correct thing then is to execute the next block and then do the setValues of the original FMUs.
+		*/
+		current_speed := speed;
+	} --> {
+		/*
+		This block will be called whenever any of the input ports that are unconnected in the original FMUs is read, in the control rules block.
+		The following variables are available in this block:
+			dt - In the control rules block, (t + dt) is the time that will be passed to the doStep function of the inner FMU. In the control rules block, this can be computed by doing dt := inner_time - t.
+			h - this is the communication step size that will be sent to the inner FMU.
+		
+		*/
+		window_sa.speed := previous_speed + (future_speed - previous_speed)*dt;
+	};
+}
+

+ 17 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa.BASE.sa

@@ -0,0 +1,17 @@
+semantic adaptation reactive mealy WindowSA windowSA
+at "./path/to/WindowSA.fmu"
+
+	for inner fmu Window window
+		at "test_input/single_folder_spec/window/Window.fmu"
+		with input ports displacement(rad), speed (rad/s), reaction_force (N)
+		with output ports height (cm), reaction_torque (N.m)
+
+output ports disp (m)  <- window.height, tau (N)
+
+out rules {
+	true -> {} --> {
+		windowSA.tau := -window.reaction_torque;
+	};
+}
+
+

+ 56 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_canonical.BASE.sa

@@ -0,0 +1,56 @@
+semantic adaptation reactive mealy WindowSA windowSA
+at "./path/to/WindowSA.fmu"
+
+	for inner fmu Window window
+		at "./path/to/Window.fmu"
+		with input ports displacement (rad), speed (rad/s), reaction_force (N)
+		with output ports height (m), reaction_torque (N.m)
+
+input ports 	reaction_force,
+				displacement,
+				speed
+
+output ports	disp,
+				tau
+
+param 	INIT_WINDOWSA_REACTION_FORCE := 0.0,
+		INIT_WINDOWSA_DISPLACEMENT := 0.0,
+		INIT_WINDOWSA_SPEED := 0.0,
+		INIT_WINDOW_REACTION_TORQUE := 0.0,
+		INIT_WINDOW_REACTION_HEIGHT := 0.0;
+
+control rules {
+	var H_window := do_step(window, t, H);
+	return H_window;
+}
+
+in var 	stored_windowsa_reaction_force := INIT_WINDOWSA_REACTION_FORCE, 
+		stored_windowsa_displacement := INIT_WINDOWSA_DISPLACEMENT, 
+		stored_windowsa_speed := INIT_WINDOWSA_SPEED;
+
+in rules {
+	true -> {
+		stored_windowsa_reaction_force := windowSA.reaction_force;
+		stored_windowsa_displacement := windowSA.displacement;			
+		stored_windowsa_speed := windowSA.speed;
+	} --> {
+		window.reaction_force := stored_windowsa_reaction_force;
+		window.displacement := stored_windowsa_displacement; 
+		window.speed := stored_windowsa_speed;
+	};
+}
+
+out var stored_window_reaction_torque := INIT_WINDOW_REACTION_TORQUE,
+		stored_window_height := INIT_WINDOW_REACTION_HEIGHT;
+
+out rules {
+	true -> {
+		stored_window_reaction_torque := window.reaction_torque;
+		stored_window_height := window.height;
+	} --> {
+		windowSA.disp := stored_window_height / 100;
+	};
+	true -> { } --> {
+		windowSA.tau := -stored_window_reaction_torque;
+	};
+}

+ 67 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_canonical_commented.BASE.sa

@@ -0,0 +1,67 @@
+module Window_SA
+
+semantic adaptation reactive mealy WindowSA windowSA
+at "./path/to/WindowSA.fmu"
+
+	for inner fmu Window window
+		at "./path/to/Window.fmu"
+		with input ports displacement (rad), speed (rad/s), reaction_force (N)
+		with output ports height (m), reaction_torque (N.m)
+
+/*
+In the original version, no input ports where declared, so all dangling inputs of the original fmus are bound to the input ports of the adapted FMU.
+In the canonical version, the input and output ports are all declared explicitly, and their bindings are implemented in the in/out rules.
+*/
+
+input ports 	reaction_force,
+				displacement,
+				speed
+
+output ports	disp,
+				tau
+
+
+control rules {
+	do_step(window, t, H); // includes update_in rules and update_out (update-in rules do not update state)
+	return H;
+}
+
+in var 	stored_windowsa_reaction_force := 0.0, 
+		stored_windowsa_displacement := 0.0, 
+		stored_windowsa_speed := 0.0;
+
+in rules {
+	true -> {
+		/*
+		is_set checks whether the input value is given in the setValues call of the adapted FMU.
+		Notice that in the canonical version, all ports are prefixed.
+		*/
+		if (is_set(windowSA.reaction_force)){
+			stored_windowsa_reaction_force := windowSA.reaction_force;
+		}
+		if (is_set(windowSA.displacement)){
+			stored_windowsa_displacement := windowSA.displacement;			
+		}
+		if (is_set(windowSA.speed)){
+			stored_windowsa_speed := windowSA.speed;
+		}
+	} --> {
+		window.reaction_force := stored_windowsa_reaction_force;
+		window.displacement := stored_windowsa_displacement; 
+		window.speed := stored_windowsa_speed;
+	};
+}
+
+out var stored_window_reaction_torque := 0,
+		stored_window_height := 0;
+		
+out rules {
+	true -> {
+		stored_window_reaction_torque := window.reaction_torque;
+		stored_window_height := window.height;
+	} --> {
+		windowSA.tau := - stored_window_reaction_torque;
+		windowSA.disp := stored_window_height / 100;
+	};
+}
+

+ 56 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_canonical_types.BASE.sa

@@ -0,0 +1,56 @@
+semantic adaptation reactive mealy WindowSA windowSA
+at "./path/to/WindowSA.fmu"
+
+	for inner fmu Window window
+		at "./path/to/Window.fmu"
+		with input ports Real displacement (rad), Real speed (rad/s), Real reaction_force (N)
+		with output ports Real height (m), Real reaction_torque (N.m)
+
+input ports 	Real reaction_force,
+				Real displacement,
+				Real speed
+
+output ports	Real disp,
+				Real tau
+
+param 	Real INIT_WINDOWSA_REACTION_FORCE := 0.0,
+		Real INIT_WINDOWSA_DISPLACEMENT := 0.0,
+		Real INIT_WINDOWSA_SPEED := 0.0,
+		Real INIT_WINDOW_REACTION_TORQUE := 0.0,
+		Real INIT_WINDOW_REACTION_HEIGHT := 0.0;
+
+control rules {
+	var Real H_window := do_step(window, t, H);
+	return H_window;
+}
+
+in var 	Real stored_windowsa_reaction_force := INIT_WINDOWSA_REACTION_FORCE, 
+		Real stored_windowsa_displacement := INIT_WINDOWSA_DISPLACEMENT, 
+		Real stored_windowsa_speed := INIT_WINDOWSA_SPEED;
+
+in rules {
+	true -> {
+		stored_windowsa_reaction_force := windowSA.reaction_force;
+		stored_windowsa_displacement := windowSA.displacement;			
+		stored_windowsa_speed := windowSA.speed;
+	} --> {
+		window.reaction_force := stored_windowsa_reaction_force;
+		window.displacement := stored_windowsa_displacement; 
+		window.speed := stored_windowsa_speed;
+	};
+}
+
+out var Real stored_window_reaction_torque := INIT_WINDOW_REACTION_TORQUE,
+		Real stored_window_height := INIT_WINDOW_REACTION_HEIGHT;
+
+out rules {
+	true -> {
+		stored_window_reaction_torque := window.reaction_torque;
+		stored_window_height := window.height;
+	} --> {
+		windowSA.disp := stored_window_height / 100;
+	};
+	true -> { } --> {
+		windowSA.tau := -stored_window_reaction_torque;
+	};
+}

+ 79 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_commented.BASE.sa

@@ -0,0 +1,79 @@
+module Window_SA
+
+semantic adaptation reactive mealy WindowSA windowSA
+at "./path/to/WindowSA.fmu"
+
+/*
+Reactive means that the unit expects the following treatment:
+Supose the external master is at time t, and that there is an FMU f providing inputs to windowsa.
+Then,
+f.doStep(t, H) // f goes from t->t+H 
+u := f.getValues(...)
+windowsa.setValues(u) // Input provided from the future (t+H)
+windowsa.doStep(t, H) // windowsa goes from t->t+H
+v := windowsa.getValues(...)
+
+Delayed unit means that the unit expects the following treatment:
+Supose the external master is at time t, and that there is an FMU f providing inputs to windowsa.
+Then,
+pu := f.getValues(...)
+f.doStep(t, H) // f goes from t->t+H 
+windowsa.setValues(pu) // Input provided at the time t
+windowsa.doStep(t, H) // windowsa goes from t->t+H and does not need input at time (t+H)
+v := windowsa.getValues(...)
+
+
+Mealy unit means the following:
+windowsa.setValues(v1)  // values set at time t
+o1 = windowsa.getValues() // values set at time t
+assert v2 <> v1 // Assumption
+windowsa.setValues(v2)  // values set at time t
+o2 = windowsa.getValues() // values set at time t
+It is probably the case that o1 <> o2
+
+Moore unit means the following:
+windowsa.setValues(v1)  // values set at time t
+o1 = windowsa.getValues() // values set at time t
+assert v2 <> v1 // Assumption
+windowsa.setValues(v2)  // values set at time t
+o2 = windowsa.getValues() // values set at time t
+It must be the case that o1 == o2
+In other words, the output at time t, only depends on the state at time t.
+*/
+
+	
+	/*
+	The definition for the wrapped FMU is now done here.
+	This is because, for adaptations that wrap multiple FMUs as well as other adaptations, the connection information cannot be fully completed in the senario description (see the window_obstacle.sa example).
+	*/
+	for inner fmu Window window
+		at "./path/to/WindowSA.fmu"
+		with input ports displacement (rad), speed (rad/s), reaction_force (N)
+		with output ports height (cm), reaction_torque (N.m)
+
+/*
+No need to have input ports declared for this model.
+Every input port of the original FMU will be automatically assumed to be an input port of the adapted FMU.
+
+If there is an input port window.p which is dangling, but is not declared here, then an input port windowsa.p will be created in the adapted FMU, and we will have that window.p -> windowsa.p.
+*/
+
+/*
+Declares two output ports, and specified how height is mapped to disp.
+Here, the units need to be specified, so that the conversion can take place.
+The units of disp can be either obtained from the scenario, or specified explicitly here.
+*/
+output ports disp (m)  <- height, tau
+/*
+There are alternative ways that this can be interpreted:
+disp  := arbitrary_function(height) * 100 or arbitrary_function(height * 100) (they are not necessarily equal)
+We pick the first one, so what we have is this:
+aux_var := arbitrary_function(height);
+disp := aux_var*100; // This part never has to be coded.
+*/
+
+out rules {
+	true -> {} --> {
+		tau := -reaction_force;
+	};
+}

+ 17 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/input/power_window_case_study/window_sa_comp_units.sa

@@ -0,0 +1,17 @@
+semantic adaptation reactive mealy WindowSA windowSA
+at "./path/to/WindowSA.fmu"
+
+	for inner fmu Window window
+		at "./path/to/Window.fmu"
+		with input ports displacement(rad), speed (rad/s), reaction_force (N)
+		with output ports height (cm), reaction_torque (N.m)
+
+output ports disp  <- window.height, tau (N)
+
+out rules {
+	true -> {} --> {
+		windowSA.tau := -window.reaction_force;
+	};
+}
+
+

+ 68 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests/pom.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<relativePath>../pom.xml</relativePath>
+		<groupId>be.uantwerpen.ansymo.semanticadaptation</groupId>
+		<artifactId>parent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests</artifactId>
+	<packaging>eclipse-test-plugin</packaging>
+
+	<name>be.uantwerpen.ansymo.semanticadaptation Code Generation to C++ Tests</name>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-clean-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>gen-clean</id>
+						<phase>clean</phase>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.eclipse.xtend</groupId>
+				<artifactId>xtend-maven-plugin</artifactId>
+			</plugin>
+
+
+			<plugin>
+				<!-- Remember that these tests only run in integration so between package 
+					and install http://www.vogella.com/tutorials/EclipseTycho/article.html -->
+				<groupId>org.eclipse.tycho</groupId>
+				<artifactId>tycho-surefire-plugin</artifactId>
+				<version>${tycho.version}</version>
+				<configuration>
+					<useUIHarness>false</useUIHarness>
+					<useUIThread>false</useUIThread>
+				</configuration>
+			</plugin>
+
+			<!-- plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> 
+				<executions> <execution> <id>copy</id> <phase>pre-integration-test</phase> 
+				<goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> 
+				<groupId>be.uantwerpen.ansymo.semanticadaptation</groupId> <artifactId>be.uantwerpen.ansymo.semanticadaptation.cg.cpp.lib</artifactId> 
+				<type>jar</type> <version>${project.version}</version> <overWrite>true</overWrite> 
+				<destFileName>cppFramework.jar</destFileName> </artifactItem> </artifactItems> 
+				<outputDirectory>${project.basedir}/jars</outputDirectory> <overWriteReleases>false</overWriteReleases> 
+				<overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> 
+				</configuration> </execution> </executions> </plugin -->
+
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-surefire-plugin</artifactId>
+					<configuration>
+						<!-- the tests use std out a lot so we dont want that in the console -->
+						<redirectTestOutputToFile>true</redirectTestOutputToFile>
+
+					</configuration>
+				</plugin>
+		</plugins>
+	</build>
+</project>

+ 15 - 4
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationGeneratorTest.xtend

@@ -1,8 +1,9 @@
 /*
  * generated by Xtext 2.10.0
  */
-package be.uantwerpen.ansymo.semanticadaptation.tests
+package be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests
 
+import be.uantwerpen.ansymo.semanticadaptation.cg.canonical.SemanticAdaptationCanonicalGenerator
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Assignment
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.AtomicUnity
@@ -17,9 +18,14 @@ import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SingleVarDeclaration
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
+import be.uantwerpen.ansymo.semanticadaptation.tests.AbstractSemanticAdaptationTest
+import be.uantwerpen.ansymo.semanticadaptation.tests.SemanticAdaptationInjectorProvider
 import com.google.inject.Inject
+import org.eclipse.emf.common.util.URI
+import org.eclipse.xtext.generator.InMemoryFileSystemAccess
 import org.eclipse.xtext.testing.InjectWith
 import org.eclipse.xtext.testing.XtextRunner
+import org.eclipse.xtext.testing.util.ParseHelper
 import org.eclipse.xtext.util.IAcceptor
 import org.eclipse.xtext.xbase.testing.CompilationTestHelper
 import org.eclipse.xtext.xbase.testing.CompilationTestHelper.Result
@@ -31,9 +37,10 @@ import org.junit.runner.RunWith
 @InjectWith(SemanticAdaptationInjectorProvider)
 class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 	
-	@Inject extension CompilationTestHelper
+	@Inject extension ParseHelper<SemanticAdaptation>
 	
-	@Test def test_inferTypesAndUnits_sample1() { __generate('input/canonical_generation/sample1.sa', new IAcceptor<CompilationTestHelper.Result>(){
+	@Test def test_inferTypesAndUnits_sample1() { 
+		__generate('input/canonical_generation/sample1.sa', new IAcceptor<CompilationTestHelper.Result>(){
 			override accept(Result t) {
 				var Adaptation sa = t.resourceSet.resources.head.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation).head
 				Assert.assertTrue(sa.name == "outerFMU")
@@ -220,7 +227,11 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 	def void __generate(String filename, IAcceptor<CompilationTestHelper.Result> acceptor) {
 		//readFile(filename).assertCompilesTo('oracles/power_window_case_study/lazy.BASE.sa')
 		
-		readFile(filename).compile(acceptor)
+		val adaptation = readFile(filename).parse
+		val fileUri = URI.createFileURI(filename)
+		val fsa = new InMemoryFileSystemAccess();
+		val generator = new SemanticAdaptationCanonicalGenerator();
 		
+		generator.doGenerate(adaptation.elements.filter(Adaptation).head, fsa, fileUri);
 	}
 }

+ 3 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical/META-INF/MANIFEST.MF

@@ -15,4 +15,6 @@ Require-Bundle: be.uantwerpen.ansymo.semanticadaptation,
  org.eclipse.xtext.xbase.testing,
  org.eclipse.xtext.util
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.apache.log4j
+Import-Package: be.uantwerpen.ansymo.semanticadaptation.log,
+ org.apache.log4j
+Export-Package: be.uantwerpen.ansymo.semanticadaptation.cg.canonical

+ 1 - 4
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.canonical/pom.xml

@@ -12,15 +12,12 @@
 	<artifactId>be.uantwerpen.ansymo.semanticadaptation.cg.canonical</artifactId>
 	<packaging>eclipse-plugin</packaging>
 
-	<name>be.uantwerpen.ansymo.semanticadaptation Code Generation to Canonical</name>
+	<name>be.uantwerpen.ansymo.semanticadaptation Canonical Generator</name>
 
 	<properties>
     <main.basedir>${project.parent.basedir}</main.basedir>
 	</properties>
 
-	<dependencies>
-		
-	</dependencies>
 
 	<build>
 			<plugins>

+ 13 - 24
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationCanonicalGenerator.xtend

@@ -1,11 +1,12 @@
 /*
  * generated by Xtext 2.10.0
  */
-package be.uantwerpen.ansymo.semanticadaptation.generator
+package be.uantwerpen.ansymo.semanticadaptation.cg.canonical
 
-import be.uantwerpen.ansymo.semanticadaptation.generator.graph.DirectedGraph
-import be.uantwerpen.ansymo.semanticadaptation.generator.graph.FMUGraph
-import be.uantwerpen.ansymo.semanticadaptation.generator.graph.TopologicalSort
+import be.uantwerpen.ansymo.semanticadaptation.cg.canonical.graph.DirectedGraph
+import be.uantwerpen.ansymo.semanticadaptation.cg.canonical.graph.FMUGraph
+import be.uantwerpen.ansymo.semanticadaptation.cg.canonical.graph.TopologicalSort
+import be.uantwerpen.ansymo.semanticadaptation.log.Log
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Assignment
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.AtomicUnity
@@ -33,7 +34,6 @@ import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.MultiplyUnity
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ReactiveOrDelayed
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RealLiteral
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptationFactory
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SingleParamDeclaration
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SingleVarDeclaration
@@ -47,40 +47,27 @@ import java.util.LinkedList
 import java.util.List
 import java.util.Map
 import org.eclipse.emf.common.util.EList
+import org.eclipse.emf.common.util.URI
 import org.eclipse.emf.ecore.EObject
-import org.eclipse.emf.ecore.resource.Resource
 import org.eclipse.xtext.EcoreUtil2
-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 SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
+class SemanticAdaptationCanonicalGenerator {
 	
 	String CANONICAL_SUFIX = "_canonical"
 	
-	override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
-		Log.push("Generating canonical semantic adaptation for file " + resource.URI + "...")
-		
-		Log.println("Resource URI information:")
-		Log.println("\t resource.URI.lastSegment = " + resource.URI.lastSegment())
-		Log.println("\t resource.URI.trimFileExtension = " + resource.URI.trimFileExtension())
-		
-		// Create in memory representation of canonical SA file
-		var adaptations = resource.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation);
-		
-		check(adaptations.size == 1, "Only one semantic adaptation is supported per .sa file")
-		
-		var adaptation = adaptations.head
+	def Adaptation doGenerate(Adaptation adaptation, IFileSystemAccess2 fsa, URI mainFile) {
+		Log.push("Generating canonical semantic adaptation for file...")
 		
 		Log.println(prettyprint_model(adaptation, "File Read"))
 		
 		// Create file name for the canonical sa file
-		var fileNameWithoutExt = resource.URI.trimFileExtension().lastSegment()
+		var fileNameWithoutExt = mainFile.trimFileExtension().lastSegment()
 		
 		Log.println("Checking if file is already a canonical version...")
 		if (fileNameWithoutExt.indexOf(CANONICAL_SUFIX) == -1){
@@ -102,7 +89,9 @@ class SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
 			Log.println("Nothing to do.")
 		}
 		
-		Log.pop("Generating canonical semantic adaptation for file " + resource.URI + "... DONE.")
+		Log.pop("Generating canonical semantic adaptation for file... DONE")
+		
+		return adaptation
 	}
 	
 	def prettyprint_model(Adaptation sa, String title){

+ 1 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/graph/DirectedGraph.java

@@ -1,4 +1,4 @@
-package be.uantwerpen.ansymo.semanticadaptation.generator.graph;
+package be.uantwerpen.ansymo.semanticadaptation.cg.canonical.graph;
 
 import java.util.Collections;
 import java.util.HashMap;

+ 1 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/graph/FMUGraph.java

@@ -1,4 +1,4 @@
-package be.uantwerpen.ansymo.semanticadaptation.generator.graph;
+package be.uantwerpen.ansymo.semanticadaptation.cg.canonical.graph;
 
 import java.util.Iterator;
 

+ 1 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/graph/TopologicalSort.java

@@ -1,4 +1,4 @@
-package be.uantwerpen.ansymo.semanticadaptation.generator.graph;
+package be.uantwerpen.ansymo.semanticadaptation.cg.canonical.graph;
 
 /******************************************************************************
  * File: TopologicalSort.java

+ 13 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/META-INF/MANIFEST.MF

@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: be.uantwerpen.ansymo.semanticadaptation.cg.chain
+Bundle-Vendor: University of Antwerp, Ansymo Lab
+Bundle-Version: 1.0.0.qualifier
+Bundle-SymbolicName: be.uantwerpen.ansymo.semanticadaptation.cg.chain;singleton:=true
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Import-Package: be.uantwerpen.ansymo.semanticadaptation.log
+Require-Bundle: be.uantwerpen.ansymo.semanticadaptation;bundle-version="1.0.0",
+ be.uantwerpen.ansymo.semanticadaptation.cg.canonical;bundle-version="1.0.0",
+ org.eclipse.xtext.generator;bundle-version="2.11.0",
+ be.uantwerpen.ansymo.semanticadaptation.cg.cpp;bundle-version="1.0.0"

+ 16 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/build.properties

@@ -0,0 +1,16 @@
+source.. = src/,\
+           src-gen/,\
+           xtend-gen/
+bin.includes = .,\
+               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,\
+                     com.ibm.icu

+ 13 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/plugin.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="windows-1252"?>
+<?eclipse version="3.0"?>
+<plugin>
+   <extension
+         id="chain_generator_extension"
+         name="chain_generator_extension"
+         point="be.uantwerpen.ansymo.semanticadaptation.generator_extension">
+      <generator
+            class="be.uantwerpen.ansymo.semanticadaptation.cg.chain.SemanticAdaptationChainGenerator">
+      </generator>
+   </extension>
+
+</plugin>

+ 35 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/pom.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<relativePath>../pom.xml</relativePath>
+		<groupId>be.uantwerpen.ansymo.semanticadaptation</groupId>
+		<artifactId>parent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>be.uantwerpen.ansymo.semanticadaptation.cg.chain</artifactId>
+	<packaging>eclipse-plugin</packaging>
+
+	<name>be.uantwerpen.ansymo.semanticadaptation Code Generator</name>
+
+	<properties>
+    <main.basedir>${project.parent.basedir}</main.basedir>
+	</properties>
+
+	<dependencies>
+		
+	</dependencies>
+
+	<build>
+			<plugins>
+				<plugin>
+					<groupId>org.eclipse.xtend</groupId>
+					<artifactId>xtend-maven-plugin</artifactId>
+				</plugin>
+	
+			</plugins>
+	</build>
+
+</project>

+ 30 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.chain/src/be/uantwerpen/ansymo/semanticadaptation/cg/chain/SemanticAdaptationChainGenerator.xtend

@@ -0,0 +1,30 @@
+/*
+ * generated by Xtext 2.10.0
+ */
+package be.uantwerpen.ansymo.semanticadaptation.cg.chain
+
+import be.uantwerpen.ansymo.semanticadaptation.cg.canonical.SemanticAdaptationCanonicalGenerator
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.CppGenerator
+import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationCustomGenerator
+import be.uantwerpen.ansymo.semanticadaptation.log.Log
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
+import org.eclipse.emf.common.util.URI
+import org.eclipse.xtext.generator.IFileSystemAccess2
+
+class SemanticAdaptationChainGenerator extends SemanticAdaptationCustomGenerator {
+	
+	override void generate(Adaptation sa, IFileSystemAccess2 fsa, URI mainFile){
+		Log.push("SemanticAdaptationChainGenerator.generate")
+		
+		val canonical_sa = (new SemanticAdaptationCanonicalGenerator).doGenerate(sa, fsa, mainFile)
+		
+		Log.push("Generating cpp code...")
+		
+		val cppGen = new CppGenerator();
+		cppGen.doGenerate(canonical_sa.eResource, fsa);
+		
+		Log.pop("Generating cpp code... DONE")
+		
+		Log.pop("SemanticAdaptationChainGenerator.generate")
+	}
+}

+ 1 - 2
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppAutoTest.xtend

@@ -92,8 +92,7 @@ class CgCppAutoTest extends AbstractSemanticAdaptationTest {
 		__assertNoParseErrors(model, hdFile)
 
 		val fsa = new InMemoryFileSystemAccess()
-		val IGeneratorContext ctxt = null;
-		new CppGenerator().doGenerate(model.eResource, fsa, ctxt)
+		new CppGenerator().doGenerate(model.eResource, fsa)
 
 		System.out.println(fsa.allFiles)
 	}

+ 7 - 8
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest.xtend

@@ -6,6 +6,7 @@ package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests
 import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.BuildUtilities
 import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.CppGenerator
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
+import be.uantwerpen.ansymo.semanticadaptation.testframework.StaticGenerators
 import be.uantwerpen.ansymo.semanticadaptation.tests.AbstractSemanticAdaptationTest
 import be.uantwerpen.ansymo.semanticadaptation.tests.SemanticAdaptationInjectorProvider
 import com.google.inject.Inject
@@ -13,19 +14,19 @@ import java.io.File
 import java.io.FileWriter
 import java.nio.file.Files
 import java.util.regex.Pattern
+import org.eclipse.emf.common.CommonPlugin
+import org.eclipse.emf.common.util.URI
 import org.eclipse.emf.ecore.EObject
 import org.eclipse.emf.ecore.resource.ResourceSet
-import org.eclipse.xtext.generator.IGeneratorContext
 import org.eclipse.xtext.generator.InMemoryFileSystemAccess
 import org.eclipse.xtext.testing.InjectWith
 import org.eclipse.xtext.testing.XtextRunner
 import org.eclipse.xtext.testing.util.ParseHelper
 import org.eclipse.xtext.testing.validation.ValidationTestHelper
+import org.junit.Assert
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
-import be.uantwerpen.ansymo.semanticadaptation.testframework.StaticGenerators
-import org.junit.Ignore
-import org.junit.Assert
 
 @RunWith(XtextRunner)
 @InjectWith(SemanticAdaptationInjectorProvider)
@@ -71,9 +72,8 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 		val correctFileDirectory = new File(directory + File.separator + "correct");
 
 		val fsa = new InMemoryFileSystemAccess()
-		val IGeneratorContext ctxt = null;
 		val cppGen = new CppGenerator();
-		cppGen.doGenerate(model.eResource, fsa, ctxt);
+		cppGen.doGenerate(model.eResource, fsa);
 
 		for (files : fsa.allFiles.entrySet) {
 			val filename2 = files.key.substring(14);
@@ -124,9 +124,8 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 		__assertNoParseErrors(model, filename)
 
 		val fsa = new InMemoryFileSystemAccess();
-		val IGeneratorContext ctxt = null;
 		val cppGen = new CppGenerator();
-		cppGen.doGenerate(model.eResource, fsa, ctxt);
+		cppGen.doGenerate(model.eResource, fsa, CommonPlugin.resolve(URI.createFileURI(".")));
 
 		if (saRootDir.exists) {
 			BuildUtilities.deleteFolder(srcGenPath);

+ 2 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/META-INF/MANIFEST.MF

@@ -15,5 +15,6 @@ Require-Bundle: be.uantwerpen.ansymo.semanticadaptation,
  org.eclipse.xtext.xbase.testing,
  org.eclipse.xtext.util
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.apache.log4j
+Import-Package: be.uantwerpen.ansymo.semanticadaptation.log,
+ org.apache.log4j
 Export-Package: be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation

+ 8 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/pom.xml

@@ -27,6 +27,14 @@
 			<version>${project.version}</version>
 			<scope>compile</scope>
 		</dependency-->
+		<dependency>
+			<groupId>be.uantwerpen.ansymo.semanticadaptation</groupId>
+			<artifactId>
+				be.uantwerpen.ansymo.semanticadaptation
+			</artifactId>
+			<version>1.0.0-SNAPSHOT</version>
+			<type>eclipse-plugin</type>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 3 - 8
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/BuildUtilities.java

@@ -1,17 +1,12 @@
 package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.io.InputStream;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
+
+import be.uantwerpen.ansymo.semanticadaptation.log.Log;
 
 public class BuildUtilities {
 //	public List<File> copyNativeLibFiles(File outfolder) {
@@ -81,7 +76,7 @@ public class BuildUtilities {
 		FileWriter writer = new FileWriter(file);
 		writer.write(content);
 		writer.close();
-		System.out.println("Stored file: " + file);
+		Log.println("Stored file: " + file);
 	}
 
 	public static void copyFile(File sourceFile, File sinkFile) throws IOException {

+ 33 - 9
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/CppGenerator.xtend

@@ -9,6 +9,7 @@ import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVCausality
 import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
 import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.ScalarVariable
 import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.IncorrectAmountOfElementsException
+import be.uantwerpen.ansymo.semanticadaptation.log.Log
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ControlRuleBlock
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InOutRules
@@ -25,23 +26,34 @@ import java.util.LinkedHashMap
 import java.util.List
 import org.eclipse.emf.common.util.EList
 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 org.eclipse.emf.common.CommonPlugin
+import org.eclipse.emf.common.util.URI
 
-class CppGenerator extends AbstractGenerator {
+class CppGenerator {
 	private var IFileSystemAccess2 fsa;
 	private List<File> resourcePaths = newArrayList();
 
-	override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
+	def void doGenerate(Resource resource, IFileSystemAccess2 fsa) {
+		Log.push("CppGenerator.doGenerate")
+		val adaptationFolderURI = resource.URI.trimSegments(1)
+		Log.println("Adaptation folder URI: " + adaptationFolderURI)
+		doGenerate(resource, fsa, adaptationFolderURI)
+		Log.pop("CppGenerator.doGenerate")
+	}
+	
+	def void doGenerate(Resource resource, IFileSystemAccess2 fsa, URI adaptationFolderURI) {
+		Log.push("CppGenerator.doGenerate " + adaptationFolderURI)
 		this.fsa = fsa;
 		for (SemanticAdaptation type : resource.allContents.toIterable.filter(SemanticAdaptation)) {
-			type.compile;
+			type.compile(adaptationFolderURI);
 		}
+		Log.pop("CppGenerator.doGenerate"  + adaptationFolderURI)
 	}
-
+	
 	// TODO: Verify adaptation.name is not a C++ keyword
-	def void compile(SemanticAdaptation adaptation) {
+	def void compile(SemanticAdaptation adaptation, URI adaptationFolderURI) {
+		Log.push("CppGenerator.compile")
 		for (Adaptation adap : adaptation.elements.filter(Adaptation)) {
 			// Value used for scoping variables in the .sa file
 			val adapInteralRefName = adap.name;
@@ -70,14 +82,15 @@ class CppGenerator extends AbstractGenerator {
 			 * The mappedSV contains the original scalar variable and extra data such as define name.
 			 */
 			var LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mappedScalarVariables = newLinkedHashMap();
-
+			
 			/*
 			 * Loading the FMU defined in InnerFMU, the related model description file and its scalar variables.
 			 */
 			// TODO: Add support for multiple inner fmus
 			var ModelDescription md;
 			for (fmu : adap.inner.eAllContents.toList.filter(InnerFMU)) {
-				val fmuFile = new File(fmu.path.replace('\"', ''));
+				Log.push("Loading fmu " + fmu.path)
+				val fmuFile = getFMUFile(fmu.path, adaptationFolderURI)
 				this.resourcePaths.add(fmuFile);
 				md = new ModelDescription(fmu.name, fmu.type.name, fmuFile);
 				fmus.add(fmu.name -> fmu.type.name);
@@ -88,6 +101,7 @@ class CppGenerator extends AbstractGenerator {
 					mSV.put(mappedSv.mappedSv.name, mappedSv);
 				}
 				mappedScalarVariables.put(fmu.name, mSV);
+				Log.pop("Loading fmu " + fmu.path)
 			}
 
 			// C++ Defines for accessing FMU scalar variables.
@@ -194,6 +208,16 @@ class CppGenerator extends AbstractGenerator {
 			fsa.generateFile("Fmu.cpp", fmuCppFile);
 
 		}
+		Log.pop("CppGenerator.compile")
+	}
+	
+	def getFMUFile(String fmuUnresolvedPath, URI adaptationFolderURI) {
+		var resolvedFolderURI = CommonPlugin.resolve(adaptationFolderURI);
+		val fmuCompleteURI = URI.createFileURI(resolvedFolderURI.toFileString + File.separatorChar + fmuUnresolvedPath.replace('\"', ''))
+		var fmuPath = fmuCompleteURI.toFileString
+		Log.println("Resolved fmu path: " + fmuPath)
+		val fmuFile = new File(fmuPath);
+		return fmuFile
 	}
 
 	def String compileParams(LinkedHashMap<String, GlobalInOutVariable> gVars, EList<ParamDeclarations> params) {

+ 16 - 12
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ModelDescription.xtend

@@ -1,23 +1,24 @@
 package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation
 
-import org.w3c.dom.Document
-import java.util.LinkedHashMap
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVCausality
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVVariability
 import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.ScalarVariable
-import java.util.zip.ZipFile
+import be.uantwerpen.ansymo.semanticadaptation.log.Log
+import java.io.File
 import java.util.Enumeration
+import java.util.LinkedHashMap
 import java.util.zip.ZipEntry
-import java.io.File
-import javax.xml.parsers.DocumentBuilderFactory
+import java.util.zip.ZipFile
 import javax.xml.parsers.DocumentBuilder
-import javax.xml.xpath.XPathFactory
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.soap.Node
 import javax.xml.xpath.XPath
-import javax.xml.xpath.XPathExpression
 import javax.xml.xpath.XPathConstants
+import javax.xml.xpath.XPathExpression
+import javax.xml.xpath.XPathFactory
+import org.w3c.dom.Document
 import org.w3c.dom.NodeList
-import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVCausality
-import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVVariability
-import javax.xml.soap.Node
-import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
 
 class ModelDescription {
 	private final Document md;
@@ -29,10 +30,12 @@ class ModelDescription {
 	private var String guid;
 
 	new(String name, String type, File path) {
+		Log.push("Loading model description for fmu " + name)
 		this.name = name;
 		this.type = type;
 		
-
+		Log.println("Source fmu absolute path: " + path.absolutePath)
+		
 		var ZipFile fmu = new ZipFile(path);
 		var Enumeration<? extends ZipEntry> entries = fmu.entries();
 		var boolean entryFound = false;
@@ -52,6 +55,7 @@ class ModelDescription {
 		this.md = builder.parse(is);
 		is.close();
 		calcExtractInformation();
+		Log.pop("Loading model description for fmu " + name)
 	}
 
 	private def calcExtractInformation() {

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

@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: be.uantwerpen.ansymo.semanticadaptation.log
+Bundle-Vendor: University of Antwerp, Ansymo Lab
+Bundle-Version: 1.0.0.qualifier
+Bundle-SymbolicName: be.uantwerpen.ansymo.semanticadaptation.log; singleton:=true
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Import-Package: org.apache.log4j
+Export-Package: be.uantwerpen.ansymo.semanticadaptation.log
+Require-Bundle: org.eclipse.xtext.xbase.lib;bundle-version="2.11.0"

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

@@ -0,0 +1,20 @@
+source.. = src/,\
+           src-gen/,\
+           xtend-gen/
+bin.includes = .,\
+               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
+src.includes = src/,\
+               plugin.xml,\
+               META-INF/

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

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="windows-1252"?>
+<?eclipse version="3.0"?>
+<plugin>
+
+</plugin>

+ 34 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.log/pom.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<relativePath>../pom.xml</relativePath>
+		<groupId>be.uantwerpen.ansymo.semanticadaptation</groupId>
+		<artifactId>parent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>be.uantwerpen.ansymo.semanticadaptation.log</artifactId>
+	<packaging>eclipse-plugin</packaging>
+
+	<name>be.uantwerpen.ansymo.semanticadaptation Logger</name>
+
+	<properties>
+    <main.basedir>${project.parent.basedir}</main.basedir>
+	</properties>
+
+	<dependencies>
+		
+	</dependencies>
+
+	<build>
+			<plugins>
+				<plugin>
+					<groupId>org.eclipse.xtend</groupId>
+					<artifactId>xtend-maven-plugin</artifactId>
+				</plugin>
+			</plugins>
+	</build>
+
+</project>

+ 63 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.log/src/be/uantwerpen/ansymo/semanticadaptation/log/Log.xtend

@@ -0,0 +1,63 @@
+package be.uantwerpen.ansymo.semanticadaptation.log
+
+import org.apache.log4j.ConsoleAppender
+import org.apache.log4j.Level
+import org.apache.log4j.LogManager
+import org.apache.log4j.Logger
+import org.apache.log4j.PatternLayout
+
+class Log {
+	var static Log l = null;
+	
+	var c = 0
+	
+	private static Logger logger;
+	
+	protected new() {
+		LogManager.resetConfiguration();
+		val console = new ConsoleAppender(); // create appender
+		// configure the appender
+		val PATTERN = "%d [%p] %m%n";
+		console.setLayout(new PatternLayout(PATTERN));
+		console.setThreshold(Level.DEBUG);
+		console.activateOptions();
+		// add appender to any Logger (here is root)
+		Logger.getRootLogger().addAppender(console);
+		
+		logger = Logger.getLogger("L")
+		logger.info("Logger initialized.")
+	}
+
+	def protected static Log gl() {
+		if (l === null) {
+			l = new Log();
+		}
+		return l;
+	}
+	
+	def static String space(int indent){
+		var res = ""
+		for(var i = 0; i<indent; i++){
+			res += " "
+		}
+		return res;
+	}
+
+	def static void println(String msg){
+		val space = space(gl().c)
+		for(line : msg.split('\n')){
+			logger.info(space + line)
+		}
+	}
+	
+	def static void push(String msg){
+		logger.info(space(gl().c) + ">" + msg)
+		gl().c++
+	}
+	
+	def static void pop(String msg){
+		gl().c--
+		logger.info(space(gl().c) + "<" + msg)
+	}
+	
+}

+ 0 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/pom.xml

@@ -33,7 +33,6 @@
 				<artifactId>xtend-maven-plugin</artifactId>
 			</plugin>
 
-
 			<plugin>
 				<!-- Remember that these tests only run in integration so between package and install http://www.vogella.com/tutorials/EclipseTycho/article.html -->
 				<groupId>org.eclipse.tycho</groupId>

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

@@ -1,57 +0,0 @@
-/*
- * 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)
-	}
-
-}

+ 12 - 10
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/META-INF/MANIFEST.MF

@@ -13,18 +13,20 @@ Require-Bundle: org.eclipse.xtext,
  org.antlr.runtime,
  org.eclipse.xtext.util,
  org.eclipse.xtend.lib,
- org.eclipse.emf.common
+ org.eclipse.emf.common,
+ org.eclipse.core.runtime;bundle-version="3.12.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.util,
- be.uantwerpen.ansymo.semanticadaptation.services,
+Export-Package: be.uantwerpen.ansymo.semanticadaptation,
+ be.uantwerpen.ansymo.semanticadaptation.formatting2,
+ be.uantwerpen.ansymo.semanticadaptation.parser.antlr,
+ be.uantwerpen.ansymo.semanticadaptation.parser.antlr.internal,
  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.semanticAdaptation.impl,
+ be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.util,
  be.uantwerpen.ansymo.semanticadaptation.serializer,
+ be.uantwerpen.ansymo.semanticadaptation.services,
  be.uantwerpen.ansymo.semanticadaptation.validation,
- be.uantwerpen.ansymo.semanticadaptation.parser.antlr,
- be.uantwerpen.ansymo.semanticadaptation.generator,
- be.uantwerpen.ansymo.semanticadaptation.formatting2
-Import-Package: org.apache.log4j
+ be.uantwerpen.ansymo.semanticadaptation.generator
+Import-Package: be.uantwerpen.ansymo.semanticadaptation.log,
+ org.apache.log4j

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

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="windows-1252"?>
 <?eclipse version="3.0"?>
 <plugin>
+   <extension-point id="generator_extension" name="generator_extension" schema="schema/generator_extension.exsd"/>
 	<extension point="org.eclipse.emf.ecore.generated_package">
 		<package 
 			uri = "http://www.uantwerpen.be/ansymo/semanticadaptation/SemanticAdaptation"

+ 102 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/schema/generator_extension.exsd

@@ -0,0 +1,102 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="be.uantwerpen.ansymo.semanticadaptation" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="be.uantwerpen.ansymo.semanticadaptation" id="generator_extension" name="generator_extension"/>
+      </appInfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <choice>
+            <element ref="generator"/>
+         </choice>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="generator">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationCustomGenerator:"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiinfo"/>
+      </appInfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+
+</schema>

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

@@ -3,9 +3,9 @@
  */
 package be.uantwerpen.ansymo.semanticadaptation
 
-import be.uantwerpen.ansymo.semanticadaptation.valueconverter.SemanticAdaptationValueConverters
+import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationGenerator
 import be.uantwerpen.ansymo.semanticadaptation.scoping.SemanticAdaptationScopeProvider
-import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationCanonicalGenerator
+import be.uantwerpen.ansymo.semanticadaptation.valueconverter.SemanticAdaptationValueConverters
 
 /**
  * Use this class to register components to be used at runtime / without the Equinox extension registry.
@@ -19,6 +19,6 @@ class SemanticAdaptationRuntimeModule extends AbstractSemanticAdaptationRuntimeM
 		return SemanticAdaptationScopeProvider
 	}
 	override bindIGenerator2() {
-		return SemanticAdaptationCanonicalGenerator
+		return SemanticAdaptationGenerator
 	}
 }

+ 1 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/formatting2/SemanticAdaptationFormatter.xtend

@@ -3,7 +3,6 @@
  */
 package be.uantwerpen.ansymo.semanticadaptation.formatting2
 
-import be.uantwerpen.ansymo.semanticadaptation.generator.Log
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CompositeOutputFunction
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CustomControlRule
@@ -11,6 +10,7 @@ import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DataRule
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.StateTransitionFunction
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Statement
+import be.uantwerpen.ansymo.semanticadaptation.log.Log
 import org.eclipse.xtext.formatting2.AbstractFormatter2
 import org.eclipse.xtext.formatting2.IFormattableDocument
 

+ 0 - 48
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/Log.xtend

@@ -1,48 +0,0 @@
-package be.uantwerpen.ansymo.semanticadaptation.generator
-
-import org.apache.log4j.Logger
-
-class Log {
-	var static Log l = null;
-	
-	var c = 0
-	
-	private static final Logger logger = Logger.getLogger("");
-	
-	protected new() {
-		// Exists only to defeat instantiation.
-	}
-
-	def protected static Log gl() {
-		if (l === null) {
-			l = new Log();
-		}
-		return l;
-	}
-	
-	def static String space(int indent){
-		var res = ""
-		for(var i = 0; i<indent; i++){
-			res += " "
-		}
-		return res;
-	}
-
-	def static void println(String msg){
-		val space = space(gl().c)
-		for(line : msg.split('\n')){
-			logger.info(space + line)
-		}
-	}
-	
-	def static void push(String msg){
-		logger.info(space(gl().c) + ">" + msg)
-		gl().c++
-	}
-	
-	def static void pop(String msg){
-		gl().c--
-		logger.info(space(gl().c) + "<" + msg)
-	}
-	
-}

+ 14 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationCustomGenerator.java

@@ -0,0 +1,14 @@
+package be.uantwerpen.ansymo.semanticadaptation.generator;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.generator.IFileSystemAccess2;
+
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation;
+
+public class SemanticAdaptationCustomGenerator {
+
+	public void generate(Adaptation sa, IFileSystemAccess2 fsa, URI mainFile) {
+		// To be overriden
+	}
+
+}

+ 69 - 5
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationGenerator.xtend

@@ -3,6 +3,12 @@
  */
 package be.uantwerpen.ansymo.semanticadaptation.generator
 
+import be.uantwerpen.ansymo.semanticadaptation.log.Log
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
+import org.eclipse.core.runtime.IExtensionPoint
+import org.eclipse.core.runtime.IExtensionRegistry
+import org.eclipse.core.runtime.Platform
 import org.eclipse.emf.ecore.resource.Resource
 import org.eclipse.xtext.generator.AbstractGenerator
 import org.eclipse.xtext.generator.IFileSystemAccess2
@@ -16,10 +22,68 @@ import org.eclipse.xtext.generator.IGeneratorContext
 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(', '))
+		Log.push("Generating canonical semantic adaptation for file " + resource.URI + "...")
+		
+		Log.println("Resource URI information:")
+		Log.println("\t resource.URI.lastSegment = " + resource.URI.lastSegment())
+		Log.println("\t resource.URI.trimFileExtension = " + resource.URI.trimFileExtension())
+		
+		val chainGenerator = loadSemanticAdaptationCustomGenerator()
+		
+		// Create in memory representation of canonical SA file
+		var adaptations = resource.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation);
+		
+		check(adaptations.size == 1, "Only one semantic adaptation is supported per .sa file")
+		
+		var adaptation = adaptations.head
+		
+		chainGenerator.generate(adaptation, fsa, resource.URI)
+		
+		Log.pop("Generating canonical semantic adaptation for file " + resource.URI + "...")
 	}
+	
+	def SemanticAdaptationCustomGenerator loadSemanticAdaptationCustomGenerator() {
+		Log.push("loadSemanticAdaptationCustomGenerator")
+		
+		val IExtensionRegistry registry = Platform.getExtensionRegistry();
+		val IExtensionPoint point = registry.getExtensionPoint("be.uantwerpen.ansymo.semanticadaptation.generator_extension");
+		if (point === null) {
+			Log.println("Extension point be_uantwerpen_ansymo_semanticadaptation_generator must be provided.")
+			throw new Exception("Extension point be_uantwerpen_ansymo_semanticadaptation_generator must be provided.");
+		}
+		Log.println("Extension point found.")
+		var chainExtension = point.getExtension("be.uantwerpen.ansymo.semanticadaptation.cg.chain.chain_generator_extension")
+		if (chainExtension === null) {
+			throw new Exception("An extension called chain_generator_extension must be provided to Extension Point be.uantwerpen.ansymo.semanticadaptation.generator_extension.");
+		}
+		Log.println("Extension to extension point found.")
+		
+		val configElement = chainExtension.configurationElements.head
+		if (configElement === null) {
+			throw new Exception("Configuration element not found.");
+		}
+		
+		val obj = configElement.createExecutableExtension("class")
+		if (obj === null) {
+			throw new Exception("Class attribute of extension not proper java class.");
+		}
+		if (!(obj instanceof SemanticAdaptationCustomGenerator)) {
+			throw new Exception("Instance of SemanticAdaptationCustomGenerator expected. Found " + obj.class);
+		}
+		
+		Log.println("Instance of SemanticAdaptationCustomGenerator found.")
+		
+		val chainGenerator = obj as SemanticAdaptationCustomGenerator
+		
+		Log.pop("loadSemanticAdaptationCustomGenerator")
+		return chainGenerator
+	}
+	
+	
+	def check(Boolean condition, String msg){
+		if (! condition){
+			throw new Exception("Assertion error: " + msg)
+		}
+	}
+	
 }

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

@@ -1,110 +0,0 @@
-/*
- * generated by Xtext 2.10.0
- */
-package be.uantwerpen.ansymo.semanticadaptation.generator
-
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
-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 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.inner.instances.filter(AtomicFMU)�
-from case_study.units.ct_based.�fmu.name� import �fmu.name�
-�ENDFOR�
-�FOR i:a.inner.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)
-'''
-}

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

@@ -7,7 +7,6 @@
  *******************************************************************************/
 package be.uantwerpen.ansymo.semanticadaptation.scoping
 
-import be.uantwerpen.ansymo.semanticadaptation.generator.Log
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.AlgebraicLoopSolution
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Component
@@ -43,6 +42,7 @@ import org.eclipse.xtext.scoping.IScope
 import org.eclipse.xtext.scoping.Scopes
 import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider
 import org.eclipse.xtext.scoping.impl.IScopeWrapper
+import be.uantwerpen.ansymo.semanticadaptation.log.Log
 
 /**
  * This class contains custom scoping description.

+ 3 - 0
DSL_SemanticAdaptation/pom.xml

@@ -15,12 +15,15 @@
 	<modules>
 		<module>be.uantwerpen.ansymo.semanticadaptation.testframework</module>
 		<module>be.uantwerpen.ansymo.semanticadaptation</module>
+		<module>be.uantwerpen.ansymo.semanticadaptation.log</module>
+		<module>be.uantwerpen.ansymo.semanticadaptation.cg.chain</module>
 		<module>be.uantwerpen.ansymo.semanticadaptation.tests</module>
 		<module>be.uantwerpen.ansymo.semanticadaptation.ide</module>
 		<module>be.uantwerpen.ansymo.semanticadaptation.ui</module>
 		<module>be.uantwerpen.ansymo.semanticadaptation.cg.cpp</module>
 		<module>be.uantwerpen.ansymo.semanticadaptation.cg.canonical</module>
 	  <module>be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests</module>
+		<module>be.uantwerpen.ansymo.semanticadaptation.cg.canonical.tests</module>
  <module>features</module>
  <module>repository</module>
 	</modules>