object_operations.alc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. include "primitives.alh"
  2. include "conformance_scd.alh"
  3. include "constructors.alh"
  4. include "modelling.alh"
  5. Element function allInstances(model : Element, type_name : String):
  6. if (dict_in(model["metamodel"]["model"], type_name)):
  7. Element result
  8. Element accepted
  9. Element keys
  10. Element tm
  11. String key
  12. result = create_node()
  13. accepted = get_subclasses(model["metamodel"], type_name)
  14. tm = model["type_mapping"]
  15. keys = dict_keys(tm)
  16. while (0 < list_len(keys)):
  17. key = set_pop(keys)
  18. if (set_in(accepted, tm[key])):
  19. set_add(result, key)
  20. return result!
  21. else:
  22. log("No such type in the metamodel: " + type_name)
  23. return create_node()!
  24. Element function selectPossibleIncoming(model : Element, target : String, limit_set : Element):
  25. // Find all possible incoming link types for the target model
  26. // Should also include those specified on the superclass(es)
  27. String type
  28. Element model_dict
  29. Element elem
  30. Element result
  31. Element target_element
  32. result = create_node()
  33. model_dict = model["model"]
  34. while (0 < list_len(limit_set)):
  35. type = set_pop(limit_set)
  36. elem = model_dict[type]
  37. if (is_nominal_subtype(model, target, reverseKeyLookup(model_dict, read_edge_dst(elem)))):
  38. set_add(result, type)
  39. return result!
  40. Element function selectPossibleOutgoing(model : Element, source : String, limit_set : Element):
  41. // Find all possible outgoing link types for the source model
  42. // Should also include those specified on the superclass(es)
  43. String type
  44. Element model_dict
  45. Element elem
  46. Element result
  47. Element source_element
  48. result = create_node()
  49. model_dict = model["model"]
  50. while (0 < list_len(limit_set)):
  51. type = set_pop(limit_set)
  52. elem = model_dict[type]
  53. if (is_nominal_subtype(model, source, reverseKeyLookup(model_dict, read_edge_src(elem)))):
  54. set_add(result, type)
  55. return result!
  56. Element function allOutgoingAssociationInstances(model : Element, source_name : String, assoc_name : String):
  57. // Read out all outgoing edges of the model and select those that are typed by the specified association
  58. Element result
  59. Element source
  60. String option
  61. Integer all_out
  62. Integer i
  63. result = create_node()
  64. source = model["model"][source_name]
  65. all_out = read_nr_out(source)
  66. i = 0
  67. while (i < all_out):
  68. option = reverseKeyLookup(model["model"], read_out(source, i))
  69. if (is_nominal_instance(model, option, assoc_name)):
  70. set_add(result, option)
  71. i = i + 1
  72. return result!
  73. Element function allIncomingAssociationInstances(model : Element, target_name : String, assoc_name : String):
  74. // Read out all outgoing edges of the model and select those that are typed by the specified association
  75. Element assocs
  76. String assoc
  77. Element result
  78. Element target
  79. assocs = allInstances(model, assoc_name)
  80. target = model["model"][target_name]
  81. result = create_node()
  82. while (0 < list_len(assocs)):
  83. assoc = set_pop(assocs)
  84. if (element_eq(target, read_edge_dst(model["model"][assoc]))):
  85. set_add(result, assoc)
  86. return result!
  87. Element function getAttributeList(model : Element, element : String):
  88. Element result
  89. Element keys
  90. Element type
  91. Element attr_name
  92. Element types
  93. String attr_type
  94. result = create_node()
  95. types = get_superclasses(model["metamodel"], read_type(model, element))
  96. while (read_nr_out(types) > 0):
  97. type = set_pop(types)
  98. keys = dict_keys(model["metamodel"]["model"][type])
  99. // Add our own attributes
  100. while (0 < list_len(keys)):
  101. attr_name = set_pop(keys)
  102. if (is_physical_string(attr_name)):
  103. attr_type = reverseKeyLookup(model["metamodel"]["model"], model["metamodel"]["model"][type][attr_name])
  104. dict_add(result, attr_name, attr_type)
  105. return result!
  106. Element function getInstantiatableAttributes(model : Element, element : String):
  107. // TODO check if this works!
  108. //output("WARNING: untested code triggered")
  109. Element all_links
  110. Element result
  111. String link
  112. result = create_node()
  113. all_links = allOutgoingAssociationInstances(model, element, "Attribute")
  114. while (read_nr_out(all_links) > 0):
  115. link = set_pop(all_links)
  116. dict_add(result, read_attribute(model, link, "name"), read_type(model, readAssociationDestination(model, link)))
  117. return result!
  118. Element function getInstantiatableAttributes_old(model : Element, element : String):
  119. Element result
  120. result = create_node()
  121. Element types
  122. types = get_superclasses(model, element)
  123. while (read_nr_out(types) > 0):
  124. element = set_pop(types)
  125. // Get all outgoing "dictionary" links
  126. Element set_own
  127. Element elem
  128. elem = model["model"][element]
  129. set_own = dict_keys(elem)
  130. // Filter them
  131. Element e
  132. while (0 < read_nr_out(set_own)):
  133. e = set_pop(set_own)
  134. if (is_physical_string(e)):
  135. dict_add(result, e, reverseKeyLookup(model["model"], elem[e]))
  136. return result!
  137. String function reverseKeyLookup(dict : Element, element : Element):
  138. Integer nr_in
  139. Integer nr_out
  140. Integer counter
  141. Element link
  142. nr_in = read_nr_in(element)
  143. counter = 0
  144. while (counter < nr_in):
  145. if (element_eq(read_edge_src(read_in(element, counter)), dict)):
  146. // Got a match
  147. return (read_edge_dst(read_out(read_in(element, counter), 0)))!
  148. counter = counter + 1
  149. return string_join(string_join("(unknown: ", cast_e2s(element)), " )")!
  150. String function print_dict(dict : Element):
  151. Element keys
  152. Element key
  153. String result
  154. keys = dict_keys(dict)
  155. result = ""
  156. while (0 < list_len(keys)):
  157. key = set_pop(keys)
  158. result = result + cast_v2s(key)
  159. result = result + ": "
  160. result = result + cast_v2s(dict[key])
  161. result = result + "\n"
  162. return result!
  163. String function readAssociationSource(model : Element, name : String):
  164. return reverseKeyLookup(model["model"], read_edge_src(model["model"][name]))!
  165. String function readAssociationDestination(model : Element, name : String):
  166. return reverseKeyLookup(model["model"], read_edge_dst(model["model"][name]))!
  167. String function followAssociation(model : Element, element_name : String, association_name : String):
  168. Element assocs
  169. String assoc
  170. Element result
  171. assocs = allOutgoingAssociationInstances(model, element_name, association_name)
  172. result = create_node()
  173. while (0 < list_len(assocs)):
  174. set_add(result, readAssociationDestination(model, set_pop(assocs)))
  175. return result!
  176. Element function allAssociationDestinations(model : Element, name : String, association_type : String):
  177. Element tmp
  178. Element result
  179. result = create_node()
  180. tmp = allOutgoingAssociationInstances(model, name, association_type)
  181. while (read_nr_out(tmp) > 0):
  182. set_add(result, readAssociationDestination(model, set_pop(tmp)))
  183. return result!
  184. Element function allAssociationOrigins(model : Element, name : String, association_type : String):
  185. Element tmp
  186. Element result
  187. result = create_node()
  188. tmp = allIncomingAssociationInstances(model, name, association_type)
  189. while (read_nr_out(tmp) > 0):
  190. set_add(result, readAssociationSource(model, set_pop(tmp)))
  191. return result!
  192. Element function allowedAssociationsBetween(model : Element, src : String, dst : String):
  193. // Go to the type and find all possibilities
  194. String type
  195. Element all_types
  196. Integer nr_edges
  197. Integer i
  198. Element result
  199. Element edge
  200. String edge_name
  201. String dst_name
  202. result = create_node()
  203. type = read_type(model, src)
  204. all_types = get_superclasses(model["metamodel"], type)
  205. while (read_nr_out(all_types) > 0):
  206. type = set_pop(all_types)
  207. nr_edges = read_nr_out(model["metamodel"]["model"][type])
  208. i = 0
  209. while (i < nr_edges):
  210. edge = read_out(model["metamodel"]["model"][type], i)
  211. if (set_in(model["metamodel"]["model"], edge)):
  212. // Find destination
  213. dst_name = reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(edge))
  214. edge_name = reverseKeyLookup(model["metamodel"]["model"], edge)
  215. if (is_nominal_instance(model, dst, dst_name)):
  216. // Find out whether our dst is an instance of the found destination type
  217. if (is_nominal_instance(model["metamodel"], edge_name, "Association")):
  218. set_add(result, edge_name)
  219. i = i + 1
  220. return result!
  221. String function read_type(model : Element, name : String):
  222. String result
  223. Element tm
  224. if (dict_in(model["model"], name)):
  225. if (dict_in(model["type_mapping"], name)):
  226. result = model["type_mapping"][name]
  227. if (dict_in(model["metamodel"]["model"], result)):
  228. return result!
  229. else:
  230. log("Could not find " + result)
  231. return ""!
  232. else:
  233. log("Untyped " + name)
  234. log("Type mapping: " + dict_to_string(model["type_mapping"]))
  235. return ""!
  236. else:
  237. log("Couldn't find type of " + name)
  238. return ""!