object_operations.alc 6.7 KB

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