HintConfiguration.xcore 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package ua.ansymo.hintco
  2. import org.eclipse.emf.common.util.BasicEList
  3. type Int wraps int
  4. abstract class IDed {
  5. String identifier
  6. }
  7. class HintConfiguration {
  8. contains RootCandidateScenario[] candidates
  9. contains CosimUnitDeclaration[] csuDeclarations
  10. refers VariantDiagram root
  11. contains VariantDiagram[] nodes
  12. }
  13. class VariantDiagram extends IDed {
  14. refers VariantDiagram[] children
  15. refers Alternative alternative
  16. derived String name get {
  17. val prefix = identifier+"_"
  18. if (alternative !== null){
  19. if (alternative instanceof RootCandidateScenario){
  20. prefix + "sce " + (alternative as RootCandidateScenario).name
  21. } else if (alternative instanceof XorPortAdaptation) {
  22. prefix + "xor " + (alternative as XorPortAdaptation).name
  23. } else if (alternative instanceof XorUnitAdaptation) {
  24. prefix + "xor " + (alternative as XorUnitAdaptation).name
  25. } else if (alternative instanceof ExtrapolationAdaptation) {
  26. prefix + "extra " + (alternative as ExtrapolationAdaptation).name
  27. } else if (alternative instanceof InterpolationAdaptation) {
  28. prefix + "intra " + (alternative as InterpolationAdaptation).name
  29. } else {
  30. prefix + "implement"
  31. }
  32. }
  33. else {
  34. prefix + "root"
  35. }
  36. }
  37. }
  38. abstract class PrecendenceNode {
  39. refers PrecendenceNode[] precedes opposite succeeds
  40. refers PrecendenceNode[] succeeds opposite precedes
  41. refers PrecendenceNode before opposite after
  42. refers PrecendenceNode after opposite before
  43. }
  44. class RootCandidateScenario extends IDed, Alternative, Scenario {
  45. derived String name get {
  46. identifier + "(w=" + weight + ")"
  47. }
  48. double stopTime
  49. double stepSize
  50. double outputStepSize
  51. int maxInitIterations = "10"
  52. }
  53. abstract class Scenario extends IDed {
  54. contains UnitInstance[] cosimunits opposite scenario
  55. }
  56. class HierarchicalCosimUnit extends Scenario,UnitInstance {
  57. op boolean valid() {
  58. ports.forall[p | p instanceof HierarchicalUnitPort]
  59. }
  60. }
  61. class CosimUnitDeclaration extends IDed {
  62. String path
  63. String guid
  64. }
  65. abstract class UnitInstance extends IDed,PrecendenceNode{
  66. refers Scenario scenario opposite cosimunits
  67. contains UnitAdaptation adaptation opposite unit
  68. contains PortInstance[] ports opposite unit
  69. op UnitAdaptation[] selectedAdaptations() {
  70. if (adaptation === null){
  71. return new BasicEList(#[])
  72. }
  73. if (adaptation.selected){
  74. if (adaptation instanceof DecompositionUnitAdaptation){
  75. return (adaptation as DecompositionUnitAdaptation).selectedAdaptations()
  76. }
  77. return new BasicEList(#[adaptation])
  78. }
  79. return new BasicEList(#[])
  80. }
  81. op OutputPortInstance[] getOutputPorts(){
  82. ports.filter(OutputPortInstance).filter[!it.isInput].toEList
  83. }
  84. op InputPortInstance[] getInputPorts(){
  85. ports.filter(InputPortInstance).filter[it.isInput].toEList
  86. }
  87. op String toString(){
  88. identifier
  89. }
  90. }
  91. class CosimUnitInstance extends UnitInstance {
  92. refers CosimUnitDeclaration[1] declaration
  93. }
  94. abstract class PortInstance extends PrecendenceNode,IDed {
  95. refers UnitInstance unit opposite ports
  96. contains PortAdaptation adaptation opposite port
  97. op PortAdaptation[] selectedAdaptations() {
  98. if (adaptation === null){
  99. return new BasicEList(#[])
  100. }
  101. if (adaptation.selected){
  102. if (adaptation instanceof DecompositionPortAdaptation){
  103. return (adaptation as DecompositionPortAdaptation).selectedAdaptations()
  104. }
  105. return new BasicEList(#[adaptation])
  106. }
  107. return new BasicEList(#[])
  108. }
  109. op boolean isInput() {
  110. false
  111. }
  112. op boolean getsValueFrom(PortInstance p){
  113. return false
  114. }
  115. op String toString(){
  116. unit.toString()+"."+identifier
  117. }
  118. }
  119. class HierarchicalUnitPort extends InputPortInstance,OutputPortInstance{
  120. op boolean isInput() {
  121. // A port is an input if it gets its value from an external port.
  122. val auxIsInput = ! unit.eAllContents.filter(OutputPortInstance).exists[p | p == valueFrom]
  123. val auxAltIsInput = altIsInput()
  124. if ((auxIsInput && !auxAltIsInput) || (!auxIsInput && auxAltIsInput)){
  125. throw new RuntimeException("Something wrong with the implementation of isInput")
  126. }
  127. auxIsInput
  128. }
  129. op boolean altIsInput() {
  130. // A port is an input if it is connected to internal input ports or internal unit ports that are inputs themselves.
  131. if (valueTo.empty){
  132. false // A port connected to nothing must be an output
  133. } else {
  134. valueTo.forall[trgP |
  135. if (trgP.unit === unit){
  136. false // We don't tolerate feedtrough connections on hierarchical units.
  137. } else {
  138. val internal = unit.eAllContents.filter(InputPortInstance).exists[ip | ip===trgP]
  139. if (! internal ){
  140. false
  141. } else if (trgP instanceof HierarchicalUnitPort){
  142. trgP.altIsInput
  143. } else {
  144. true
  145. }
  146. }
  147. ]
  148. }
  149. }
  150. }
  151. class InputPortInstance extends PortInstance {
  152. refers OutputPortInstance[] internalValueTo opposite internalValueFrom
  153. refers OutputPortInstance valueFrom opposite valueTo
  154. // Recursively ignore HierarchicalUnitPort and get the OutputPortInstance that generates this value
  155. op OutputPortInstance getRealValueFrom() {
  156. if (valueFrom instanceof HierarchicalUnitPort){
  157. (valueFrom as HierarchicalUnitPort).realValueFrom
  158. } else {
  159. valueFrom
  160. }
  161. }
  162. op boolean getsValueFrom(PortInstance p){
  163. if (valueFrom === p){
  164. return true
  165. } else if (valueFrom instanceof InputPortInstance){
  166. return (valueFrom as InputPortInstance).getsValueFrom(p)
  167. } else {
  168. return false
  169. }
  170. }
  171. op boolean isInput() {
  172. true
  173. }
  174. }
  175. class OutputPortInstance extends PortInstance {
  176. refers InputPortInstance[] valueTo opposite valueFrom
  177. refers InputPortInstance[] internalValueFrom opposite internalValueTo
  178. op boolean isInput() {
  179. false
  180. }
  181. }
  182. abstract class Alternative
  183. {
  184. int weight
  185. boolean selected
  186. refers Alternative[] implies
  187. }
  188. abstract class Adaptation extends Alternative
  189. {
  190. }
  191. abstract class PortAdaptation extends Adaptation
  192. {
  193. refers PortInstance port opposite adaptation
  194. refers DecompositionPortAdaptation parent opposite children
  195. op PortInstance adapted() {
  196. if (port !== null){
  197. return port
  198. }
  199. if (parent === null){
  200. return null
  201. }
  202. return parent.adapted()
  203. }
  204. }
  205. abstract class DecompositionPortAdaptation extends PortAdaptation {
  206. contains PortAdaptation[] children opposite parent
  207. derived String name get {
  208. "(w=" + weight + ")"
  209. }
  210. op PortAdaptation[] selectedAdaptations() {
  211. val res = new BasicEList(children.size)
  212. for (c : children.filter[a | a.selected]){
  213. if (c instanceof DecompositionPortAdaptation){
  214. res.addAll(c.selectedAdaptations())
  215. } else {
  216. res.add(c)
  217. }
  218. }
  219. return res
  220. }
  221. }
  222. abstract class UnitAdaptation extends Adaptation {
  223. refers UnitInstance unit opposite adaptation
  224. refers DecompositionUnitAdaptation parent opposite children
  225. op UnitInstance adapted() {
  226. if (unit !== null){
  227. return unit
  228. }
  229. if (parent === null){
  230. return null
  231. }
  232. return parent.adapted()
  233. }
  234. }
  235. abstract class DecompositionUnitAdaptation extends UnitAdaptation {
  236. contains UnitAdaptation[] children opposite parent
  237. derived String name get {
  238. "(w=" + weight + ")"
  239. }
  240. op UnitAdaptation[] selectedAdaptations() {
  241. val res = new BasicEList(children.size)
  242. for (c : children.filter[a | a.selected]){
  243. if (c instanceof DecompositionUnitAdaptation){
  244. res.addAll(c.selectedAdaptations())
  245. } else {
  246. res.add(c)
  247. }
  248. }
  249. return res
  250. }
  251. }
  252. class XorUnitAdaptation extends DecompositionUnitAdaptation {
  253. }
  254. class XorPortAdaptation extends DecompositionPortAdaptation {
  255. }
  256. abstract class ApproximationAdaptation extends PortAdaptation {
  257. int order
  258. }
  259. class MultiRateAdaptation extends UnitAdaptation {
  260. int rate
  261. derived String name get {
  262. rate + "(w=" + weight + ")"
  263. }
  264. }
  265. class PowerBondAdaptation extends UnitAdaptation {
  266. refers PortInstance effort
  267. refers PortInstance flow
  268. refers OutputPortInstance pOut
  269. refers InputPortInstance pIn
  270. op PowerBondAdaptation getDual() {
  271. var PowerBondAdaptation res = null
  272. if (effort instanceof InputPortInstance && flow instanceof OutputPortInstance){
  273. res = unit.scenario.cosimunits
  274. .flatMap[u | u.eAllContents.filter(PowerBondAdaptation).toIterable]
  275. .filter[a | a.effort instanceof OutputPortInstance && a.flow instanceof InputPortInstance]
  276. .findFirst[a | (a.effort as OutputPortInstance).valueTo.contains(effort) && (a.flow as InputPortInstance).valueFrom === flow]
  277. } else if (effort instanceof OutputPortInstance && flow instanceof InputPortInstance) {
  278. res = unit.scenario.cosimunits
  279. .flatMap[u | u.eAllContents.filter(PowerBondAdaptation).toIterable]
  280. .filter[a | a.effort instanceof InputPortInstance && a.flow instanceof OutputPortInstance]
  281. .findFirst[a | (a.effort as InputPortInstance).valueFrom === effort && (a.flow as OutputPortInstance).valueTo.contains(flow)]
  282. } else {
  283. throw new RuntimeException("Invalid effort and flow in power bond adaptation")
  284. }
  285. if (res===null){
  286. throw new RuntimeException("Power bond adaptation has no dual")
  287. }
  288. res
  289. }
  290. derived String name get {
  291. if (effort!==null && flow !== null){
  292. "PBond_" + effort.identifier + "_" + flow.identifier + "(w=" + weight + ")"
  293. } else {
  294. "PBond(w=" + weight + ")"
  295. }
  296. }
  297. }
  298. class ExtrapolationAdaptation extends ApproximationAdaptation {
  299. derived String name get {
  300. order + "(w=" + weight + ")"
  301. }
  302. }
  303. class RollbackInterpolationAdaptation extends ExtrapolationAdaptation {
  304. }
  305. class InterpolationAdaptation extends ApproximationAdaptation {
  306. derived String name get {
  307. order + "(w=" + weight + ")"
  308. }
  309. }