Browse Source

Corrected typo in window_sa example.
Place assertions in tests as xtend sometimes works, sometimes doesnt...
Updated tests to accomodate for replacement of port refs
In CG, Updated min to use a list instead of just two values.
The generated windows_sa is now fully supported! From high level dsl description, to c++ code generation.

Cláudio Gomes 3 years ago
parent
commit
d28c3be133

+ 4 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest.xtend

@@ -45,6 +45,10 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 		__parseNoErrors('test_input/single_folder_spec/window/window_sa_canonical_new.BASE.sa', 'generated', "powerwindow");
 	}
 	
+	@Test def window_sa_canonical_generated() {
+		__parseNoErrors('test_input/single_folder_spec/window/window_sa.BASE_canonical.sa', 'generated', "powerwindow_generated");
+	}
+	
 	@Ignore
 	@Test def lazy_sa_canonical() {
 		__parseNoErrors('test_input/single_folder_spec/lazy/lazy_canonical.sa', 'generated', "lazy");

+ 39 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/window_sa.BASE_canonical.sa

@@ -0,0 +1,39 @@
+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 Real displacement(rad), Real speed (rad/s), Real reaction_force (N)
+		with output ports Real height (cm), Real reaction_torque (N.m)
+
+input ports Real displacement ( rad ) , Real speed ( rad / s ) , Real reaction_force ( N )
+
+output ports Real disp (m)  , Real tau (N)
+
+param Real INIT_DISPLACEMENT := 0.0 , Real INIT_SPEED := 0.0 , Real INIT_REACTION_FORCE := 0.0 , Real INIT_HEIGHT := 0.0 , Real INIT_REACTION_TORQUE := 0.0 ;
+
+control rules {
+var H_window := do_step ( window , t , H ) ;
+return min ( H_window ) ; }
+
+in var Real stored__displacement := INIT_DISPLACEMENT , Real stored__speed := INIT_SPEED , Real stored__reaction_force := INIT_REACTION_FORCE ; 
+in rules {
+	true -> {
+		stored__speed := windowSA . speed ;
+		stored__reaction_force := windowSA . reaction_force ;
+		stored__displacement := windowSA . displacement ; } --> {
+		window . speed := stored__speed ;
+		window . displacement := stored__displacement ;
+		window . reaction_force := stored__reaction_force ; } ; }
+		
+out var Real stored__reaction_torque := INIT_REACTION_TORQUE , Real stored__height := INIT_HEIGHT ; 
+out rules {
+	true -> {
+		stored__reaction_torque := window . reaction_torque ;
+		stored__height := window . height ; } --> {
+		windowSA . disp := stored__height / 100.0 ;
+		windowSA.tau := -stored__reaction_torque;
+	};
+}
+
+

+ 1 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/RulesConditionSwitch.xtend

@@ -424,7 +424,7 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 		} 
 		retInfo.code = 
 		'''
-		min(«doSwitchResCode.join(",")»)
+		min({«doSwitchResCode.join(",")»})
 		'''
 		return retInfo;
 	}

+ 2 - 2
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/input/power_window_case_study/window_sa.BASE.sa

@@ -2,7 +2,7 @@ semantic adaptation reactive mealy WindowSA windowSA
 at "./path/to/WindowSA.fmu"
 
 	for inner fmu Window window
-		at "./path/to/Window.fmu"
+		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)
 
@@ -10,7 +10,7 @@ output ports disp (m)  <- window.height, tau (N)
 
 out rules {
 	true -> {} --> {
-		windowSA.tau := -window.reaction_force;
+		windowSA.tau := -window.reaction_torque;
 	};
 }
 

+ 48 - 37
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationGeneratorTest.xtend

@@ -9,10 +9,13 @@ import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.AtomicUnity
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BoolLiteral
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CompositeOutputFunction
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CustomControlRule
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Declaration
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InnerFMU
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.MultiplyUnity
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Neg
 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 com.google.inject.Inject
 import org.eclipse.xtext.testing.InjectWith
