object_operations.alc 7.4 KB

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