model_management.alc 7.3 KB

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