@@ -23,7 +26,6 @@ import org.eclipse.xtext.xbase.testing.CompilationTestHelper.Result
 import org.junit.Assert
 import org.junit.Test
 import org.junit.runner.RunWith
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Declaration
 
 @RunWith(XtextRunner)
 @InjectWith(SemanticAdaptationInjectorProvider)
@@ -34,14 +36,14 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 	@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
-				sa.name == "outerFMU"
-				sa.eAllContents.filter(Port).filter[p | p.name=="ext_input_port3"].head.unity instanceof MultiplyUnity
-				sa.eAllContents.filter(InnerFMU).filter[f | f.name=="innerFMU2"].head
-							.eAllContents.filter(Port).filter[p | p.name=="innerFMU2__input_port1"].head.type == "Real"
-				sa.eAllContents.filter(InnerFMU).filter[f | f.name=="innerFMU2"].head
-							.eAllContents.filter(Port).filter[p | p.name=="innerFMU2__outout_port1"].head.type == "Real"
-				sa.eAllContents.filter(InnerFMU).filter[f | f.name=="innerFMU2"].head
-							.eAllContents.filter(Port).filter[p | p.name=="innerFMU2__outout_port1"].head.unity instanceof AtomicUnity
+				Assert.assertTrue(sa.name == "outerFMU")
+				Assert.assertTrue(sa.eAllContents.filter(Port).filter[p | p.name=="ext_input_port3"].head.unity instanceof MultiplyUnity)
+				Assert.assertTrue(sa.eAllContents.filter(InnerFMU).filter[f | f.name=="innerFMU2"].head
+							.eAllContents.filter(Port).filter[p | p.name=="innerFMU2__input_port1"].head.type == "Real")
+				Assert.assertTrue(sa.eAllContents.filter(InnerFMU).filter[f | f.name=="innerFMU2"].head
+							.eAllContents.filter(Port).filter[p | p.name=="innerFMU2__outout_port1"].head.type == "Real")
+				Assert.assertTrue(sa.eAllContents.filter(InnerFMU).filter[f | f.name=="innerFMU2"].head
+							.eAllContents.filter(Port).filter[p | p.name=="innerFMU2__outout_port1"].head.unity instanceof AtomicUnity)
 				
 			}
 		}) }
@@ -49,9 +51,9 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 	@Test def test_addInputPorts_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
-				sa.inports.filter[p | p.name=="innerFMU1__input_port2"].head.type == "Bool"
+				Assert.assertTrue(sa.inports.filter[p | p.name=="innerFMU1__input_port2"].head.type == "Bool")
 				
-				sa.inports.filter[p | p.name=="innerFMU1__input_port1"].size == 0
+				Assert.assertTrue(sa.inports.filter[p | p.name=="innerFMU1__input_port1"].size == 0)
 				
 				//sa.inports.filter[p | p.name=="innerFMU2__input_port3"].head.targetdependency.owner.name == "innerFMU2"
 				//sa.inports.filter[p | p.name=="innerFMU2__input_port3"].head.targetdependency.port.name == "input_port3"
@@ -61,32 +63,32 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 	@Test def test_addParams_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
-				sa.params.head.declarations.filter[p | p.name=="INIT_EXT_INPUT_PORT3"].head.type == "Real"
-				sa.params.head.declarations.filter[p | p.name=="INIT_INNERFMU1__INPUT_PORT2"].head.expr instanceof BoolLiteral
+				Assert.assertTrue(sa.params.head.declarations.filter[p | p.name=="INIT_EXT_INPUT_PORT3"].head.type == "Real")
+				Assert.assertTrue(sa.params.head.declarations.filter[p | p.name=="INIT_INNERFMU1__INPUT_PORT2"].head.expr instanceof BoolLiteral)
 			}
 		}) }
 	
 	@Test def test_addInVars_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
