浏览代码

generation of hints, reause loaded fmus, and analytical solution

Claudio Gomes 6 年之前
父节点
当前提交
cfe57f54cc
共有 38 个文件被更改,包括 31415 次插入81 次删除
  1. 2 0
      .gitignore
  2. 1 1
      HintCO/.classpath
  3. 2 5
      HintCO/HintCO.product
  4. 2 1
      HintCO/META-INF/MANIFEST.MF
  5. 30002 0
      HintCO/examples/analytical_solution/LoadNSensor_FixedEuler_1Em6.csv
  6. 12 0
      HintCO/examples/case_study_contract.contractlang
  7. 16 0
      HintCO/examples/case_study_contract.xmi
  8. 1 1
      HintCO/examples/case_study_double_loop.xmi
  9. 12 0
      HintCO/examples/watertanks_ctrl.contractlang
  10. 16 0
      HintCO/examples/watertanks_ctrl.xmi
  11. 12 0
      HintCO/instances/case_study_contract.contractlang
  12. 16 0
      HintCO/instances/case_study_contract.xmi
  13. 161 0
      HintCO/instances/case_study_double_loop.xmi
  14. 46 0
      HintCO/instances/duplicate_unit_test.xmi
  15. 100 0
      HintCO/instances/watertanks.xmi
  16. 12 0
      HintCO/instances/watertanks_ctrl.contractlang
  17. 16 0
      HintCO/instances/watertanks_ctrl.xmi
  18. 321 0
      HintCO/model/ContractLang.ecore
  19. 269 0
      HintCO/model/ContractLang.genmodel
  20. 2 2
      HintCO/plugin.xml
  21. 6 5
      HintCO/scripts/plot_results.py
  22. 1 1
      HintCO/src/ua/ansymo/hintco/AdaptedFMUInstance.xtend
  23. 130 40
      HintCO/src/ua/ansymo/hintco/CandidateSpaceGenerator.xtend
  24. 13 5
      HintCO/src/ua/ansymo/hintco/CosimRunner.xtend
  25. 1 0
      HintCO/src/ua/ansymo/hintco/FmuInstance.xtend
  26. 33 9
      HintCO/src/ua/ansymo/hintco/Main.xtend
  27. 17 0
      HintCO/src/ua/ansymo/hintco/ModelStorage.xtend
  28. 14 2
      HintCO/src/ua/ansymo/hintco/OutputProcessor.xtend
  29. 9 5
      HintCO/test/ua/ansymo/hintco/test/AdaptedFMUTest.xtend
  30. 59 2
      HintCO/test/ua/ansymo/hintco/test/CandidateSpaceGeneratorTest.xtend
  31. 23 2
      HintCO/test/ua/ansymo/hintco/test/CosimRunnerTest.xtend
  32. 7 0
      be.uantwerpen.cosys.ContractLang/.classpath
  33. 28 0
      be.uantwerpen.cosys.ContractLang/.project
  34. 7 0
      be.uantwerpen.cosys.ContractLang/.settings/org.eclipse.jdt.core.prefs
  35. 16 0
      be.uantwerpen.cosys.ContractLang/META-INF/MANIFEST.MF
  36. 9 0
      be.uantwerpen.cosys.ContractLang/build.properties
  37. 4 0
      be.uantwerpen.cosys.ContractLang/plugin.properties
  38. 17 0
      be.uantwerpen.cosys.ContractLang/plugin.xml

+ 2 - 0
.gitignore

@@ -9,3 +9,5 @@
 # ---> Needed for Maven build
 #/HintCO/src-gen/
 
+/HintCO/output/
+/be.uantwerpen.cosys.ContractLang/src-gen/

+ 1 - 1
HintCO/.classpath

@@ -6,7 +6,7 @@
 	<classpathentry kind="src" path="test"/>
 	<classpathentry kind="src" output="target/test-classes" path="target/test-xtend-gen"/>
 	<classpathentry kind="src" path="target/xtend-gen"/>
-	<classpathentry kind="lib" path="lib/opencsv-4.3.2.jar"/>
+	<classpathentry kind="lib" path="lib/opencsv-4.3.2.jar" sourcepath="lib/opencsv-source.zip"/>
 	<classpathentry kind="lib" path="lib/commons-lang3-3.8.1.jar" sourcepath="lib/commons-cli-1.4-sources.jar"/>
 	<classpathentry kind="lib" path="lib/commons-beanutils-1.9.3.jar" sourcepath="lib/commons-beanutils-1.9.3-sources.jar"/>
 	<classpathentry kind="lib" path="lib/commons-cli-1.4.jar" sourcepath="lib/commons-cli-1.4-sources.jar"/>

+ 2 - 5
HintCO/HintCO.product

@@ -1,8 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?pde version="3.5"?>
 
-<product name="HintCO" uid="HintCO" id="ua.ansymo.HintCO.product" application="ua.ansymo.hinco" version="0.0.1" useFeatures="false" includeLaunchers="true">
-
+<product name="HintCO" uid="HintCO" id="ua.ansymo.HintCO.product" application="ua.ansymo.hintco" version="0.0.1" useFeatures="false" includeLaunchers="true">
 
    <configIni use="default">
    </configIni>
@@ -16,19 +15,17 @@
 
    <windowImages/>
 
-
    <launcher name="hintco">
       <win useIco="false">
          <bmp/>
       </win>
    </launcher>
 
-
    <vm>
    </vm>
 
-
    <plugins>
+      <plugin id="be.uantwerpen.cosys.ContractLang"/>
       <plugin id="com.google.guava"/>
       <plugin id="javax.xml"/>
       <plugin id="org.eclipse.core.contenttype"/>

+ 2 - 1
HintCO/META-INF/MANIFEST.MF

@@ -28,5 +28,6 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.14.0",
  org.eclipse.xtext.xbase.lib,
  org.eclipse.emf.ecore.xcore.lib,
  org.junit;bundle-version="4.12.0",
- org.eclipse.emf.ecore.xmi;bundle-version="2.14.0"
+ org.eclipse.emf.ecore.xmi;bundle-version="2.14.0",
+ be.uantwerpen.cosys.ContractLang;bundle-version="1.0.0"
 Bundle-ActivationPolicy: lazy

文件差异内容过多而无法显示
+ 30002 - 0
HintCO/examples/analytical_solution/LoadNSensor_FixedEuler_1Em6.csv


+ 12 - 0
HintCO/examples/case_study_contract.contractlang

@@ -0,0 +1,12 @@
+Root ContractSet "example" {
+	contracts {
+		Contract controller {
+			description "Software Controller"
+			statements {
+				Property "ctrl" FMUProperty FMUInstance "DLoopController_FixedEuler_1Em6" exec_rate == 100
+			}
+			scope Globally
+			pattern Universality:always-the-case-that "ctrl" holds
+		}
+	}
+}

+ 16 - 0
HintCO/examples/case_study_contract.xmi

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<contractLang:Root xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:contractLang="http://www.uantwerpen.be/cosys/ContractLang">
+  <contractSet name="&quot;example&quot;">
+    <contracts xsi:type="contractLang:Contract" name="controller" description="&quot;Software Controller&quot;">
+      <statements xsi:type="contractLang:Property" name="&quot;ctrl&quot;">
+        <var xsi:type="contractLang:FMUProperty">
+          <fmu signal="&quot;DLoopController_FixedEuler_1Em6&quot;"/>
+        </var>
+        <oper xsi:type="contractLang:Equality"/>
+        <expr xsi:type="contractLang:IntValue" val="100"/>
+      </statements>
+      <scope xsi:type="contractLang:GloballyScope"/>
+      <pattern xsi:type="contractLang:UniversalityPattern" statement="//@contractSet/@contracts.0/@statements.0"/>
+    </contracts>
+  </contractSet>
+</contractLang:Root>

+ 1 - 1
HintCO/examples/case_study_double_loop.xmi

@@ -8,7 +8,7 @@
       identifier="Original"
       stopTime="10.0"
       stepSize="1.0E-5"
-      outputStepSize="0.001">
+      outputStepSize="0.01">
     <cosimunits
         identifier="Scenario"
         declaration="//@csuDeclarations.0">

+ 12 - 0
HintCO/examples/watertanks_ctrl.contractlang

@@ -0,0 +1,12 @@
+Root ContractSet "example" {
+	contracts {
+		Contract controller {
+			description "Software Controller"
+			statements {
+				Property "ctrlRate" FMUProperty FMUInstance "ctrl" exec_rate == 100
+			}
+			scope Globally
+			pattern Universality:always-the-case-that "ctrlRate" holds
+		}
+	}
+}

