model_management.alc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. include "primitives.alh"
  2. include "io.alh"
  3. include "object_operations.alh"
  4. include "constructors.alh"
  5. include "metamodels.alh"
  6. include "library.alh"
  7. include "modelling.alh"
  8. Element function model_fuse(models : Element):
  9. Element new_model
  10. Element tagged_model
  11. String model_name
  12. Element model
  13. Element keys
  14. String key
  15. Element selected_MM
  16. String type
  17. // Read out some data first
  18. tagged_model = set_pop(models)
  19. set_add(models, tagged_model)
  20. new_model = instantiate_model(tagged_model[1]["metamodel"])
  21. // Do the iteration
  22. while (read_nr_out(models)):
  23. tagged_model = set_pop(models)
  24. model_name = string_join(list_read(tagged_model, 0), "/")
  25. model = list_read(tagged_model, 1)
  26. // Add all elements from 'model', but prepend it with the 'model_name'
  27. keys = set_to_list(dict_keys(model["model"]))
  28. while (read_nr_out(keys) > 0):
  29. key = list_pop(keys, 0)
  30. type = read_type(model, key)
  31. if (is_edge(model["model"][key])):
  32. String src
  33. String dst
  34. src = model_name + reverseKeyLookup(model["model"], read_edge_src(model["model"][key]))
  35. dst = model_name + reverseKeyLookup(model["model"], read_edge_dst(model["model"][key]))
  36. if (bool_and(dict_in(new_model["model"], src), dict_in(new_model["model"], dst))):
  37. instantiate_link(new_model, type, model_name + key, src, dst)
  38. else:
  39. list_append(keys, key)
  40. elif (has_value(model["model"][key])):
  41. instantiate_value(new_model, type, model_name + key, model["model"][key])
  42. else:
  43. instantiate_node(new_model, type, model_name + key)
  44. return new_model!
  45. Element function model_copy(src_model : Element):
  46. Element dst_model
  47. Element queue
  48. Element name
  49. String type
  50. dst_model = instantiate_model(src_model["metamodel"])
  51. queue = set_to_list(dict_keys(src_model["model"]))
  52. while (read_nr_out(queue) > 0):
  53. name = list_pop(queue, 0)
  54. if (is_edge(src_model["model"][name])):
  55. // Is an edge, so potentially queue it
  56. String src
  57. String dst
  58. src = reverseKeyLookup(src_model["model"], read_edge_src(src_model["model"][name]))
  59. dst = reverseKeyLookup(src_model["model"], read_edge_dst(src_model["model"][name]))
  60. type = read_type(src_model, name)
  61. if (bool_and(dict_in(dst_model["model"], src), dict_in(dst_model["model"], dst))):
  62. // All present, so create the link between them
  63. instantiate_link(dst_model, type, name, src, dst)
  64. else:
  65. list_append(queue, name)
  66. elif (has_value(src_model["model"][name])):
  67. // Has a value, so copy that as well
  68. type = read_type(src_model, name)
  69. instantiate_value(dst_model, type, name, src_model["model"][name])
  70. else:
  71. // Is a node
  72. type = read_type(src_model, name)
  73. instantiate_node(dst_model, type, name)
  74. return dst_model!
  75. Element function model_retype_on_name(model : Element, new_MM : Element, operation : String, name : String):
  76. String key
  77. String type
  78. Element keys
  79. Integer length
  80. keys = dict_keys(model["model"])
  81. length = string_len(name)
  82. while (read_nr_out(keys) > 0):
  83. key = set_pop(keys)
  84. if (dict_in(model["model"], key)):
  85. // Check if the element is still there, as a delete of a node might remove all attached links automatically
  86. type = read_type(model, key)
  87. if (operation == "+"):
  88. // Keep all, but augment typename
  89. dict_delete(model["type_mapping"], key)
  90. dict_add(model["type_mapping"], key, name + type)
  91. elif (operation == "-"):
  92. // Keep only if typename beginning matches and remove from typename
  93. if (string_startswith(type, name)):
  94. dict_delete(model["type_mapping"], key)
  95. dict_add(model["type_mapping"], key, string_substr(type, length, string_len(type)))
  96. else:
  97. model_delete_element(model, key)
  98. dict_delete(model, "metamodel")
  99. dict_add(model, "metamodel", new_MM)
  100. return model!
  101. Void function model_join(dst_model : Element, src_model : Element, retyping_key : String):
  102. Element queue
  103. Element mapping
  104. String name
  105. String type
  106. String src
  107. String dst
  108. queue = set_to_list(dict_keys(src_model["model"]))
  109. mapping = create_node()
  110. while (read_nr_out(queue) > 0):
  111. name = list_pop(queue, 0)
  112. type = read_type(src_model, name)
  113. if (is_edge(src_model["model"][name])):
  114. // Is an edge, so potentially queue it
  115. String src
  116. String dst
  117. src = reverseKeyLookup(src_model["model"], read_edge_src(src_model["model"][name]))
  118. dst = reverseKeyLookup(src_model["model"], read_edge_dst(src_model["model"][name]))
  119. if (bool_and(dict_in(mapping, src), dict_in(mapping, dst))):
  120. // All present, so create the link between them
  121. dict_add(mapping, name, instantiate_link(dst_model, retyping_key + type, "", mapping[src], mapping[dst]))
  122. else:
  123. list_append(queue, name)
  124. elif (has_value(src_model["model"][name])):
  125. // Has a value, so copy that as well
  126. dict_add(mapping, name, instantiate_value(dst_model, retyping_key + type, "", src_model["model"][name]))
  127. else:
  128. // Is a node
  129. dict_add(mapping, name, instantiate_node(dst_model, retyping_key + type, ""))
  130. return!
  131. Element function model_split(src_model : Element, target_metamodel : Element, retyping_key : String):
  132. Element dst_model
  133. dst_model = instantiate_model(target_metamodel)
  134. Element queue
  135. Element mapping
  136. String name
  137. String type
  138. String src
  139. String dst
  140. Integer length
  141. String new_type
  142. queue = set_to_list(dict_keys(src_model["model"]))
  143. mapping = create_node()
  144. length = string_len(retyping_key)
  145. while (read_nr_out(queue) > 0):
  146. name = list_pop(queue, 0)
  147. type = read_type(src_model, name)
  148. if (string_startswith(type, retyping_key)):
  149. new_type = string_substr(type, length, string_len(type))
  150. if (is_edge(src_model["model"][name])):
  151. // Is an edge, so potentially queue it
  152. String src
  153. String dst
  154. src = reverseKeyLookup(src_model["model"], read_edge_src(src_model["model"][name]))
  155. dst = reverseKeyLookup(src_model["model"], read_edge_dst(src_model["model"][name]))
  156. if (bool_and(dict_in(mapping, src), dict_in(mapping, dst))):
  157. // All present, so create the link between them
  158. dict_add(mapping, name, instantiate_link(dst_model, new_type, "", mapping[src], mapping[dst]))
  159. elif (bool_not(bool_or(set_in(queue, src), set_in(queue, dst)))):
  160. // Source/target not in the queue, but we need it to split!
  161. // This is an error as it indicates problems with links crossing different formalisms
  162. log("ERROR: source/target of link to be included is not included!")
  163. log("Source: " + src)
  164. log(" type: " + read_type(src_model, src))
  165. log("Destination: " + dst)
  166. log(" type: " + read_type(src_model, dst))
  167. log("For link: " + name)
  168. log(" type: " + type)
  169. return create_node()!
  170. else:
  171. // Still source or destination in the queue, so we wait for that
  172. list_append(queue, name)
  173. elif (has_value(src_model["model"][name])):
  174. // Has a value, so copy that as well
  175. dict_add(mapping, name, instantiate_value(dst_model, new_type, "", src_model["model"][name]))
  176. else:
  177. // Is a node
  178. dict_add(mapping, name, instantiate_node(dst_model, new_type, ""))
  179. return dst_model!