-				sa.in.globalInVars.head.declarations.filter[p | p.name=="stored__innerFMU2__input_port2"].head.type == "Bool"
-				sa.in.globalInVars.head.declarations.filter[p | p.name=="stored__innerFMU2__input_port3"].head.expr instanceof Variable
+				Assert.assertTrue(sa.in.globalInVars.head.declarations.filter[p | p.name=="stored__innerFMU2__input_port2"].head.type == "Bool")
+				Assert.assertTrue(sa.in.globalInVars.head.declarations.filter[p | p.name=="stored__innerFMU2__input_port3"].head.expr instanceof Variable)
 			}
 		}) }
 	
 	@Test def test_addOutVars_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
-				sa.out.globalOutVars.head.declarations.filter[p | p.name=="stored__innerFMU1__output_port2"].head.type == "Integer"
+				Assert.assertTrue(sa.out.globalOutVars.head.declarations.filter[p | p.name=="stored__innerFMU1__output_port2"].head.type == "Integer")
 			}
 		}) }
 	
 	@Test def test_addExternal2InputPortStoredAssignments_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
-				sa.in.rules.head.statetransitionfunction.statements.head instanceof Assignment
-				(sa.in.rules.head.statetransitionfunction.statements.head as Assignment).lvalue.ref.name == "stored__innerFMU2__input_port3"
-				((sa.in.rules.head.statetransitionfunction.statements.head as Assignment).expr as Variable).ref.name == "innerFMU2__input_port3"
+				val fistAssignment = sa.in.rules.head.statetransitionfunction.statements.head as Assignment
+				Assert.assertTrue((fistAssignment.lvalue as Variable).ref instanceof SingleVarDeclaration)
+				Assert.assertTrue((fistAssignment.expr as Variable).ref instanceof Port)
 			}
 		}) }
 	
@@ -104,8 +106,8 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 				var Adaptation sa = t.resourceSet.resources.head.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation).head
 				val outFunction = sa.in.rules.head.outputfunction as CompositeOutputFunction
 				val firstAssignment = outFunction.statements.head as Assignment
-				firstAssignment.lvalue.ref.name == "input_port3"
-				(firstAssignment.expr as Variable).ref.name == "innerFMU2__input_port3"
+				Assert.assertTrue(firstAssignment.lvalue.ref.name == "innerFMU2__input_port1")
+				Assert.assertTrue((firstAssignment.expr as Variable).ref.name == "stored__innerFMU2__input_port1")
 			}
 		}) }
 	
@@ -115,29 +117,29 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 				var Adaptation sa = t.resourceSet.resources.head.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation).head
 				val outFunction = sa.out.rules.head.outputfunction as CompositeOutputFunction
 				val firstAssignment = outFunction.statements.head as Assignment
-				firstAssignment.lvalue.ref.name == "ext_output_port2"
-				(firstAssignment.expr as Variable).ref.name == "stored__innerFMU1__output_port2"
+				Assert.assertTrue(firstAssignment.lvalue.ref.name == "ext_output_port2")
+				Assert.assertTrue((firstAssignment.expr as Variable).ref.name == "stored__innerFMU1__output_port2")
 			}
 		}) }
 	
 	@Test def test_removeInBindings_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
-				sa.inports.forall[p | p.targetdependency === null]
+				Assert.assertTrue(sa.inports.forall[p | p.targetdependency === null])
 			}
 		}) }
 	
 	@Test def test_removeOutBindings_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
-				sa.outports.forall[p | p.sourcedependency === null]
+				Assert.assertTrue(sa.outports.forall[p | p.sourcedependency === null])
 			}
 		}) }
 	
 	@Test def test_addOutParams_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
-				sa.params.head.declarations.filter[p | p.name == "INIT_INNERFMU2__OUTPUT_PORT2"].size == 1
+				Assert.assertTrue(sa.params.head.declarations.filter[p | p.name == "INIT_INNERFMU2__OUTPUT_PORT2"].size == 1)
 			}
 		}) }
 	