+ 16 - 0
HintCO/examples/watertanks_ctrl.xmi

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<contractLang:Root xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:contractLang="http://www.uantwerpen.be/cosys/ContractLang">
+  <contractSet name="&quot;example&quot;">
+    <contracts xsi:type="contractLang:Contract" name="controller" description="&quot;Software Controller&quot;">
+      <statements xsi:type="contractLang:Property" name="&quot;ctrlRate&quot;">
+        <var xsi:type="contractLang:FMUProperty">
+          <fmu signal="&quot;ctrl&quot;"/>
+        </var>
+        <oper xsi:type="contractLang:Equality"/>
+        <expr xsi:type="contractLang:IntValue" val="100"/>
+      </statements>
+      <scope xsi:type="contractLang:GloballyScope"/>
+      <pattern xsi:type="contractLang:UniversalityPattern" statement="//@contractSet/@contracts.0/@statements.0"/>
+    </contracts>
+  </contractSet>
+</contractLang:Root>

+ 12 - 0
HintCO/instances/case_study_contract.contractlang

@@ -0,0 +1,12 @@
+Root ContractSet "example" {
+	contracts {
+		Contract controller {
+			description "Software Controller"
+			statements {
+				Property "ctrl" FMUProperty FMUInstance "DLoopController_FixedEuler_1Em6" exec_rate == 100
+			}
+			scope Globally
+			pattern Universality:always-the-case-that "ctrl" holds
+		}
+	}
+}

+ 16 - 0
HintCO/instances/case_study_contract.xmi

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<contractLang:Root xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:contractLang="http://www.uantwerpen.be/cosys/ContractLang">
+  <contractSet name="&quot;example&quot;">
+    <contracts xsi:type="contractLang:Contract" name="controller" description="&quot;Software Controller&quot;">
+      <statements xsi:type="contractLang:Property" name="&quot;ctrl&quot;">
+        <var xsi:type="contractLang:FMUProperty">
+          <fmu signal="&quot;DLoopController_FixedEuler_1Em6&quot;"/>
+        </var>
+        <oper xsi:type="contractLang:Equality"/>
+        <expr xsi:type="contractLang:IntValue" val="100"/>
+      </statements>
+      <scope xsi:type="contractLang:GloballyScope"/>
+      <pattern xsi:type="contractLang:UniversalityPattern" statement="//@contractSet/@contracts.0/@statements.0"/>
+    </contracts>
+  </contractSet>
+</contractLang:Root>

+ 161 - 0
HintCO/instances/case_study_double_loop.xmi

@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="ASCII"?>
+<hintco:Candidates
+    xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:hintco="ua.ansymo.hintco">
+  <candidates
+      identifier="Original"
+      stopTime="10.0"
+      stepSize="1.0E-5"
+      outputStepSize="0.001">
+    <cosimunits
+        identifier="Scenario"
+        declaration="//@csuDeclarations.0">
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="psuvolt"
+          valueTo="//@candidates.0/@cosimunits.2/@ports.1"
+          declaration="//@csuDeclarations.0/@ports.0"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="ref"
+          valueTo="//@candidates.0/@cosimunits.1/@ports.2"
+          declaration="//@csuDeclarations.0/@ports.1"/>
+    </cosimunits>
+    <cosimunits
+        identifier="DLoopController_FixedEuler_1Em6"
+        declaration="//@csuDeclarations.1">
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="VEL_FB@expseu_"
+          declaration="//@csuDeclarations.1/@ports.0"
+          valueFrom="//@candidates.0/@cosimunits.2/@ports.4"/>
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="POS_FB@expseu_"
+          declaration="//@csuDeclarations.1/@ports.1"
+          valueFrom="//@candidates.0/@cosimunits.3/@ports.1"/>
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="REFERENCE@expseu_"
+          declaration="//@csuDeclarations.1/@ports.2"
+          valueFrom="//@candidates.0/@cosimunits.0/@ports.1"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="OUTPUT@expseu_"
+          valueTo="//@candidates.0/@cosimunits.2/@ports.0"
+          declaration="//@csuDeclarations.1/@ports.3"/>
+    </cosimunits>
+    <cosimunits
+        identifier="EMAPlantNoLoad_FixedEuler_1Em6"
+        declaration="//@csuDeclarations.2">
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="torque_input@expseu_"
+          declaration="//@csuDeclarations.2/@ports.0"
+          valueFrom="//@candidates.0/@cosimunits.1/@ports.3"/>
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="psu_vol_input_v@expseu_"
+          declaration="//@csuDeclarations.2/@ports.1"
+          valueFrom="//@candidates.0/@cosimunits.0/@ports.0"/>
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="V_IN@expseu_"
+          declaration="//@csuDeclarations.2/@ports.2"
+          valueFrom="//@candidates.0/@cosimunits.3/@ports.2"/>
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="X_IN@expseu_"
+          declaration="//@csuDeclarations.2/@ports.3"
+          valueFrom="//@candidates.0/@cosimunits.3/@ports.3"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="ang_vel_out_rpm@expseu_"
+          valueTo="//@candidates.0/@cosimunits.1/@ports.0"
+          declaration="//@csuDeclarations.2/@ports.4"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="F_OUT@expseu_"
+          valueTo="//@candidates.0/@cosimunits.3/@ports.0"
+          declaration="//@csuDeclarations.2/@ports.5"/>
+    </cosimunits>
+    <cosimunits
+        identifier="LoadNSensor_FixedEuler_1Em6"
+        declaration="//@csuDeclarations.3">
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="F_INPUT@expseu_"
+          declaration="//@csuDeclarations.3/@ports.0"
+          valueFrom="//@candidates.0/@cosimunits.2/@ports.5"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="X_AFTER_LOAD@expseu_"
+          valueTo="//@candidates.0/@cosimunits.1/@ports.1"
+          declaration="//@csuDeclarations.3/@ports.1"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="V_OUTPUT@expseu_"
+          valueTo="//@candidates.0/@cosimunits.2/@ports.2"
+          declaration="//@csuDeclarations.3/@ports.2"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="X_OUTPUT@expseu_"
+          valueTo="//@candidates.0/@cosimunits.2/@ports.3"
+          declaration="//@csuDeclarations.3/@ports.3"/>
+    </cosimunits>
+  </candidates>
+  <csuDeclarations
+      identifier="Scenario"
+      path="resources/Scenario.fmu"
+      guid="{a174734c-d15f-4ef0-838d-06526230b19e}">
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="psuvolt"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="ref"/>
+  </csuDeclarations>
+  <csuDeclarations
+      identifier="DLoopController_FixedEuler_1Em6"
+      path="resources/DLoopController_FixedEuler_1Em6.fmu"
+      guid="2761528305">
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="VEL_FB@expseu_"/>
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="POS_FB@expseu_"/>
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="REFERENCE@expseu_"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="OUTPUT@expseu_"/>
+  </csuDeclarations>
+  <csuDeclarations
+      identifier="EMAPlantNoLoad_FixedEuler_1Em6"
+      path="resources/EMAPlantNoLoad_FixedEuler_1Em6.fmu"
+      guid="698567049">
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="torque_input@expseu_"/>
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="psu_vol_input_v@expseu_"/>
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="V_IN@expseu_"/>
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="X_IN@expseu_"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="ang_vel_out_rpm@expseu_"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="F_OUT@expseu_"/>
+  </csuDeclarations>
+  <csuDeclarations
+      identifier="LoadNSensor_FixedEuler_1Em6"
+      path="resources/LoadNSensor_FixedEuler_1Em6.fmu"
+      guid="2810456241">
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="F_INPUT@expseu_"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="X_AFTER_LOAD@expseu_"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="V_OUTPUT@expseu_"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="X_OUTPUT@expseu_"/>
+  </csuDeclarations>
+</hintco:Candidates>

+ 46 - 0
HintCO/instances/duplicate_unit_test.xmi

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="ASCII"?>
+<hintco:Candidates
+    xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:hintco="ua.ansymo.hintco">
+  <candidates
+      identifier="Original"
+      stopTime="10.0"
+      stepSize="0.01"
+      outputStepSize="0.01">
+    <cosimunits
+        identifier="wt1"
+        declaration="//@csuDeclarations.0">
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="Tank2WaterLevel"
+          declaration="//@csuDeclarations.0/@ports.0"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="Tank2OutFlow"
+          declaration="//@csuDeclarations.0/@ports.1"/>
+    </cosimunits>
+    <cosimunits
+        identifier="wt2"
+        declaration="//@csuDeclarations.0">
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="Tank2WaterLevel"
+          declaration="//@csuDeclarations.0/@ports.0"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="Tank2OutFlow"
+          declaration="//@csuDeclarations.0/@ports.1"/>
+    </cosimunits>
+  </candidates>
+  <csuDeclarations
+      identifier="threewatertank1"
+      path="resources/threewatertank1.fmu"
+      guid="{dcd729ec-423a-4a0d-8030-4c42a840abba}">
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="Tank2WaterLevel"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="Tank2OutFlow"/>
+  </csuDeclarations>
+</hintco:Candidates>

