cbd_semantics.alc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. include "primitives.alh"
  2. include "modelling.alh"
  3. include "object_operations.alh"
  4. include "library.alh"
  5. include "conformance_scd.alh"
  6. Void function main():
  7. Element model
  8. String verify_result
  9. while (True):
  10. output("Which model do you want to execute with CBD semantics?")
  11. model = import_node(input())
  12. if (element_eq(model, read_root())):
  13. output("Could not find model; aborting")
  14. elif (element_neq(model["metamodel"], import_node("models/CausalBlockDiagrams_Design"))):
  15. output("Not a CBD design model; aborting")
  16. else:
  17. verify_result = conformance_scd(model)
  18. if (verify_result == "OK"):
  19. output("Model OK!")
  20. execute_cbd(model)
  21. else:
  22. output("Non-conforming model: " + verify_result)
  23. Void function translate_to_runtime(design_model : Element):
  24. Element runtime_model
  25. Element all_blocks
  26. Element all_links
  27. String mm_type_name
  28. String element_name
  29. String attr_name
  30. String attr_value
  31. String attribute
  32. String src
  33. String dst
  34. Element all_attributes
  35. log("Translating to runtime model!")
  36. log("Creating empty runtime model")
  37. runtime_model = instantiate_model(import_node("models/CausalBlockDiagrams_Runtime"))
  38. log("Converting blocks")
  39. all_blocks = allInstances(design_model, "Block")
  40. while (list_len(all_blocks) > 0):
  41. element_name = set_pop(all_blocks)
  42. mm_type_name = reverseKeyLookup(design_model["metamodel"]["model"], dict_read_node(design_model["type_mapping"], design_model["model"][element_name]))
  43. instantiate_node(runtime_model, mm_type_name, element_name)
  44. all_attributes = getAttributeList(design_model, element_name)
  45. while (read_nr_out(all_attributes) > 0):
  46. attr_name = set_pop(all_attributes)
  47. if (bool_not(set_in(runtime_model["model"], read_attribute(design_model, element_name, attr_name)))):
  48. instantiate_attribute(runtime_model, element_name, attr_name, read_attribute(design_model, element_name, attr_name))
  49. log(" Converted block " + element_name)
  50. // Don't merge this together with the block conversion, as the destination block might not exist yet!
  51. log("Relinking blocks")
  52. all_links = allInstances(design_model, "Link")
  53. while (read_nr_out(all_links) > 0):
  54. element_name = set_pop(all_links)
  55. src = reverseKeyLookup(design_model["model"], read_edge_src(design_model["model"][element_name]))
  56. dst = reverseKeyLookup(design_model["model"], read_edge_dst(design_model["model"][element_name]))
  57. instantiate_link(runtime_model, "Link", element_name, src, dst)
  58. log(((" Relinked blocks " + src) + " and ") + dst)
  59. log("Resetting initial conditions")
  60. all_links = allInstances(design_model, "InitialCondition")
  61. while (read_nr_out(all_links) > 0):
  62. element_name = set_pop(all_links)
  63. src = reverseKeyLookup(design_model["model"], read_edge_src(design_model["model"][element_name]))
  64. dst = reverseKeyLookup(design_model["model"], read_edge_dst(design_model["model"][element_name]))
  65. instantiate_link(runtime_model, "InitialCondition", element_name, src, dst)
  66. log(" Reset IC of " + dst)
  67. log("Creating schedule at time = 0")
  68. create_schedule(runtime_model, True)
  69. log("Creating schedule at time > 0")
  70. create_schedule(runtime_model, False)
  71. log("Solving loops (TODO)")
  72. log("DONE!")
  73. return !
  74. Void function create_schedule(model : Element, is_time_zero : Boolean):
  75. Element all_blocks
  76. Element visited
  77. Element to_visit
  78. Element incoming_links
  79. String schedule
  80. String element_name
  81. String link
  82. String source
  83. String new_schedule
  84. Boolean ready
  85. all_blocks = allInstances(model, "Block")
  86. visited = create_node()
  87. to_visit = create_node()
  88. if (is_time_zero):
  89. log("Make initial schedule!")
  90. schedule = instantiate_node(model, "Schedule", "schedule_init")
  91. else:
  92. log("Make normal schedule!")
  93. schedule = instantiate_node(model, "Schedule", "schedule_run")
  94. instantiate_attribute(model, schedule, "active", True)
  95. log("Instantiated attribute")
  96. while (read_nr_out(all_blocks) > 0):
  97. element_name = set_pop(all_blocks)
  98. if (bool_not(set_in(visited, element_name))):
  99. list_append(to_visit, element_name)
  100. while (list_len(to_visit) > 0):
  101. element_name = list_read(to_visit, list_len(to_visit) - 1)
  102. if (reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][element_name])) == "DelayBlock"):
  103. if (is_time_zero):
  104. incoming_links = allIncomingAssociationInstances(model, element_name, "InitialCondition")
  105. else:
  106. incoming_links = create_node()
  107. else:
  108. incoming_links = allIncomingAssociationInstances(model, element_name, "Link")
  109. ready = True
  110. while (list_len(incoming_links) > 0):
  111. link = set_pop(incoming_links)
  112. source = readAssociationSource(model, link)
  113. if (bool_not(set_in(visited, source))):
  114. list_append(to_visit, source)
  115. ready = False
  116. if (ready):
  117. new_schedule = instantiate_node(model, "Schedule", "")
  118. log("Instantiate active")
  119. log(cast_e2s(new_schedule))
  120. instantiate_attribute(model, new_schedule, "active", False)
  121. log("ACTIVE OK")
  122. instantiate_link(model, "LinkedBlock", "", schedule, element_name)
  123. instantiate_link(model, "NextSchedule", "", schedule, new_schedule)
  124. schedule = new_schedule
  125. list_delete(to_visit, list_len(to_visit) - 1)
  126. set_add(visited, element_name)
  127. return !
  128. String function readType(model : Element, name : String):
  129. return reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][name]))!
  130. Void function list_CBD(model : Element):
  131. Element all_elements
  132. String elem
  133. String block
  134. output("Blocks:")
  135. all_elements = allInstances(model, "Block")
  136. while (read_nr_out(all_elements) > 0):
  137. elem = set_pop(all_elements)
  138. output(((" " + elem) + ": ") + readType(model, elem))
  139. output("Links:")
  140. all_elements = allInstances(model, "Link")
  141. while (read_nr_out(all_elements) > 0):
  142. elem = set_pop(all_elements)
  143. output(((" " + reverseKeyLookup(model["model"], read_edge_src(model["model"][elem]))) + " --> ") + reverseKeyLookup(model["model"], read_edge_dst(model["model"][elem])))
  144. output("Initial conditions:")
  145. all_elements = allInstances(model, "InitialCondition")
  146. while (read_nr_out(all_elements) > 0):
  147. elem = set_pop(all_elements)
  148. output(((" " + reverseKeyLookup(model["model"], read_edge_src(model["model"][elem]))) + " --> ") + reverseKeyLookup(model["model"], read_edge_dst(model["model"][elem])))
  149. output("Schedule @ 0:")
  150. elem = "schedule_init"
  151. while (allOutgoingAssociationInstances(model, elem, "LinkedBlock")):
  152. block = set_pop(readAssociationSource(model, set_pop(allOutgoingAssociationInstances(model, elem, "LinkedBlock"))))
  153. output(" " + block)
  154. elem = set_pop(readAssociationSource(model, set_pop(allOutgoingAssociationInstances(model, elem, "LinkedBlock"))))
  155. output("Schedule @ 0:")
  156. elem = "schedule_run"
  157. while (allOutgoingAssociationInstances(model, elem, "LinkedBlock")):
  158. block = set_pop(readAssociationSource(model, set_pop(allOutgoingAssociationInstances(model, elem, "LinkedBlock"))))
  159. output(" " + block)
  160. elem = set_pop(readAssociationSource(model, set_pop(allOutgoingAssociationInstances(model, elem, "LinkedBlock"))))
  161. return !
  162. Void function execute_cbd(model : Element):
  163. translate_to_runtime(model)
  164. String cmd
  165. while (True):
  166. output("Which operation do you want to execute?")
  167. cmd = input()
  168. if (cmd == "help"):
  169. output("Supported operations:")
  170. output(" start -- start simulation")
  171. output(" pause -- pause simulation")
  172. output(" modify -- live modelling: modify model structure")
  173. output(" list -- list blocks and connections")
  174. output(" help -- this information")
  175. output(" exit -- select another model")
  176. elif (cmd == "list"):
  177. list_CBD(model)
  178. elif (cmd == "exit"):
  179. return!
  180. else:
  181. output("Did not understand command!")
  182. output("Use 'help' for a list of available options")