@@ -145,40 +147,49 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 	@Test def test_createCoSimStepInstructions_sample2() { __generate('input/canonical_generation/sample2.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()
-				(sa.control.rule as CustomControlRule).controlRulestatements.filter[s | s instanceof Declaration].size>4
+				Assert.assertTrue((sa.control.rule as CustomControlRule).controlRulestatements.filter[s | s instanceof Declaration].size>4)
 			}
 		}) }
 	
 	@Test def test_createInternalBindingAssignments_sample2() { __generate('input/canonical_generation/sample2.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()
-				(sa.control.rule as CustomControlRule).controlRulestatements.filter[s | s instanceof Assignment].size>4
+				Assert.assertTrue((sa.control.rule as CustomControlRule).controlRulestatements.filter[s | s instanceof Assignment].size>4)
 			}
 		}) }
 	
 	@Test def test_ReplacePortRefs_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
-				noPortRefsLeft(sa)
+				Assert.assertTrue(noPortRefsLeft_LHS(sa))
+			}
+		}) }
+	
+	@Test def test_ReplacePortRefs_windowsa() { __generate('input/power_window_case_study/window_sa.BASE.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(noPortRefsLeft_LHS(sa))
+				val tauAssignment = ((sa.out.rules.head.outputfunction as CompositeOutputFunction).statements.get(1) as Assignment)
+				Assert.assertFalse(((tauAssignment.expr as Neg).right as Variable).ref instanceof Port)
 			}
 		}) }
 	
-	def noPortRefsLeft(Adaptation sa){
+	def noPortRefsLeft_LHS(Adaptation sa){
 		return sa.in.rules.forall[dr | 
-					(dr.outputfunction as CompositeOutputFunction).statements.forall[ s |
-						s.eAllContents.filter[v | v instanceof Variable].forall[ v |
+					(dr.outputfunction as CompositeOutputFunction).statements.filter[s | s instanceof Assignment].forall[ s |
+						(s as Assignment).expr.eAllContents.filter[v | v instanceof Variable].forall[ v |
 							! ((v as Variable).ref instanceof Port)
 						]
 					]
 				] &&
-				(sa.control.rule as CustomControlRule).controlRulestatements.forall[ s |
-					s.eAllContents.filter[v | v instanceof Variable].forall[ v |
+				(sa.control.rule as CustomControlRule).controlRulestatements.filter[s | s instanceof Assignment].forall[ s |
+					(s as Assignment).expr.eAllContents.filter[v | v instanceof Variable].forall[ v |
 						! ((v as Variable).ref instanceof Port)
 					]
 				] && 
 				sa.out.rules.forall[dr | 
-					(dr.outputfunction as CompositeOutputFunction).statements.forall[ s |
-						s.eAllContents.filter[v | v instanceof Variable].forall[ v |
+					(dr.outputfunction as CompositeOutputFunction).statements.filter[s | s instanceof Assignment].forall[ s |
+						(s as Assignment).expr.eAllContents.filter[v | v instanceof Variable].forall[ v |
 							! ((v as Variable).ref instanceof Port)
 						]
 					]
@@ -188,7 +199,7 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 	@Test def test_ReplacePortRefs_sample2() { __generate('input/canonical_generation/sample2.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
-				noPortRefsLeft(sa)
+				noPortRefsLeft_LHS(sa)
 			}
 		}) }
 	

+ 2 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationCanonicalGenerator.xtend

@@ -97,7 +97,6 @@ class SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
 			fsa.generateFile(canonicalFileName, adaptation.serialize_model)
 			Log.println("File " + canonicalFileName + " written.")
 			
-			
 		} else {
 			Log.println("It is already a canonical version.")
 			Log.println("Nothing to do.")
@@ -309,6 +308,8 @@ class SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
 					val varDecl = port2VarDecl.get(v.ref)
 					v.ref = varDecl
 					Log.println("Replaced ref to " + port.qualifiedName + " by " + varDecl.name)
+				} else {
+					Log.println("Var ref not substituted: " + v.ref)
 				}
 			}
 		}