object_operations.alc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. include "primitives.alh"
  2. include "conformance_scd.alh"
  3. include "constructors.alh"
  4. include "modelling.alh"
  5. include "typing.alh"
  6. Element function allInstances(model : Element, type_name : String):
  7. if (dict_in(model["metamodel"]["model"], type_name)):
  8. Element result
  9. Element accepted
  10. Element keys
  11. Element tm
  12. String key
  13. String class
  14. Element results
  15. result = set_create()
  16. accepted = get_subclasses(model["metamodel"], type_name)
  17. while (set_len(accepted) > 0):
  18. class = set_pop(accepted)
  19. set_merge(result, elements_typed_by(model, class))
  20. return result!
  21. else:
  22. log("No such type in the metamodel: " + type_name)
  23. return set_create()!
  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 = set_create()
  33. model_dict = model["model"]
  34. while (list_len(limit_set) > 0):
  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 = set_create()
  49. model_dict = model["model"]
  50. while (list_len(limit_set) > 0):
  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 = set_create()
  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 (option != ""):
  70. if (assoc_name != ""):
  71. if (is_nominal_instance(model, option, assoc_name)):
  72. set_add(result, option)
  73. else:
  74. set_add(result, option)
  75. i = i + 1
  76. return result!
  77. Element function allIncomingAssociationInstances(model : Element, target_name : String, assoc_name : String):
  78. // Read out all outgoing edges of the model and select those that are typed by the specified association
  79. Element result
  80. Element source
  81. String option
  82. Integer all_out
  83. Integer i
  84. result = set_create()
  85. source = model["model"][target_name]
  86. all_out = read_nr_in(source)
  87. i = 0
  88. while (i < all_out):
  89. option = reverseKeyLookup(model["model"], read_in(source, i))
  90. if (option != ""):
  91. if (assoc_name != ""):
  92. if (is_nominal_instance(model, option, assoc_name)):
  93. set_add(result, option)
  94. else:
  95. set_add(result, option)
  96. i = i + 1
  97. return result!
  98. Element function getAttributeList(model : Element, element : String):
  99. Element result
  100. Element keys
  101. Element type
  102. Element attr_name
  103. Element types
  104. Element mm
  105. String attr_type
  106. result = dict_create()
  107. mm = model["metamodel"]["model"]
  108. types = get_superclasses(model["metamodel"], read_type(model, element))
  109. while (set_len(types) > 0):
  110. type = set_pop(types)
  111. // Add our own attributes
  112. keys = dict_keys(mm[type])
  113. while (set_len(keys) > 0):
  114. attr_name = set_pop(keys)
  115. if (is_physical_string(attr_name)):
  116. if (read_type(model["metamodel"], reverseKeyLookup(mm, dict_read_edge(mm[type], attr_name))) == "AttributeLink"):
  117. attr_type = reverseKeyLookup(mm, mm[type][attr_name])
  118. // WARNING: do not change this to dict_add_fast, as this crashes random code...
  119. dict_add(result, attr_name, attr_type)
  120. return result!
  121. Element function getAttributes(model : Element, element : String):
  122. Element result
  123. Element keys
  124. Element type
  125. Element attr_name
  126. Element types
  127. Element mm
  128. result = dict_create()
  129. mm = model["metamodel"]["model"]
  130. types = get_superclasses(model["metamodel"], read_type(model, element))
  131. while (set_len(types) > 0):
  132. type = set_pop(types)
  133. // Add our own attributes
  134. keys = dict_keys(mm[type])
  135. while (set_len(keys) > 0):
  136. attr_name = set_pop(keys)
  137. if (is_physical_string(attr_name)):
  138. // WARNING: do not change this to dict_add_fast, as this crashes random code...
  139. dict_add(result, attr_name, read_attribute(model, element, attr_name))
  140. return result!
  141. Element function getAttributeOptionality(model : Element, element : String, type : String):
  142. Element all_links
  143. Element result
  144. String link
  145. Element types
  146. result = dict_create()
  147. types = get_superclasses(model, element)
  148. while (set_len(types) > 0):
  149. element = set_pop(types)
  150. all_links = allOutgoingAssociationInstances(model, element, type)
  151. while (set_len(all_links) > 0):
  152. link = set_pop(all_links)
  153. if (value_eq(read_attribute(model, link, "optional"), True)):
  154. dict_add(result, read_attribute(model, link, "name"), True)
  155. else:
  156. dict_add(result, read_attribute(model, link, "name"), False)
  157. return result!
  158. Element function getInstantiatableAttributes(model : Element, element : String, type : String):
  159. Element all_links
  160. Element result
  161. String link
  162. Element types
  163. result = dict_create()
  164. types = get_superclasses(model, element)
  165. while (set_len(types) > 0):
  166. element = set_pop(types)
  167. all_links = allOutgoingAssociationInstances(model, element, type)
  168. while (set_len(all_links) > 0):
  169. link = set_pop(all_links)
  170. // WARNING: do not change this to dict_add_fast, as this crashes random code...
  171. dict_add(result, read_attribute(model, link, "name"), readAssociationDestination(model, link))
  172. return result!
  173. String function print_dict(dict : Element):
  174. Element keys
  175. Element key
  176. String result
  177. keys = dict_keys(dict)
  178. result = ""
  179. while (0 < list_len(keys)):
  180. key = set_pop(keys)
  181. result = result + cast_value(key)
  182. result = result + ": "
  183. result = result + cast_value(dict[key])
  184. result = result + "\n"
  185. return result!
  186. String function readAssociationSource(model : Element, name : String):
  187. return reverseKeyLookup(model["model"], read_edge_src(model["model"][name]))!
  188. String function readAssociationDestination(model : Element, name : String):
  189. return reverseKeyLookup(model["model"], read_edge_dst(model["model"][name]))!
  190. String function anAssociationDestination(model : Element, name : String, association_type : String):
  191. Element tmp
  192. Element result
  193. String val
  194. result = set_create()
  195. tmp = allOutgoingAssociationInstances(model, name, association_type)
  196. while (set_len(tmp) > 0):
  197. val = readAssociationDestination(model, set_pop(tmp))
  198. if (val != ""):
  199. return val!
  200. return ""!
  201. Element function allAssociationDestinations(model : Element, name : String, association_type : String):
  202. Element tmp
  203. Element result
  204. String val
  205. result = set_create()
  206. tmp = allOutgoingAssociationInstances(model, name, association_type)
  207. while (set_len(tmp) > 0):
  208. val = readAssociationDestination(model, set_pop(tmp))
  209. if (val != ""):
  210. set_add(result, val)
  211. return result!
  212. String function anAssociationOrigin(model : Element, name : String, association_type : String):
  213. Element tmp
  214. Element result
  215. String val
  216. result = set_create()
  217. tmp = allIncomingAssociationInstances(model, name, association_type)
  218. while (set_len(tmp) > 0):
  219. val = readAssociationSource(model, set_pop(tmp))
  220. if (val != ""):
  221. return val!
  222. return ""!
  223. Element function allAssociationOrigins(model : Element, name : String, association_type : String):
  224. Element tmp
  225. Element result
  226. String val
  227. result = set_create()
  228. tmp = allIncomingAssociationInstances(model, name, association_type)
  229. while (set_len(tmp) > 0):
  230. val = readAssociationSource(model, set_pop(tmp))
  231. if (val != ""):
  232. set_add(result, val)
  233. return result!
  234. Element function allowedAssociationsBetween(model : Element, src : String, dst : String):
  235. // Go to the type and find all possibilities
  236. String type
  237. Element all_types
  238. Integer nr_edges
  239. Integer i
  240. Element result
  241. Element edge
  242. String edge_name
  243. String dst_name
  244. result = set_create()
  245. type = read_type(model, src)
  246. all_types = get_superclasses(model["metamodel"], type)
  247. while (set_len(all_types) > 0):
  248. type = set_pop(all_types)
  249. nr_edges = read_nr_out(model["metamodel"]["model"][type])
  250. i = 0
  251. while (i < nr_edges):
  252. edge = read_out(model["metamodel"]["model"][type], i)
  253. edge_name = reverseKeyLookup(model["metamodel"]["model"], edge)
  254. if (dict_in(model["metamodel"]["model"], edge_name)):
  255. // Find destination
  256. dst_name = reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(edge))
  257. if (is_nominal_instance(model, dst, dst_name)):
  258. // Find out whether our dst is an instance of the found destination type
  259. if (is_nominal_instance(model["metamodel"], edge_name, "Association")):
  260. set_add(result, edge_name)
  261. i = i + 1
  262. return result!