object_operations.alc 7.2 KB

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