object_operations.alc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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. // Add our own attributes
  99. keys = dict_keys(model["metamodel"]["model"][type])
  100. while (read_nr_out(keys) > 0):
  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. // WARNING: do not change this to dict_add_fast, as this crashes random code...
  105. dict_add(result, attr_name, attr_type)
  106. return result!
  107. Element function getInstantiatableAttributes(model : Element, element : String):
  108. // TODO check if this works!
  109. //output("WARNING: untested code triggered")
  110. Element all_links
  111. Element result
  112. String link
  113. result = create_node()
  114. all_links = allOutgoingAssociationInstances(model, element, "Attribute")
  115. while (read_nr_out(all_links) > 0):
  116. link = set_pop(all_links)
  117. // WARNING: do not change this to dict_add_fast, as this crashes random code...
  118. dict_add(result, read_attribute(model, link, "name"), read_type(model, readAssociationDestination(model, link)))
  119. return result!
  120. String function reverseKeyLookup(dict : Element, element : Element):
  121. Integer nr_in
  122. Integer nr_out
  123. Integer counter
  124. Element link
  125. nr_in = read_nr_in(element)
  126. counter = 0
  127. while (counter < nr_in):
  128. if (element_eq(read_edge_src(read_in(element, counter)), dict)):
  129. // Got a match
  130. return (read_edge_dst(read_out(read_in(element, counter), 0)))!
  131. counter = counter + 1
  132. return string_join(string_join("(unknown: ", cast_e2s(element)), " )")!
  133. String function print_dict(dict : Element):
  134. Element keys
  135. Element key
  136. String result
  137. keys = dict_keys(dict)
  138. result = ""
  139. while (0 < list_len(keys)):
  140. key = set_pop(keys)
  141. result = result + cast_v2s(key)
  142. result = result + ": "
  143. result = result + cast_v2s(dict[key])
  144. result = result + "\n"
  145. return result!
  146. String function readAssociationSource(model : Element, name : String):
  147. return reverseKeyLookup(model["model"], read_edge_src(model["model"][name]))!
  148. String function readAssociationDestination(model : Element, name : String):
  149. return reverseKeyLookup(model["model"], read_edge_dst(model["model"][name]))!
  150. String function followAssociation(model : Element, element_name : String, association_name : String):
  151. Element assocs
  152. String assoc
  153. Element result
  154. assocs = allOutgoingAssociationInstances(model, element_name, association_name)
  155. result = create_node()
  156. while (0 < list_len(assocs)):
  157. set_add(result, readAssociationDestination(model, set_pop(assocs)))
  158. return result!
  159. Element function allAssociationDestinations(model : Element, name : String, association_type : String):
  160. Element tmp
  161. Element result
  162. result = create_node()
  163. tmp = allOutgoingAssociationInstances(model, name, association_type)
  164. while (read_nr_out(tmp) > 0):
  165. set_add(result, readAssociationDestination(model, set_pop(tmp)))
  166. return result!
  167. Element function allAssociationOrigins(model : Element, name : String, association_type : String):
  168. Element tmp
  169. Element result
  170. result = create_node()
  171. tmp = allIncomingAssociationInstances(model, name, association_type)
  172. while (read_nr_out(tmp) > 0):
  173. set_add(result, readAssociationSource(model, set_pop(tmp)))
  174. return result!
  175. Element function allowedAssociationsBetween(model : Element, src : String, dst : String):
  176. // Go to the type and find all possibilities
  177. String type
  178. Element all_types
  179. Integer nr_edges
  180. Integer i
  181. Element result
  182. Element edge
  183. String edge_name
  184. String dst_name
  185. result = create_node()
  186. type = read_type(model, src)
  187. all_types = get_superclasses(model["metamodel"], type)
  188. while (read_nr_out(all_types) > 0):
  189. type = set_pop(all_types)
  190. nr_edges = read_nr_out(model["metamodel"]["model"][type])
  191. i = 0
  192. while (i < nr_edges):
  193. edge = read_out(model["metamodel"]["model"][type], i)
  194. if (set_in(model["metamodel"]["model"], edge)):
  195. // Find destination
  196. dst_name = reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(edge))
  197. edge_name = reverseKeyLookup(model["metamodel"]["model"], edge)
  198. if (is_nominal_instance(model, dst, dst_name)):
  199. // Find out whether our dst is an instance of the found destination type
  200. if (is_nominal_instance(model["metamodel"], edge_name, "Association")):
  201. set_add(result, edge_name)
  202. i = i + 1
  203. return result!
  204. String function read_type(model : Element, name : String):
  205. String result
  206. Element tm
  207. if (dict_in(model["model"], name)):
  208. if (dict_in(model["type_mapping"], name)):
  209. result = model["type_mapping"][name]
  210. if (dict_in(model["metamodel"]["model"], result)):
  211. return result!
  212. else:
  213. log("Could not find " + result)
  214. return ""!
  215. else:
  216. log("Untyped " + name)
  217. log("Type mapping: " + dict_to_string(model["type_mapping"]))
  218. return ""!
  219. else:
  220. log("Couldn't find type of " + name)
  221. return ""!