+ 100 - 0
HintCO/instances/watertanks.xmi

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="ASCII"?>
+<hintco:Candidates
+    xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:hintco="ua.ansymo.hintco">
+  <candidates
+      identifier="Original"
+      stopTime="10.0"
+      stepSize="0.01"
+      outputStepSize="0.01">
+    <cosimunits
+        identifier="ctrl"
+        declaration="//@csuDeclarations.0">
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="wt3_level"
+          declaration="//@csuDeclarations.0/@ports.0"
+          valueFrom="//@candidates.0/@cosimunits.2/@ports.2"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="wt3_valve"
+          valueTo="//@candidates.0/@cosimunits.2/@ports.4"
+          declaration="//@csuDeclarations.0/@ports.1"/>
+    </cosimunits>
+    <cosimunits
+        identifier="wt1"
+        declaration="//@csuDeclarations.1">
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="Tank2WaterLevel"
+          declaration="//@csuDeclarations.1/@ports.0"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="Tank2OutFlow"
+          valueTo="//@candidates.0/@cosimunits.2/@ports.3"
+          declaration="//@csuDeclarations.1/@ports.1"/>
+    </cosimunits>
+    <cosimunits
+        identifier="wt2"
+        declaration="//@csuDeclarations.2">
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="puddle"
+          declaration="//@csuDeclarations.2/@ports.0"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="Tank3OutFlow"
+          declaration="//@csuDeclarations.2/@ports.2"/>
+      <ports
+          xsi:type="hintco:OutputPortInstance"
+          identifier="level"
+          valueTo="//@candidates.0/@cosimunits.0/@ports.0"
+          declaration="//@csuDeclarations.2/@ports.4"/>
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="inFlow"
+          declaration="//@csuDeclarations.2/@ports.1"
+          valueFrom="//@candidates.0/@cosimunits.1/@ports.1"/>
+      <ports
+          xsi:type="hintco:InputPortInstance"
+          identifier="valveControl"
+          declaration="//@csuDeclarations.2/@ports.3"
+          valueFrom="//@candidates.0/@cosimunits.0/@ports.1"/>
+    </cosimunits>
+  </candidates>
+  <csuDeclarations
+      identifier="threewatertankcontroller2"
+      path="resources/threewatertankcontroller2.fmu"
+      guid="{8c4e810f-3df3-4a00-8276-176fa3c9f003}">
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="wt3_level"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="wt3_valve"/>
+  </csuDeclarations>
+  <csuDeclarations
+      identifier="threewatertank1"
+      path="resources/threewatertank1.fmu"
+      guid="{dcd729ec-423a-4a0d-8030-4c42a840abba}">
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="Tank2WaterLevel"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="Tank2OutFlow"/>
+  </csuDeclarations>
+  <csuDeclarations
+      identifier="threewatertank2"
+      path="resources/threewatertank2.fmu"
+      guid="{25941611-1350-4ca2-8fe8-85d9193c14fd}">
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="puddle"/>
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="inFlow"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="Tank3OutFlow"/>
+    <ports xsi:type="hintco:InputPortDeclaration"
+        identifier="valveControl"/>
+    <ports xsi:type="hintco:OutputPortDeclaration"
+        identifier="level"/>
+  </csuDeclarations>
+</hintco:Candidates>

+ 12 - 0
HintCO/instances/watertanks_ctrl.contractlang

@@ -0,0 +1,12 @@
+Root ContractSet "example" {
+	contracts {
+		Contract controller {
+			description "Software Controller"
+			statements {
+				Property "ctrlRate" FMUProperty FMUInstance "ctrl" exec_rate == 100
+			}
+			scope Globally
+			pattern Universality:always-the-case-that "ctrlRate" holds
+		}
+	}
+}

+ 16 - 0
HintCO/instances/watertanks_ctrl.xmi

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<contractLang:Root xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:contractLang="http://www.uantwerpen.be/cosys/ContractLang">
+  <contractSet name="&quot;example&quot;">
+    <contracts xsi:type="contractLang:Contract" name="controller" description="&quot;Software Controller&quot;">
+      <statements xsi:type="contractLang:Property" name="&quot;ctrlRate&quot;">
+        <var xsi:type="contractLang:FMUProperty">
+          <fmu signal="&quot;ctrl&quot;"/>
+        </var>
+        <oper xsi:type="contractLang:Equality"/>
+        <expr xsi:type="contractLang:IntValue" val="100"/>
+      </statements>
+      <scope xsi:type="contractLang:GloballyScope"/>
+      <pattern xsi:type="contractLang:UniversalityPattern" statement="//@contractSet/@contracts.0/@statements.0"/>
+    </contracts>
+  </contractSet>
+</contractLang:Root>

+ 321 - 0
HintCO/model/ContractLang.ecore

