model_management.alc 7.5 KB

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