HintConfiguration.xcore 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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 PrecedenceNode {
  39. refers PrecedenceNode[] precedes opposite succeeds
  40. refers PrecedenceNode[] succeeds opposite precedes
  41. refers PrecedenceNode before opposite after
  42. refers PrecedenceNode 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,PrecedenceNode{
  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 PrecedenceNode,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. float extrapolationCost = "1.0"
  153. refers OutputPortInstance[] internalValueTo opposite internalValueFrom
  154. refers OutputPortInstance valueFrom opposite valueTo
  155. // Recursively ignore HierarchicalUnitPort and get the OutputPortInstance that generates this value
  156. op OutputPortInstance getRealValueFrom() {
  157. if (valueFrom instanceof HierarchicalUnitPort){
  158. (valueFrom as HierarchicalUnitPort).realValueFrom
  159. } else {
  160. valueFrom
  161. }
  162. }
  163. op boolean getsValueFrom(PortInstance p){
  164. if (valueFrom === p){
  165. return true
  166. } else if (valueFrom instanceof InputPortInstance){
  167. return (valueFrom as InputPortInstance).getsValueFrom(p)
  168. } else {
  169. return false
  170. }
  171. }
  172. op boolean isInput() {
  173. true
  174. }
  175. }
  176. class OutputPortInstance extends PortInstance {
  177. refers InputPortInstance[] valueTo opposite valueFrom
  178. refers InputPortInstance[] internalValueFrom opposite internalValueTo
  179. op boolean isInput() {
  180. false
  181. }
  182. }
  183. abstract class Alternative
  184. {
  185. int weight
  186. boolean selected
  187. refers Alternative[] implies
  188. }
  189. abstract class Adaptation extends Alternative
  190. {
  191. }
  192. abstract class PortAdaptation extends Adaptation
  193. {
  194. refers PortInstance port opposite adaptation
  195. refers DecompositionPortAdaptation parent opposite children
  196. op PortInstance adapted() {
  197. if (port !== null){
  198. return port
  199. }
  200. if (parent === null){
  201. return null
  202. }
  203. return parent.adapted()
  204. }
  205. }
  206. abstract class DecompositionPortAdaptation extends PortAdaptation {
  207. contains PortAdaptation[] children opposite parent
  208. derived String name get {
  209. "(w=" + weight + ")"
  210. }
  211. op PortAdaptation[] selectedAdaptations() {
  212. val res = new BasicEList(children.size)
  213. for (c : children.filter[a | a.selected]){
  214. if (c instanceof DecompositionPortAdaptation){
  215. res.addAll(c.selectedAdaptations())
  216. } else {
  217. res.add(c)
  218. }
  219. }
  220. return res
  221. }
  222. }
  223. abstract class UnitAdaptation extends Adaptation {
  224. refers UnitInstance unit opposite adaptation
  225. refers DecompositionUnitAdaptation parent opposite children
  226. op UnitInstance adapted() {
  227. if (unit !== null){
  228. return unit
  229. }
  230. if (parent === null){
  231. return null
  232. }
  233. return parent.adapted()
  234. }
  235. }
  236. abstract class DecompositionUnitAdaptation extends UnitAdaptation {
  237. contains UnitAdaptation[] children opposite parent
  238. derived String name get {
  239. "(w=" + weight + ")"
  240. }
  241. op UnitAdaptation[] selectedAdaptations() {
  242. val res = new BasicEList(children.size)
  243. for (c : children.filter[a | a.selected]){
  244. if (c instanceof DecompositionUnitAdaptation){
  245. res.addAll(c.selectedAdaptations())
  246. } else {
  247. res.add(c)
  248. }
  249. }
  250. return res
  251. }
  252. }
  253. class XorUnitAdaptation extends DecompositionUnitAdaptation {
  254. }
  255. class XorPortAdaptation extends DecompositionPortAdaptation {
  256. }
  257. abstract class ApproximationAdaptation extends PortAdaptation {
  258. int order
  259. }
  260. class MultiRateAdaptation extends UnitAdaptation {
  261. int rate
  262. derived String name get {
  263. rate + "(w=" + weight + ")"
  264. }
  265. }
  266. class PowerBondAdaptation extends UnitAdaptation {
  267. refers PortInstance effort
  268. refers PortInstance flow
  269. refers OutputPortInstance pOut
  270. refers InputPortInstance pIn
  271. op PowerBondAdaptation getDual() {
  272. var PowerBondAdaptation res = null
  273. if (effort instanceof InputPortInstance && flow instanceof OutputPortInstance){
  274. res = unit.scenario.cosimunits
  275. .flatMap[u | u.eAllContents.filter(PowerBondAdaptation).toIterable]
  276. .filter[a | a.effort instanceof OutputPortInstance && a.flow instanceof InputPortInstance]
  277. .findFirst[a | (a.effort as OutputPortInstance).valueTo.contains(effort) && (a.flow as InputPortInstance).valueFrom === flow]
  278. } else if (effort instanceof OutputPortInstance && flow instanceof InputPortInstance) {
  279. res = unit.scenario.cosimunits
  280. .flatMap[u | u.eAllContents.filter(PowerBondAdaptation).toIterable]
  281. .filter[a | a.effort instanceof InputPortInstance && a.flow instanceof OutputPortInstance]
  282. .findFirst[a | (a.effort as InputPortInstance).valueFrom === effort && (a.flow as OutputPortInstance).valueTo.contains(flow)]
  283. } else {
  284. throw new RuntimeException("Invalid effort and flow in power bond adaptation")
  285. }
  286. if (res===null){
  287. throw new RuntimeException("Power bond adaptation has no dual")
  288. }
  289. res
  290. }
  291. derived String name get {
  292. if (effort!==null && flow !== null){
  293. "PBond_" + effort.identifier + "_" + flow.identifier + "(w=" + weight + ")"
  294. } else {
  295. "PBond(w=" + weight + ")"
  296. }
  297. }
  298. }
  299. class ExtrapolationAdaptation extends ApproximationAdaptation {
  300. derived String name get {
  301. order + "(w=" + weight + ")"
  302. }
  303. }
  304. class RollbackInterpolationAdaptation extends ExtrapolationAdaptation {
  305. }
  306. class InterpolationAdaptation extends ApproximationAdaptation {
  307. derived String name get {
  308. order + "(w=" + weight + ")"
  309. }
  310. }