object_operations.alc 8.1 KB

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