object_operations.alc 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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. if (dict_in(model["metamodel"]["model"], type_name)):
  12. type = model["metamodel"]["model"][type_name]
  13. result = create_node()
  14. // TODO more efficient to work backwards: find all instances of an element through the type mapping directly
  15. // must then take into account all inheritance links ourselves...
  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 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. Element result
  108. result = create_node()
  109. Element types
  110. types = get_superclasses(model, element)
  111. while (read_nr_out(types) > 0):
  112. element = set_pop(types)
  113. // Get all outgoing "dictionary" links
  114. Element set_own
  115. Element elem
  116. elem = model["model"][element]
  117. set_own = dict_keys(elem)
  118. // Filter them
  119. Element e
  120. while (0 < read_nr_out(set_own)):
  121. e = set_pop(set_own)
  122. if (is_physical_string(e)):
  123. dict_add(result, e, reverseKeyLookup(model["model"], elem[e]))
  124. return result!
  125. String function reverseKeyLookup(dict : Element, element : Element):
  126. Integer nr_in
  127. Integer nr_out
  128. Integer counter
  129. Element link
  130. nr_in = read_nr_in(element)
  131. counter = 0
  132. while (counter < nr_in):
  133. if (element_eq(read_edge_src(read_in(element, counter)), dict)):
  134. // Got a match
  135. return (read_edge_dst(read_out(read_in(element, counter), 0)))!
  136. counter = counter + 1
  137. return string_join(string_join("(unknown: ", cast_e2s(element)), " )")!
  138. String function print_dict(dict : Element):
  139. Element keys
  140. Element key
  141. String result
  142. keys = dict_keys(dict)
  143. result = ""
  144. while (0 < list_len(keys)):
  145. key = set_pop(keys)
  146. result = result + cast_v2s(key)
  147. result = result + ": "
  148. result = result + cast_v2s(dict[key])
  149. result = result + "\n"
  150. return result!
  151. String function readAssociationSource(model : Element, name : String):
  152. return reverseKeyLookup(model["model"], read_edge_src(model["model"][name]))!
  153. String function readAssociationDestination(model : Element, name : String):
  154. return reverseKeyLookup(model["model"], read_edge_dst(model["model"][name]))!
  155. String function followAssociation(model : Element, element_name : String, association_name : String):
  156. Element assocs
  157. String assoc
  158. Element result
  159. assocs = allOutgoingAssociationInstances(model, element_name, association_name)
  160. result = create_node()
  161. while (0 < list_len(assocs)):
  162. set_add(result, readAssociationDestination(model, set_pop(assocs)))
  163. return result!
  164. Element function allAssociationDestinations(model : Element, name : String, association_type : String):
  165. Element tmp
  166. Element result
  167. result = create_node()
  168. tmp = allOutgoingAssociationInstances(model, name, association_type)
  169. while (read_nr_out(tmp) > 0):
  170. set_add(result, readAssociationDestination(model, set_pop(tmp)))
  171. return result!
  172. Element function allowedAssociationsBetween(model : Element, src : String, dst : String):
  173. // Go to the type and find all possibilities
  174. String type
  175. Element all_types
  176. Integer nr_edges
  177. Integer i
  178. Element result
  179. Element edge
  180. String edge_name
  181. String dst_name
  182. result = create_node()
  183. type = read_type(model, src)
  184. all_types = get_superclasses(model["metamodel"], type)
  185. while (read_nr_out(all_types) > 0):
  186. type = set_pop(all_types)
  187. nr_edges = read_nr_out(model["metamodel"]["model"][type])
  188. i = 0
  189. while (i < nr_edges):
  190. edge = read_out(model["metamodel"]["model"][type], i)
  191. if (set_in(model["metamodel"]["model"], edge)):
  192. // Find destination
  193. dst_name = reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(edge))
  194. edge_name = reverseKeyLookup(model["metamodel"]["model"], edge)
  195. if (is_nominal_instance(model, dst, dst_name)):
  196. // Find out whether our dst is an instance of the found destination type
  197. set_add(result, edge_name)
  198. i = i + 1
  199. return result!
  200. String function read_type(model : Element, name : String):
  201. String result
  202. Element tm
  203. if (dict_in(model["model"], name)):
  204. if (dict_in(model["type_mapping"], name)):
  205. result = model["type_mapping"][name]
  206. if (dict_in(model["metamodel"]["model"], result)):
  207. return result!
  208. else:
  209. log("Could not find " + result)
  210. return ""!
  211. else:
  212. log("Untyped " + name)
  213. log("Type mapping: " + dict_to_string(model["type_mapping"]))
  214. return ""!
  215. else:
  216. log("Couldn't find type of " + name)
  217. return ""!