@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="contractLang" nsURI="http://www.uantwerpen.be/cosys/ContractLang"
+    nsPrefix="contractLang">
+  <eClassifiers xsi:type="ecore:EClass" name="Root">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="contract" eType="#//Contract"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="contractSet" eType="#//ContractSet"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ContractSet">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="contracts" upperBound="-1"
+        eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ContractRef">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="contract" eType="#//Contract"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Contract">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statements" upperBound="-1"
+        eType="#//Statement" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="scope" eType="#//Scope"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="pattern" eType="#//Pattern"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="action" eType="#//Action"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Event" eSuperTypes="#//Statement"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Property" eSuperTypes="#//Statement"/>
+  <eClassifiers xsi:type="ecore:EClass" name="MetaStatement"/>
+  <eClassifiers xsi:type="ecore:EClass" name="StatementRef" eSuperTypes="#//MetaStatement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement" eType="#//Statement"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Statement">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="var" eType="#//VarOrVarOp"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="oper" eType="#//Operator"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="expr" eType="#//Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="StatementOp" eSuperTypes="#//MetaStatement"/>
+  <eClassifiers xsi:type="ecore:EClass" name="StatementAnd" eSuperTypes="#//StatementOp">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement1" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement2" eType="#//MetaStatement"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="StatementOr" eSuperTypes="#//StatementOp">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement1" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement2" eType="#//MetaStatement"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="StatementNot" eSuperTypes="#//StatementOp">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement" eType="#//MetaStatement"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Scope"/>
+  <eClassifiers xsi:type="ecore:EClass" name="GloballyScope" eSuperTypes="#//Scope"/>
+  <eClassifiers xsi:type="ecore:EClass" name="BeforeScope" eSuperTypes="#//Scope">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="event" eType="#//Event"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="AfterScope" eSuperTypes="#//Scope">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="event" eType="#//Event"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="BetweenScope" eSuperTypes="#//Scope">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//Event"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//Event"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="AfterUntilScope" eSuperTypes="#//Scope">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//Event"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//Event"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Pattern">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="prob" eType="#//Probability"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Occurrence" eSuperTypes="#//Pattern">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement" eType="#//Statement"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="UniversalityPattern" eSuperTypes="#//Occurrence">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="AbsencePattern" eSuperTypes="#//Occurrence">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ExistencePattern" eSuperTypes="#//Occurrence">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="BoundedExistencePattern" eSuperTypes="#//Occurrence">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="n" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="TransientStatePattern" eSuperTypes="#//Occurrence">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//SingleTime"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="SteadyStatePattern" eSuperTypes="#//Occurrence"/>
+  <eClassifiers xsi:type="ecore:EClass" name="MinDurationPattern" eSuperTypes="#//Occurrence">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="duration" eType="#//SingleTime"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="MaxDurationPattern" eSuperTypes="#//Occurrence">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="duration" eType="#//SingleTime"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Recurrence" eSuperTypes="#//Occurrence">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//SingleTime"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PrecStatement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="constraint" eType="#//Constraint"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Order" eSuperTypes="#//Pattern"/>
+  <eClassifiers xsi:type="ecore:EClass" name="PrecedencePattern" eSuperTypes="#//Order">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//MetaStatement"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//MetaStatement"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="interval" eType="#//Interval"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PrecedenceChain1NPattern" eSuperTypes="#//Order">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//MetaStatement"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statements" unique="false"
+        upperBound="-1" eType="#//PrecStatement"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//MetaStatement"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="interval" eType="#//Interval"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="constraint" eType="#//Constraint"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="UntilPattern" eSuperTypes="#//Order">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//MetaStatement"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//MetaStatement"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ResponsePattern" eSuperTypes="#//Order">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="constraint" eType="#//Constraint"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ResponseChain1NPattern" eSuperTypes="#//Order">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="constraint" eType="#//Constraint"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statements" unique="false"
+        upperBound="-1" eType="#//PrecStatement"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ResponseChainN1Pattern" eSuperTypes="#//Order">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statements" unique="false"
+        upperBound="-1" eType="#//PrecStatement"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="constraint" eType="#//Constraint"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ResponseInvariancePattern" eSuperTypes="#//Order">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="first" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="second" eType="#//MetaStatement"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="time" eType="#//Time" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Constraint">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="statement" eType="#//Statement"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Time">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="unit" eType="#//TimeUnit"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="TimeInterval" eSuperTypes="#//Time">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="min" eType="#//NumValue"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="max" eType="#//NumValue"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="closed_min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="closed_max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="UpperTimeBound" eSuperTypes="#//Time">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="val" eType="#//NumValue"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="LowerTimeBound" eSuperTypes="#//Time">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="val" eType="#//NumValue"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="SingleTime" eSuperTypes="#//Time">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="val" eType="#//NumValue"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="TimeUnit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Milliseconds" eSuperTypes="#//TimeUnit #//Unit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Seconds" eSuperTypes="#//TimeUnit #//Unit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Probability">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="prob" eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ProbLess"/>
+  <eClassifiers xsi:type="ecore:EClass" name="ProbLessEq"/>
+  <eClassifiers xsi:type="ecore:EClass" name="ProbGreater"/>
+  <eClassifiers xsi:type="ecore:EClass" name="ProbGreaterEq"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Action"/>
+  <eClassifiers xsi:type="ecore:EClass" name="VarOrVarOp"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Operator"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Expression"/>
+  <eClassifiers xsi:type="ecore:EClass" name="NumValue"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Unit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Derivative" eSuperTypes="#//VarOrVarOp">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="var" eType="#//VarOrVarOp"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="AbsoluteValue" eSuperTypes="#//VarOrVarOp">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="var" eType="#//VarOrVarOp"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Difference" eSuperTypes="#//VarOrVarOp">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="var" eType="#//VarOrVarOp"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="var2" eType="#//VarOrVarOp"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Average" eSuperTypes="#//VarOrVarOp">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="var" eType="#//VarOrVarOp"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="duration" eType="#//SingleTime"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Infinity" eSuperTypes="#//Expression #//NumValue #//Value"/>
+  <eClassifiers xsi:type="ecore:EClass" name="IntValue" eSuperTypes="#//Expression #//NumValue #//Value">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="val" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="FloatValue" eSuperTypes="#//Expression #//NumValue #//Value">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="val" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Equality" eSuperTypes="#//Operator"/>
+  <eClassifiers xsi:type="ecore:EClass" name="GreaterThan" eSuperTypes="#//Operator">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="equalTo" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="LessThan" eSuperTypes="#//Operator">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="equalTo" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="AndExpression" eSuperTypes="#//Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="arg0" eType="#//Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="arg1" eType="#//Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="True" eSuperTypes="#//Expression #//Value"/>
+  <eClassifiers xsi:type="ecore:EClass" name="False" eSuperTypes="#//Expression #//Value"/>
+  <eClassifiers xsi:type="ecore:EClass" name="StringValue" eSuperTypes="#//Expression #//Value">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="val" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="QualValue" eSuperTypes="#//Expression #//Value">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="val" eType="#//LOW_MED_HIGH"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Interval" eSuperTypes="#//Expression">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="closed_min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="closed_max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="min" eType="#//Value" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="max" eType="#//Value" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="unit" eType="#//Unit" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ValueWithUnit" eSuperTypes="#//Expression #//Value">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="val" eType="#//NumValue"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="unit" eType="#//Unit" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="LOW_MED_HIGH">
+    <eLiterals name="NONE" literal="NONE"/>
+    <eLiterals name="LOW" value="1" literal="LOW"/>
+    <eLiterals name="MED" value="2" literal="MED"/>
+    <eLiterals name="HIGH" value="3" literal="HIGH"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Unitless" eSuperTypes="#//Unit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Percentage" eSuperTypes="#//Unit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="AssignAction" eSuperTypes="#//Action">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="var" eType="#//VarOrVarOp"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Value"/>
+  <eClassifiers xsi:type="ecore:EClass" name="DomainValue" eSuperTypes="#//Expression"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Variable" eSuperTypes="#//VarOrVarOp"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Frequency" eSuperTypes="#//Unit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="FMUProperty" eSuperTypes="#//Variable">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="fmu" eType="#//FMUInstance"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="#//FMUPropertyEnum"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="FMUPropertyEnum">
+    <eLiterals name="EXEC_RATE" literal="exec_rate"/>
+    <eLiterals name="IS_PHYSICAL" value="1" literal="is_physical"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="FMUInstance">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="signal" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="FMUSignal" eSuperTypes="#//Variable">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="signal" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="SteadyStateSuggestion" eSuperTypes="#//DomainValue"/>
+  <eClassifiers xsi:type="ecore:EClass" name="MetersPerSecond" eSuperTypes="#//Unit"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Meters" eSuperTypes="#//Unit"/>
+</ecore:EPackage>

+ 269 - 0
HintCO/model/ContractLang.genmodel

