fsa_semantics.alc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. include "primitives.alh"
  2. include "modelling.alh"
  3. include "object_operations.alh"
  4. include "library.alh"
  5. include "conformance_scd.alh"
  6. include "io.alh"
  7. include "metamodels.alh"
  8. include "compilation_manager.alh"
  9. Element function retype_to_runtime(design_model : Element):
  10. Element runtime_model
  11. Element all_states
  12. Element all_links
  13. String mm_type_name
  14. String element_name
  15. String attr_name
  16. String attr_value
  17. String attribute
  18. String src
  19. String dst
  20. String time
  21. Element all_attributes
  22. runtime_model = instantiate_model(import_node("models/FiniteStateAutomata_Runtime"))
  23. all_blocks = allInstances(design_model, "State")
  24. while (list_len(all_states) > 0):
  25. element_name = set_pop(all_states)
  26. mm_type_name = reverseKeyLookup(design_model["metamodel"]["model"], dict_read_node(design_model["type_mapping"], design_model["model"][element_name]))
  27. element_name = instantiate_node(runtime_model, mm_type_name, element_name)
  28. instantiate_attribute(runtime_model, element_name, "name", read_attribute(design_model, element_name, "name"))
  29. // Don't merge this together with the block conversion, as the destination block might not exist yet!
  30. all_links = allInstances(design_model, "Transition")
  31. while (read_nr_out(all_links) > 0):
  32. element_name = set_pop(all_links)
  33. src = reverseKeyLookup(design_model["model"], read_edge_src(design_model["model"][element_name]))
  34. dst = reverseKeyLookup(design_model["model"], read_edge_dst(design_model["model"][element_name]))
  35. instantiate_link(runtime_model, "Transition", element_name, src, dst)
  36. instantiate_attribute(runtime_model, element_name, "event", read_attribute(design_model, element_name, "event"))
  37. if (element_neq(read_attribute(design_model, element_name, "raise"), read_root())):
  38. // There is a raise attribute
  39. instantiate_attribute(runtime_model, element_name, "raise", read_attribute(design_model, element_name, "raise"))
  40. return runtime_model!
  41. Element function sanitize(new_runtime_model : Element, old_runtime_model : Element):
  42. Element all_blocks
  43. Element all_links
  44. String element_name
  45. String attr_name
  46. String attr_value
  47. String attribute
  48. String time
  49. Element all_attributes
  50. Float current_time
  51. all_blocks = allInstances(new_runtime_model, "Block")
  52. while (list_len(all_blocks) > 0):
  53. element_name = set_pop(all_blocks)
  54. if (dict_in(old_runtime_model["model"], element_name)):
  55. if (is_nominal_instance(new_runtime_model, element_name, "ICBlock")):
  56. instantiate_attribute(new_runtime_model, element_name, "last_in", read_attribute(old_runtime_model, element_name, "last_in"))
  57. if (is_nominal_instance(new_runtime_model, element_name, "IntegratorBlock")):
  58. instantiate_attribute(new_runtime_model, element_name, "last_out", read_attribute(old_runtime_model, element_name, "last_out"))
  59. instantiate_attribute(new_runtime_model, element_name, "signal", read_attribute(old_runtime_model, element_name, "signal"))
  60. else:
  61. instantiate_attribute(new_runtime_model, element_name, "signal", 0.0)
  62. if (dict_in(old_runtime_model["model"], "time")):
  63. current_time = read_attribute(old_runtime_model, "time", "current_time")
  64. else:
  65. current_time = 0
  66. time = instantiate_node(new_runtime_model, "Time", "time")
  67. instantiate_attribute(new_runtime_model, time, "start_time", current_time)
  68. instantiate_attribute(new_runtime_model, time, "current_time", current_time)
  69. return new_runtime_model!
  70. Void function dict_overwrite(d : Element, key : Element, value : Element):
  71. if (dict_in(d, key)):
  72. dict_delete(d, key)
  73. if (dict_in_node(d, key)):
  74. dict_delete_node(d, key)
  75. dict_add(d, key, value)
  76. return !
  77. Integer function min(a : Integer, b : Integer):
  78. if (a < b):
  79. return a!
  80. else:
  81. return b!
  82. Element function list_pop(list : Element):
  83. Integer top
  84. Element t
  85. top = list_len(list) - 1
  86. t = list_read(list, top)
  87. list_delete(list, top)
  88. return t!
  89. String function readType(model : Element, name : String):
  90. return reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][name]))!
  91. Integer function list_index_of(lst : Element, elem : Element):
  92. Integer i
  93. i = 0
  94. while (i < read_nr_out(lst)):
  95. if (value_eq(list_read(lst, i), elem)):
  96. return i!
  97. else:
  98. i = i + 1
  99. return -1!
  100. Void function do_transition(model : Element, start_time : Float, event : String):
  101. // Read out current state
  102. String cstate_link
  103. String cstate
  104. cstate_link = set_pop(allInstances(model, "CurrentStateLink"))
  105. cstate = readAssociationDestination(model, cstate_link)
  106. // Read out all outgoing transitions
  107. Element all_transitions
  108. all_transitions = allOutgoingAssociationInstances(model, cstate, "Transition")
  109. while (read_nr_out(all_transitions) > 0):
  110. if (value_eq(read_attribute(model, cstate, "event"), event)):
  111. // Found a match
  112. model_delete_element(model, cstate_link)
  113. // TODO
  114. // Set destination of state
  115. // Raise "raise" attribute of transition
  116. return !
  117. return!
  118. Void function execute_fsa(design_model : Element):
  119. String verify_result
  120. Element runtime_model
  121. Element old_runtime_model
  122. String cmd
  123. Boolean running
  124. String conforming
  125. Float simulation_time
  126. Float start_time
  127. start_time = time()
  128. simulation_time = 0.0
  129. old_runtime_model = instantiate_model(import_node("models/FiniteStateAutomata_Runtime"))
  130. runtime_model = retype_to_runtime(design_model)
  131. runtime_model = sanitize(runtime_model, old_runtime_model)
  132. conforming = conformance_scd(design_model)
  133. if (conforming == "OK"):
  134. output("CONFORMANCE_OK")
  135. else:
  136. output("CONFORMANCE_FAIL")
  137. while (True):
  138. cmd = input()
  139. // Process input
  140. if (cmd == "pause"):
  141. // Pausing merely stops a running simulation
  142. simulation_time = time() - start_time
  143. output("PAUSED")
  144. while (cmd != "simulate"):
  145. cmd = input()
  146. start_time = time() - simulation_time
  147. output("CONTINUE")
  148. elif (cmd == "event"):
  149. String evt
  150. evt = input()
  151. do_transition(runtime_model, start_time, evt)
  152. elif (cmd == "read_available_attributes"):
  153. // Returns a list of all available attributes
  154. Element attr_list
  155. Element attrs
  156. Element attr
  157. attr_list = getAttributeList(design_model, input())
  158. attrs = dict_keys(attr_list)
  159. while (0 < read_nr_out(attrs)):
  160. attr = set_pop(attrs)
  161. output("AVAILABLE_ATTR_VALUE " + cast_v2s(attr))
  162. output("AVAILABLE_ATTR_TYPE " + cast_v2s(dict_read(attr_list, attr)))
  163. output("AVAILABLE_ATTR_END")
  164. elif (cmd == "read_attribute"):
  165. // Returns the value of an attribute
  166. output("ATTR_VALUE " + cast_v2s(read_attribute(design_model, input(), input())))
  167. elif (bool_or(bool_or(cmd == "set_attribute", cmd == "instantiate_node"), bool_or(cmd == "delete_element", cmd == "instantiate_association"))):
  168. // Modify the structure
  169. if (cmd == "set_attribute"):
  170. // Setting an attribute
  171. String element_name
  172. String attribute_name
  173. element_name = input()
  174. attribute_name = input()
  175. // Delete it if it exists already
  176. if (bool_not(element_eq(read_attribute(design_model, element_name, attribute_name), read_root()))):
  177. unset_attribute(design_model, element_name, attribute_name)
  178. // And finally set it
  179. instantiate_attribute(design_model, element_name, attribute_name, input())
  180. elif (cmd == "instantiate_node"):
  181. // Instantiate a node
  182. instantiate_node(design_model, input(), input())
  183. elif (cmd == "instantiate_association"):
  184. // Instantiate an association
  185. instantiate_link(design_model, input(), input(), input(), input())
  186. elif (cmd == "delete_element"):
  187. // Delete the provided element
  188. model_delete_element(design_model, input())
  189. // After changes, we check whether or not the design model conforms
  190. if (conforming == "OK"):
  191. // Was correct, so store just to make sure
  192. simulation_time = time() - start_time
  193. conforming = conformance_scd(design_model)
  194. if (conforming == "OK"):
  195. // Conforming, so do the retyping and sanitization step
  196. runtime_model = retype_to_runtime(design_model)
  197. runtime_model = sanitize(runtime_model, old_runtime_model)
  198. schedule_init = create_schedule(runtime_model)
  199. schedule_run = read_root()
  200. old_runtime_model = runtime_model
  201. start_time = time() - simulation_time
  202. output("CONFORMANCE_OK")
  203. else:
  204. // Not conforming, so stop simulation and block for input (preferably a modify to make everything consistent again)
  205. output("CONFORMANCE_FAIL " + conforming)
  206. else:
  207. log("Did not understand command: " + cmd)
  208. Float function v2f(i : Element):
  209. return cast_s2f(cast_v2s(i))!