@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" copyrightText="generated by Xtext 2.16.0" modelDirectory="/be.uantwerpen.cosys.ContractLang/src-gen"
+    modelPluginID="be.uantwerpen.cosys.ContractLang" forceOverwrite="true" modelName="ContractLang"
+    updateClasspath="false" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container"
+    complianceLevel="6.0" copyrightFields="false" runtimeVersion="2.16">
+  <genPackages prefix="ContractLang" basePackage="be.uantwerpen.cosys" disposableProviderFactory="true"
+      fileExtensions="contractlang" ecorePackage="ContractLang.ecore#/">
+    <genEnums typeSafeEnumCompatible="false" ecoreEnum="ContractLang.ecore#//LOW_MED_HIGH">
+      <genEnumLiterals ecoreEnumLiteral="ContractLang.ecore#//LOW_MED_HIGH/NONE"/>
+      <genEnumLiterals ecoreEnumLiteral="ContractLang.ecore#//LOW_MED_HIGH/LOW"/>
+      <genEnumLiterals ecoreEnumLiteral="ContractLang.ecore#//LOW_MED_HIGH/MED"/>
+      <genEnumLiterals ecoreEnumLiteral="ContractLang.ecore#//LOW_MED_HIGH/HIGH"/>
+    </genEnums>
+    <genEnums typeSafeEnumCompatible="false" ecoreEnum="ContractLang.ecore#//FMUPropertyEnum">
+      <genEnumLiterals ecoreEnumLiteral="ContractLang.ecore#//FMUPropertyEnum/EXEC_RATE"/>
+      <genEnumLiterals ecoreEnumLiteral="ContractLang.ecore#//FMUPropertyEnum/IS_PHYSICAL"/>
+    </genEnums>
+    <genClasses ecoreClass="ContractLang.ecore#//Root">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Root/contract"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Root/contractSet"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ContractSet">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//ContractSet/name"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ContractSet/contracts"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ContractRef">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ContractRef/contract"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Contract">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//Contract/name"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//Contract/description"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Contract/statements"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Contract/scope"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Contract/pattern"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Contract/action"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Event"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Property"/>
+    <genClasses ecoreClass="ContractLang.ecore#//MetaStatement"/>
+    <genClasses ecoreClass="ContractLang.ecore#//StatementRef">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//StatementRef/statement"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Statement">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//Statement/name"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Statement/var"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Statement/oper"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Statement/expr"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//StatementOp"/>
+    <genClasses ecoreClass="ContractLang.ecore#//StatementAnd">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//StatementAnd/statement1"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//StatementAnd/statement2"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//StatementOr">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//StatementOr/statement1"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//StatementOr/statement2"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//StatementNot">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//StatementNot/statement"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Scope"/>
+    <genClasses ecoreClass="ContractLang.ecore#//GloballyScope"/>
+    <genClasses ecoreClass="ContractLang.ecore#//BeforeScope">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//BeforeScope/event"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//AfterScope">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//AfterScope/event"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//BetweenScope">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//BetweenScope/first"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//BetweenScope/second"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//AfterUntilScope">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//AfterUntilScope/first"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//AfterUntilScope/second"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Pattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Pattern/prob"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Occurrence">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Occurrence/statement"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//UniversalityPattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//UniversalityPattern/time"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//AbsencePattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//AbsencePattern/time"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ExistencePattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ExistencePattern/time"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//BoundedExistencePattern">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//BoundedExistencePattern/n"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//BoundedExistencePattern/time"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//TransientStatePattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//TransientStatePattern/time"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//SteadyStatePattern"/>
+    <genClasses ecoreClass="ContractLang.ecore#//MinDurationPattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//MinDurationPattern/duration"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//MaxDurationPattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//MaxDurationPattern/duration"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Recurrence">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Recurrence/time"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//PrecStatement">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecStatement/statement"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecStatement/time"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecStatement/constraint"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Order"/>
+    <genClasses ecoreClass="ContractLang.ecore#//PrecedencePattern">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecedencePattern/first"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecedencePattern/second"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecedencePattern/interval"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//PrecedenceChain1NPattern">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecedenceChain1NPattern/second"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecedenceChain1NPattern/statements"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecedenceChain1NPattern/first"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecedenceChain1NPattern/interval"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//PrecedenceChain1NPattern/constraint"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//UntilPattern">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//UntilPattern/first"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//UntilPattern/second"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//UntilPattern/time"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ResponsePattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponsePattern/first"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponsePattern/second"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponsePattern/time"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponsePattern/constraint"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ResponseChain1NPattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChain1NPattern/first"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChain1NPattern/second"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChain1NPattern/time"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChain1NPattern/constraint"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChain1NPattern/statements"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ResponseChainN1Pattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChainN1Pattern/second"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChainN1Pattern/statements"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChainN1Pattern/first"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChainN1Pattern/time"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseChainN1Pattern/constraint"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ResponseInvariancePattern">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseInvariancePattern/first"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseInvariancePattern/second"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ResponseInvariancePattern/time"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Constraint">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Constraint/statement"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Time">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Time/unit"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//TimeInterval">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//TimeInterval/min"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//TimeInterval/max"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//TimeInterval/closed_min"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//TimeInterval/closed_max"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//UpperTimeBound">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//UpperTimeBound/val"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//LowerTimeBound">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//LowerTimeBound/val"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//SingleTime">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//SingleTime/val"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//TimeUnit"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Milliseconds"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Seconds"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Probability">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Probability/prob"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ProbLess"/>
+    <genClasses ecoreClass="ContractLang.ecore#//ProbLessEq"/>
+    <genClasses ecoreClass="ContractLang.ecore#//ProbGreater"/>
+    <genClasses ecoreClass="ContractLang.ecore#//ProbGreaterEq"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Action"/>
+    <genClasses ecoreClass="ContractLang.ecore#//VarOrVarOp"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Operator"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Expression"/>
+    <genClasses ecoreClass="ContractLang.ecore#//NumValue"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Unit"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Derivative">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Derivative/var"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//AbsoluteValue">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//AbsoluteValue/var"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Difference">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Difference/var"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Difference/var2"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Average">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Average/var"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Average/duration"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Infinity"/>
+    <genClasses ecoreClass="ContractLang.ecore#//IntValue">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//IntValue/val"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//FloatValue">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//FloatValue/val"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Equality"/>
+    <genClasses ecoreClass="ContractLang.ecore#//GreaterThan">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//GreaterThan/equalTo"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//LessThan">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//LessThan/equalTo"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//AndExpression">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//AndExpression/arg0"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//AndExpression/arg1"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//True"/>
+    <genClasses ecoreClass="ContractLang.ecore#//False"/>
+    <genClasses ecoreClass="ContractLang.ecore#//StringValue">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//StringValue/val"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//QualValue">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//QualValue/val"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Interval">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//Interval/closed_min"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//Interval/closed_max"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Interval/min"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Interval/max"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//Interval/unit"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//ValueWithUnit">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ValueWithUnit/val"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//ValueWithUnit/unit"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Unitless"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Percentage"/>
+    <genClasses ecoreClass="ContractLang.ecore#//AssignAction">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//AssignAction/var"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//Value"/>
+    <genClasses ecoreClass="ContractLang.ecore#//DomainValue"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Variable"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Frequency"/>
+    <genClasses ecoreClass="ContractLang.ecore#//FMUProperty">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ContractLang.ecore#//FMUProperty/fmu"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//FMUProperty/property"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//FMUInstance">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//FMUInstance/signal"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//FMUSignal">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute ContractLang.ecore#//FMUSignal/signal"/>
+    </genClasses>
+    <genClasses ecoreClass="ContractLang.ecore#//SteadyStateSuggestion"/>
+    <genClasses ecoreClass="ContractLang.ecore#//MetersPerSecond"/>
+    <genClasses ecoreClass="ContractLang.ecore#//Meters"/>
+  </genPackages>
+</genmodel:GenModel>

+ 2 - 2
HintCO/plugin.xml

@@ -2,7 +2,7 @@
 <?eclipse version="3.4"?>
 <plugin>
    <extension
-         id="ua.ansymo.hinco"
+         id="ua.ansymo.hintco"
          name="HintCO"
          point="org.eclipse.core.runtime.applications">
       <application
@@ -27,7 +27,7 @@
          name="HintCO"
          point="org.eclipse.core.runtime.products">
       <product
-            application="ua.ansymo.hinco"
+            application="ua.ansymo.hintco"
             name="HintCO">
          <property
                name="HintCO"

+ 6 - 5
HintCO/scripts/plot_results.py

@@ -32,11 +32,12 @@ def selectTime(raw_data, maxTime):
 def get_all_csvs(results_folder):
     results = []
     directory = os.fsencode(results_folder)
-    for file in os.listdir(directory):
-        filename = os.fsdecode(file)
-        if filename.endswith(".csv"):
-            filepath = os.path.join(results_folder, filename)
-            results.append((filename, filepath))
+    for root, dirs, files in os.walk(directory):
+        for file in files:
+            filename = os.fsdecode(file)
+            if filename.endswith(".csv"):
+                filepath = os.fsdecode(os.path.join(root,file))
+                results.append((filename, filepath))
     return results
             
 def plot_results(results_folder, analyticalSolutionDir):

+ 1 - 1
HintCO/src/ua/ansymo/hintco/AdaptedFMUInstance.xtend

@@ -19,7 +19,7 @@ class AdaptedFMUInstance extends FmuInstance {
 		// Check if unit has a multi-rate adaptation
 		val unitAdaptation = unit.selectedAdaptation
 		if (unitAdaptation !== null && unitAdaptation instanceof MultiRateAdaptation){
-			innerRate = (unit.adaptation as MultiRateAdaptation).rate
+			innerRate = (unitAdaptation as MultiRateAdaptation).rate
 		}
 		
 		// Instantiate each adaptation input port of the unit.

+ 130 - 40
HintCO/src/ua/ansymo/hintco/CandidateSpaceGenerator.xtend

@@ -1,6 +1,13 @@
 package ua.ansymo.hintco
 
+import be.uantwerpen.cosys.contractLang.ContractSet
+import be.uantwerpen.cosys.contractLang.FMUProperty
+import be.uantwerpen.cosys.contractLang.FMUPropertyEnum
+import be.uantwerpen.cosys.contractLang.IntValue
+import be.uantwerpen.cosys.contractLang.Property
 import org.eclipse.core.runtime.Assert
+import java.util.List
+import org.eclipse.emf.ecore.util.EcoreUtil
 
 /*
  * Main purpose: take a hint model, and generate a candidate model that we assume will best implement the hints.
@@ -36,9 +43,69 @@ class CandidateSpaceGenerator {
 		cs.candidates.add(defaultScenario)
 	}
 	
-	def createCandidateSpace(Object hints, Candidates cs){
-		// TODO
-		return HintcoFactory.eINSTANCE.createCandidates()
+	def createCandidateSpace(ContractSet hints, Candidates cs){
+		
+		// Assume that there are no adaptations
+		Assert.isTrue(cs.eAllContents.filter(Adaptation).empty)
+		
+		// For now, execute each candidate handler in sequence.
+		// In the future, we might want to refactor this to include conflict resolution, etc...
+		handleSoftwareHints(hints, cs)
+		
+		return cs
+	}
+	
+	def handleSoftwareHints(ContractSet hints, Candidates cs) {
+		/*
+		 * Assumes that there is only one software controller fmu.
+		 * Creates a new candidate scenario, duplicate of the previous one, with higher weight.
+		 * Then sets the scenario step size to the frequency of the software controller.
+		 * Then sets every other fmu to a higher rate, giving preference to interpolations over extrapolations.
+		 */
+	 	if (!(hints.eAllContents.filter(FMUProperty).filter[p | p.property === FMUPropertyEnum.EXEC_RATE].size == 1)){
+	 		return 
+	 	}
+		
+	 	Assert.isNotNull(cs.candidates.head)
+	 	
+	 	val prop = hints.eAllContents
+	 						.filter(Property)
+	 						.findFirst[p |
+	 							val v = p.^var
+	 							if (v instanceof FMUProperty){
+		 							v.property == FMUPropertyEnum.EXEC_RATE &&
+		 							p.expr instanceof IntValue
+	 							} else {
+	 								false
+	 							}
+	 						]
+	 						
+//		val scenario = duplicateScenario(cs.candidates.head)
+//		cs.candidates.add(scenario)
+//		val maxScenarioWeight = cs.candidates.map[c | c.weight].max
+//		scenario.weight = maxScenarioWeight + 1
+		val scenario = cs.candidates.head
+		
+		val hz = (prop.expr as IntValue).^val
+		
+		scenario.stepSize = 1.0/hz
+		
+		val ctrlUnitName = (prop.^var as FMUProperty).fmu.signal.stripQuotes
+		val ctrlUnit = scenario.cosimunits.findFirst[u | u.identifier == ctrlUnitName]
+		Assert.isNotNull(ctrlUnit, "Contracts refers to a non existing unit: " + ctrlUnitName)
+		val otherUnits = scenario.cosimunits.filter[u | u.identifier != ctrlUnitName]
+		for (otherUnit : otherUnits) {
+			createDefaultInPortsApproximations(otherUnit, #[10, 100])
+		}
+	}
+	
+	def stripQuotes(String string) {
+		string.subSequence(1, string.length-1)
+	}
+	
+	def duplicateScenario(CandidateScenario scenario) {
+		val newScenario = EcoreUtil.copy(scenario)
+		return newScenario
 	}
 	
 	def createDefaultCandidateSpace(Candidates cs) {
@@ -55,44 +122,8 @@ class CandidateSpaceGenerator {
 		
 		val scenario = cs.candidates.head
 		
-		val f = HintcoFactory.eINSTANCE
-		
 		for (unit : scenario.cosimunits) {
-			
-			// Add multi-rate adaptation
-			val mr = f.createMultiRateAdaptation
-			unit.adaptation = mr
-			mr.rate = 10
-			
-			val inPorts = unit.ports.filter(InputPortInstance)
-			for (inPort : inPorts) {
-				val xor = f.createXorAdaptation()
-				inPort.adaptation = xor
-				val extra = f.createExtrapolationAdaptation()
-				xor.children.add(extra)
-				extra.weight = 0
-				val intra = f.createInterpolationAdaptation()
-				xor.children.add(intra)
-				extra.weight = 10
-			}
-			// Add implies constraints
-			val intraAdaptations = unit.eAllContents.filter(InterpolationAdaptation).toList
-			val extraAdaptations = unit.eAllContents.filter(ExtrapolationAdaptation).toList
-			val sI = intraAdaptations.size
-			val sE = extraAdaptations.size
-			Assert.isTrue(sI === sE)
-			for (aS : intraAdaptations){
-				for (aT : intraAdaptations){
-					aS.implies.add(aT)
-				}
-				aS.implies.add(unit.adaptation)
-			}
-			for (aS : extraAdaptations){
-				for (aT : extraAdaptations){
-					aS.implies.add(aT)
-				}
-				aS.implies.add(unit.adaptation)
-			}
+			createDefaultInPortsApproximations(unit, #[10])
 		}
 		
 		Assert.isTrue(cs.eAllContents.filter(CosimUnitInstance).forall[u | 
@@ -107,4 +138,63 @@ class CandidateSpaceGenerator {
 		return cs
 	}
 	
+	def createDefaultInPortsApproximations(CosimUnitInstance unit, List<Integer> rates) {
+		val f = HintcoFactory.eINSTANCE
+		
+		// Add multi-rate adaptation
+		{
+			if (rates.size == 1){
+				val mr = f.createMultiRateAdaptation
+				unit.adaptation = mr
+				mr.rate = 10				
+			} else {
+				val xor = f.createXorAdaptation()
+				unit.adaptation = xor
+				for (r : rates){
+					val mr = f.createMultiRateAdaptation
+					xor.children.add(mr)
+					mr.rate = r	
+				}
+			}
+		}
+		{
+			val inPorts = unit.ports.filter(InputPortInstance)
+			for (inPort : inPorts) {
+				val xor = f.createXorAdaptation()
+				inPort.adaptation = xor
+				{
+					val extra = f.createExtrapolationAdaptation()
+					xor.children.add(extra)
+					extra.weight = 0
+					extra.order = 1
+				}
+				{
+					val intra = f.createInterpolationAdaptation()
+					xor.children.add(intra)
+					intra.weight = 10
+					intra.order = 1
+				}
+			}
+		}
+		
+		// Add implies constraints
+		val intraAdaptations = unit.eAllContents.filter(InterpolationAdaptation).toList
+		val extraAdaptations = unit.eAllContents.filter(ExtrapolationAdaptation).toList
+		val sI = intraAdaptations.size
+		val sE = extraAdaptations.size
+		Assert.isTrue(sI === sE)
+		for (aS : intraAdaptations){
+			for (aT : intraAdaptations){
+				aS.implies.add(aT)
+			}
+			aS.implies.add(unit.adaptation)
+		}
+		for (aS : extraAdaptations){
+			for (aT : extraAdaptations){
+				aS.implies.add(aT)
+			}
+			aS.implies.add(unit.adaptation)
+		}
+	}
+	
 }

+ 13 - 5
HintCO/src/ua/ansymo/hintco/CosimRunner.xtend

@@ -1,9 +1,12 @@
 package ua.ansymo.hintco
 
+import java.io.Closeable
+import java.io.IOException
 import java.util.HashMap
 import java.util.LinkedList
+import org.eclipse.core.runtime.Assert
 
-class CosimRunner implements ICosimRunner {
+class CosimRunner implements ICosimRunner, Closeable {
 	
 	val HashMap<CosimUnitInstance, IFmuInstance> fmuInstanceMap = newHashMap()
 	
@@ -17,12 +20,14 @@ class CosimRunner implements ICosimRunner {
 	}
 	
 	override run(CandidateScenario scenario, LinkedList<PrecendenceNode> nodes, String variantID) {
-		val units = nodes.filter(CosimUnitInstance)
+		Assert.isTrue(nodes.forall[n1 | scenario.eAllContents.exists[n2 | n1===n2]])
+		
+		val units = nodes.filter(CosimUnitInstance).toList
 		
 		// Instantiate each fmu, and record the instance reference.
 		for (unit : units) {
 			val fmuInstance = fmuLoader.instantiate(unit)
-
+			
 			fmuInstance.setupExperiment()
 			
 			// TODO Set the configured parameter values.
@@ -36,7 +41,7 @@ class CosimRunner implements ICosimRunner {
 		// Fixpoint initial values, by following the same order of get.values as specified in nodes.
 		// Uses a map to store the previous value of each output. Then, whenever a new value of that output is obtained, checks if is the same as the previous value.
 		val outVals = newHashMap()
-		val outputPorts = nodes.filter(OutputPortInstance)
+		val outputPorts = nodes.filter(OutputPortInstance).toList
 		// Initialize
 		for (out : outputPorts){
 			outVals.put(out, Double.POSITIVE_INFINITY)
@@ -111,7 +116,7 @@ class CosimRunner implements ICosimRunner {
 			// Commit outputs
 			// Record all outputs at time time.
 			// Note that the values in outVals might not be all in time time because getOutputs can be invoked before doStep of the same fmu.
-			for (n : nodes.filter(OutputPortInstance)) {
+			for (n : outputPorts) {
 				// Record outputs
 				val outV = fmuInstanceMap.get(n.unit).getReal(n.identifier)
 				outVals.put(n, outV)
@@ -124,6 +129,9 @@ class CosimRunner implements ICosimRunner {
 		for (unit : units) {
 			fmuInstanceMap.get(unit).free()
 		}
+	}
+	
+	override close() throws IOException {
 		fmuLoader.free()
 	}
 	

+ 1 - 0
HintCO/src/ua/ansymo/hintco/FmuInstance.xtend

@@ -44,6 +44,7 @@ class FmuInstance implements IFmuInstance  {
 	override getReal(String varName) {
 		val res = f.getReal(#[varsByName.get(varName).valueReference])
 		Assert.isTrue(res.status == Fmi2Status.OK)
+		Assert.isTrue(!res.result.empty)
 		return res.result.head
 	}
 	

+ 33 - 9
HintCO/src/ua/ansymo/hintco/Main.xtend

@@ -11,6 +11,7 @@ import org.eclipse.core.runtime.Assert
 import org.eclipse.equinox.app.IApplication
 import org.eclipse.equinox.app.IApplicationContext
 import org.intocps.fmi.jnifmuapi.Factory
+import java.io.File
 
 class Main implements IApplication {
 	
@@ -25,13 +26,15 @@ class Main implements IApplication {
 		
 		val helpOpt = Option.builder("h").longOpt("help").desc("Show this description").build();
 		val scenarioOpt = Option.builder("s").longOpt("scenario").desc("Path to scenario file").hasArg().numberOfArgs(1).argName("path").build();
+		val contractOpt = Option.builder("c").longOpt("contract").desc("Path to contracts file").hasArg().numberOfArgs(1).argName("path").build();
 		val genDefAdaptations = Option.builder("d").longOpt("default").desc("Generate default adaptations").build();
 		val outDirOpt = Option.builder("o").longOpt("output").desc("Path to output directory").hasArg().numberOfArgs(1).argName("path").build();
 		val nVarsOpt = Option.builder("n").longOpt("variants").desc("Number of variants to run").hasArg().numberOfArgs(1).argName("int").build();
 		
-		val options = new Options();
-		options.addOption(helpOpt);
+		val options = new Options()
+		options.addOption(helpOpt)
 		options.addOption(scenarioOpt)
+		options.addOption(contractOpt)
 		options.addOption(genDefAdaptations)
 		options.addOption(outDirOpt)
 		options.addOption(nVarsOpt)
@@ -41,9 +44,9 @@ class Main implements IApplication {
 		try
 		{
 			cmd = parser.parse(options, args);
-		} catch (ParseException e1)
+		} catch (ParseException e)
 		{
-			System.err.println("Parsing failed. Reason: " + e1.getMessage());
+			System.err.println("Parsing failed. Reason: " + e.getMessage());
 			showHelp(options);
 			return IApplication.EXIT_OK
 		}
@@ -57,16 +60,23 @@ class Main implements IApplication {
 		run_diagnostics()
 
 		val scenarioFile = getString(scenarioOpt, cmd);
-		val outDir = getString(outDirOpt, cmd);
+		var outDir = getOptString(outDirOpt, cmd, "output");
 		
 		val loader = new ModelStorage()
 		val src = loader.loadCandidates(scenarioFile)
 		
+		val spaceGenerator = new CandidateSpaceGenerator()
+		val hintsPath = getOptString(contractOpt, cmd, null);
+		
 		if (cmd.hasOption(genDefAdaptations.getOpt())){
-			new CandidateSpaceGenerator().createDefaultCandidateSpace(src)
+			spaceGenerator.createDefaultCandidateSpace(src)
+		} else if (hintsPath !== null) {
+			val hints = loader.loadContractSet(hintsPath)
+			spaceGenerator.createCandidateSpace(hints, src)
 		}
 		
-		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(new CosimRunner(new OutputProcessor(outDir), new FmuLoader)))
+		val runner = new CosimRunner(new OutputProcessor(outDir), new FmuLoader)
+		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(runner))
 		
 		generator.createVariantTree(src)
 		
@@ -77,6 +87,8 @@ class Main implements IApplication {
 			generator.generateVariants(src)
 		}
 		
+		runner.close()
+		
 		return IApplication.EXIT_OK
 	}
 	
@@ -87,8 +99,18 @@ class Main implements IApplication {
 			return cmd.getOptionValue(opt.getOpt());
 		} else
 		{
-			System.err.println("Missing option --" + opt.getLongOpt());
-			return null;
+			throw new IllegalArgumentException("Missing option --" + opt.getLongOpt())
+		}
+	}
+	
+	def private String getOptString(Option opt, CommandLine cmd, String d)
+	{
+		if (cmd.hasOption(opt.getOpt()))
+		{
+			return cmd.getOptionValue(opt.getOpt())
+		} else
+		{
+			return d
 		}
 	}
 	
@@ -108,6 +130,8 @@ class Main implements IApplication {
 		Assert.isTrue(candidates.eAllContents.filter(CandidateScenario).head.identifier == "c1")
 		
 		Factory.checkApi()
+		
+		Assert.isTrue(new File("storage_test.xmi").delete())
 	}
 	
 	override stop() {}

+ 17 - 0
HintCO/src/ua/ansymo/hintco/ModelStorage.xtend

@@ -1,7 +1,10 @@
 package ua.ansymo.hintco
 
+import be.uantwerpen.cosys.contractLang.ContractLangPackage
+import be.uantwerpen.cosys.contractLang.Root
 import java.util.HashMap
 import org.eclipse.emf.common.util.URI
+import org.eclipse.emf.ecore.EPackage
 import org.eclipse.emf.ecore.resource.Resource
 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
 import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
@@ -23,6 +26,20 @@ class ModelStorage {
 		return candidates
 	}
 	
+	def loadContractSet(String uri){
+		doContractEMFSetup()
+		val resourceSet = new ResourceSetImpl
+		val res = resourceSet.getResource(URI.createURI(uri), true)
+		val contractSet = (res.contents.get(0) as Root).contractSet
+		return contractSet
+	}
+	
+	def doContractEMFSetup() {
+		if (!EPackage.Registry.INSTANCE.containsKey("http://www.uantwerpen.be/cosys/ContractLang")) {
+			EPackage.Registry.INSTANCE.put("http://www.uantwerpen.be/cosys/ContractLang", ContractLangPackage.eINSTANCE);
+		}
+	}
+	
 	def doEMFSetup(){
 		Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("xmi", new XMIResourceFactoryImpl);
 		// Forces initialization of the package.

+ 14 - 2
HintCO/src/ua/ansymo/hintco/OutputProcessor.xtend

@@ -10,7 +10,7 @@ import org.eclipse.core.runtime.Assert
 class OutputProcessor implements IOutputProcessor {
 	
 	var String outDirPrefix;
-	val Map<CosimUnitInstance, CSVWriter> fmuFileMap = newHashMap()
+	var Map<CosimUnitInstance, CSVWriter> fmuFileMap 
 	var String outDirPath;
 	var long outputInterval;
 	var long outputCounter;
@@ -20,6 +20,9 @@ class OutputProcessor implements IOutputProcessor {
 	}
 	
 	override initialize(CandidateScenario scenario, String variantID) {
+		Assert.isTrue(scenario.outputStepSize >= scenario.stepSize)
+		fmuFileMap = newHashMap()
+		
 		// Compute output interval
 		if (scenario.outputStepSize == 0.0){
 			outputInterval = 1
@@ -58,7 +61,15 @@ class OutputProcessor implements IOutputProcessor {
 		if (outputCounter == 0){
 			outputCounter = outputInterval
 			for (u : fmuFileMap.keySet){
-				fmuFileMap.get(u).writeNext(#[String.format("%g",time)] + u.ports.filter(OutputPortInstance).map[p | String.format("%g", values.get(p))])
+				val file = fmuFileMap.get(u)
+				val outVsString = u.ports.filter(OutputPortInstance)
+								.map[p | 
+										Assert.isTrue(values.containsKey(p))
+										Assert.isNotNull(values.get(p)) 
+										values.get(p)
+								]
+								.map[v | String.format("%g", v)]
+				file.writeNext(#[String.format("%g",time)] + outVsString)
 			}
 		}
 	}
@@ -67,6 +78,7 @@ class OutputProcessor implements IOutputProcessor {
 		for (u : fmuFileMap.keySet){
 			fmuFileMap.get(u).close()
 		}
+		fmuFileMap.clear()
 	}
 		
 }

+ 9 - 5
HintCO/test/ua/ansymo/hintco/test/AdaptedFMUTest.xtend

@@ -74,10 +74,11 @@ class AdaptedFMUTest {
 			}
 			override terminate() {}
 		}
-		
-		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(new CosimRunner(outputCheck, mockLoader)))
+		val runner = new CosimRunner(outputCheck, mockLoader)
+		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(runner))
 		generator.createVariantTree(src)
 		generator.generateVariants(src)
+		runner.close()
 		assertEquals(110, numInnerSteps.size)
 	}
 	
@@ -120,9 +121,11 @@ class AdaptedFMUTest {
 			override terminate() {}
 		}
 		
-		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(new CosimRunner(outputCheck, mockLoader)))
+		val runner = new CosimRunner(outputCheck, mockLoader)
+		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(runner))
 		generator.createVariantTree(src)
 		generator.generateVariants(src)
+		runner.close()
 		assertEquals(11, numInnerSteps.size)
 	}
 	
@@ -166,10 +169,11 @@ class AdaptedFMUTest {
 			}
 			override terminate() {}
 		}
-		
-		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(new CosimRunner(outputCheck, mockLoader)))
+		val runner = new CosimRunner(outputCheck, mockLoader)
+		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(runner))
 		generator.createVariantTree(src)
 		generator.generateVariants(src)
+		runner.close()
 		assertEquals(110, numInnerSteps.size)
 	}
 	

+ 59 - 2
HintCO/test/ua/ansymo/hintco/test/CandidateSpaceGeneratorTest.xtend

@@ -1,10 +1,20 @@
 package ua.ansymo.hintco.test
 
 import org.junit.Test
-import static org.junit.Assert.*
+import ua.ansymo.hintco.CandidateScenario
 import ua.ansymo.hintco.CandidateSpaceGenerator
+import ua.ansymo.hintco.CandidatesGenerator
+import ua.ansymo.hintco.ConstraintChecker
+import ua.ansymo.hintco.CosimRunner
+import ua.ansymo.hintco.FmuLoader
 import ua.ansymo.hintco.ModelStorage
-import ua.ansymo.hintco.CandidateScenario
+import ua.ansymo.hintco.OutputPortInstance
+import ua.ansymo.hintco.OutputProcessor
+import ua.ansymo.hintco.VariantProcessor
+import ua.ansymo.hintco.VariantValidator
+import ua.ansymo.hintco.XorAdaptation
+
+import static org.junit.Assert.*
 
 class CandidateSpaceGeneratorTest {
 	val generator = new CandidateSpaceGenerator()
@@ -25,4 +35,51 @@ class CandidateSpaceGeneratorTest {
 		loader.storeCandidates("instances/generated/create_default_candidate_space_test.xmi", src)
 	}
 	
+	@Test
+	def void loadHintsModelTest(){
+		val contractSet = loader.loadContractSet("instances/case_study_contract.xmi")
+		assertNotNull(contractSet)
+	}
+	
+	@Test
+	def void duplicateScenarioTest(){
+		val candidates = loader.loadCandidates("instances/case_study_double_loop.xmi")
+		val src  = candidates.candidates.head
+		val copy = generator.duplicateScenario(candidates.candidates.head)
+		assertFalse(src === copy)
+		assertFalse(src.cosimunits.head === copy.cosimunits.head)
+		assertTrue(src.cosimunits.head.identifier == copy.cosimunits.head.identifier)
+		val scrOutPort = src.cosimunits.head.ports.head as OutputPortInstance
+		val copyOutPort = copy.cosimunits.head.ports.head as OutputPortInstance
+		assertFalse(scrOutPort === copyOutPort)
+		assertTrue(scrOutPort.identifier == copyOutPort.identifier)
+		assertFalse(scrOutPort.valueTo.head === copyOutPort.valueTo.head)
+		assertTrue(scrOutPort.valueTo.head.identifier == copyOutPort.valueTo.head.identifier)
+	}
+	
+	@Test
+	def void generateSoftwareHintsTest(){
+		val contractSet = loader.loadContractSet("instances/case_study_contract.xmi")
+		val candidates = loader.loadCandidates("instances/case_study_double_loop.xmi")
+		generator.createCandidateSpace(contractSet, candidates)
+		val newScenario = candidates.candidates.last
+		assertTrue(newScenario.cosimunits.filter[u | u.identifier != "DLoopController_FixedEuler_1Em6"]
+										.forall[u | u.adaptation instanceof XorAdaptation]
+		)
+	}
+	
+	@Test
+	def void endToEndWaterTankTest(){
+		val resultsDirPath = "results-gen/waterTankTest"
+		val candidates = loader.loadCandidates("instances/watertanks.xmi")
+		val contractSet = loader.loadContractSet("instances/watertanks_ctrl.xmi")
+		generator.createCandidateSpace(contractSet, candidates)
+		val runner = new CosimRunner(new OutputProcessor(resultsDirPath), new FmuLoader)
+		val variantGen = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(runner))
+		variantGen.createVariantTree(candidates)
+		variantGen.generateVariants(candidates, 5)
+		runner.close()
+	}
+	
+	
 }

+ 23 - 2
HintCO/test/ua/ansymo/hintco/test/CosimRunnerTest.xtend

@@ -17,6 +17,7 @@ import ua.ansymo.hintco.VariantProcessor
 import ua.ansymo.hintco.VariantValidator
 
 import static org.junit.Assert.*
+import org.apache.commons.io.FileUtils
 
 class CosimRunnerTest {
 	@Test
@@ -100,10 +101,12 @@ class CosimRunnerTest {
 	def void executeCosimulationTest(){
 		val resultsDirPath = "results-gen/cosimTest"
 		val loader = new ModelStorage()
-		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(new CosimRunner(new OutputProcessor(resultsDirPath), new FmuLoader)))
+		val runner = new CosimRunner(new OutputProcessor(resultsDirPath), new FmuLoader)
+		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(runner))
 		val src = loader.loadCandidates("instances/execute_cosim_test_watertanks.xmi")
 		generator.createVariantTree(src)
 		generator.generateVariants(src, 1)
+		runner.close()
 	}
 	
 	@Test
@@ -111,11 +114,29 @@ class CosimRunnerTest {
 	def void executeCosimulationTestDoubleLoop(){
 		val resultsDirPath = "results-gen/cosimTestDLoop"
 		val loader = new ModelStorage()
-		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(new CosimRunner(new OutputProcessor(resultsDirPath), new FmuLoader)))
+		val runner = new CosimRunner(new OutputProcessor(resultsDirPath), new FmuLoader)
+		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(runner))
 		val src = loader.loadCandidates("instances/case_study_double_loop_better.xmi")
 		generator.createVariantTree(src)
 		generator.generateVariants(src, 1)
+		runner.close()
 	}
 	
+	@Test
+	def void executeDuplicateUnitTest(){
+		val resultsDirPath = "results-gen/dupUnitTest"
+		FileUtils.deleteDirectory(new File(resultsDirPath))
+		val loader = new ModelStorage()
+		val runner = new CosimRunner(new OutputProcessor(resultsDirPath), new FmuLoader)
+		val generator = new CandidatesGenerator(new ConstraintChecker,new VariantValidator, new VariantProcessor(runner))
+		val src = loader.loadCandidates("instances/duplicate_unit_test.xmi")
+		generator.createVariantTree(src)
+		generator.generateVariants(src, 1)
+		runner.close()
+		val resultsWt1 = new File(resultsDirPath + "/0_1/wt1.csv")
+		val resultsWt2 = new File(resultsDirPath + "/0_1/wt2.csv")
+		assertTrue(resultsWt1.exists)
+		assertTrue(resultsWt2.exists)
+	}
 	
 }

+ 7 - 0
be.uantwerpen.cosys.ContractLang/.classpath

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

+ 28 - 0
be.uantwerpen.cosys.ContractLang/.project

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>be.uantwerpen.cosys.ContractLang</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>

+ 7 - 0
be.uantwerpen.cosys.ContractLang/.settings/org.eclipse.jdt.core.prefs

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

+ 16 - 0
be.uantwerpen.cosys.ContractLang/META-INF/MANIFEST.MF

@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: be.uantwerpen.cosys.ContractLang;singleton:=true
+Automatic-Module-Name: be.uantwerpen.cosys.ContractLang
+Bundle-Version: 1.0.0.qualifier
+Bundle-ClassPath: .
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: be.uantwerpen.cosys.contractLang,
+ be.uantwerpen.cosys.contractLang.impl,
+ be.uantwerpen.cosys.contractLang.util
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.emf.ecore;visibility:=reexport
+Bundle-ActivationPolicy: lazy

+ 9 - 0
be.uantwerpen.cosys.ContractLang/build.properties

@@ -0,0 +1,9 @@
+# generated by Xtext 2.16.0
+
+bin.includes = .,\
+               META-INF/,\
+               plugin.xml,\
+               plugin.properties
+jars.compile.order = .
+source.. = src-gen/
+output.. = bin/

+ 4 - 0
be.uantwerpen.cosys.ContractLang/plugin.properties

@@ -0,0 +1,4 @@
+# generated by Xtext 2.16.0
+
+pluginName = ContractLang Model
+providerName = www.example.org

+ 17 - 0
be.uantwerpen.cosys.ContractLang/plugin.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<!--
+ generated by Xtext 2.16.0
+-->
+
+<plugin>
+
+   <extension point="org.eclipse.emf.ecore.generated_package">
+      <!-- @generated ContractLang -->
+      <package
+            uri="http://www.uantwerpen.be/cosys/ContractLang"
+            class="be.uantwerpen.cosys.contractLang.ContractLangPackage"/>
+   </extension>
+
+</plugin>