object_operations.alc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. include "primitives.alh"
  2. include "conformance_scd.alh"
  3. include "constructors.alh"
  4. include "modelling.alh"
  5. include "typing.alh"
  6. Element function allInstances(model : Element, type_name : String):
  7. if (dict_in(model["metamodel"]["model"], type_name)):
  8. Element result
  9. Element accepted
  10. Element keys
  11. Element tm
  12. String key
  13. String class
  14. Element results
  15. result = set_create()
  16. accepted = get_subclasses(model["metamodel"], type_name)
  17. Element dict_mapping
  18. dict_mapping = get_type_mapping_as_dict(model)
  19. while (set_len(accepted) > 0):
  20. class = set_pop(accepted)
  21. set_merge(result, reverseKeyLookupMulti(dict_mapping, class))
  22. return result!
  23. else:
  24. log("No such type in the metamodel: " + type_name)
  25. return set_create()!
  26. Element function selectPossibleIncoming(model : Element, target : String, limit_set : Element):
  27. // Find all possible incoming link types for the target model
  28. // Should also include those specified on the superclass(es)
  29. String type
  30. Element model_dict
  31. Element elem
  32. Element result
  33. Element target_element
  34. result = set_create()
  35. model_dict = model["model"]
  36. while (list_len(limit_set) > 0):
  37. type = set_pop(limit_set)
  38. elem = model_dict[type]
  39. if (is_nominal_subtype(model, target, reverseKeyLookup(model_dict, read_edge_dst(elem)))):
  40. set_add(result, type)
  41. return result!
  42. Element function selectPossibleOutgoing(model : Element, source : String, limit_set : Element):
  43. // Find all possible outgoing link types for the source model
  44. // Should also include those specified on the superclass(es)
  45. String type
  46. Element model_dict
  47. Element elem
  48. Element result
  49. Element source_element
  50. result = set_create()
  51. model_dict = model["model"]
  52. while (list_len(limit_set) > 0):
  53. type = set_pop(limit_set)
  54. elem = model_dict[type]
  55. if (is_nominal_subtype(model, source, reverseKeyLookup(model_dict, read_edge_src(elem)))):
  56. set_add(result, type)
  57. return result!
  58. Element function allOutgoingAssociationInstances(model : Element, source_name : String, assoc_name : String):
  59. // Read out all outgoing edges of the model and select those that are typed by the specified association
  60. Element result
  61. Element source
  62. String option
  63. Integer all_out
  64. Integer i
  65. result = set_create()
  66. source = model["model"][source_name]
  67. all_out = read_nr_out(source)
  68. i = 0
  69. while (i < all_out):
  70. option = reverseKeyLookup(model["model"], read_out(source, i))
  71. if (is_nominal_instance(model, option, assoc_name)):
  72. set_add(result, option)
  73. i = i + 1
  74. return result!
  75. Element function allIncomingAssociationInstances(model : Element, target_name : String, assoc_name : String):
  76. // Read out all outgoing edges of the model and select those that are typed by the specified association
  77. Element result
  78. Element source
  79. String option
  80. Integer all_out
  81. Integer i
  82. result = set_create()
  83. source = model["model"][target_name]
  84. all_out = read_nr_in(source)
  85. i = 0
  86. while (i < all_out):
  87. option = reverseKeyLookup(model["model"], read_in(source, i))
  88. if (is_nominal_instance(model, option, assoc_name)):
  89. set_add(result, option)
  90. i = i + 1
  91. return result!
  92. Element function getAttributeList(model : Element, element : String):
  93. Element result
  94. Element keys
  95. Element type
  96. Element attr_name
  97. Element types
  98. Element mm
  99. String attr_type
  100. result = dict_create()
  101. mm = model["metamodel"]["model"]
  102. types = get_superclasses(model["metamodel"], read_type(model, element))
  103. while (set_len(types) > 0):
  104. type = set_pop(types)
  105. // Add our own attributes
  106. keys = dict_keys(mm[type])
  107. while (set_len(keys) > 0):
  108. attr_name = set_pop(keys)
  109. if (is_physical_string(attr_name)):
  110. attr_type = reverseKeyLookup(mm, mm[type][attr_name])
  111. // WARNING: do not change this to dict_add_fast, as this crashes random code...
  112. dict_add(result, attr_name, attr_type)
  113. return result!
  114. Element function getInstantiatableAttributes(model : Element, element : String):
  115. Element all_links
  116. Element result
  117. String link
  118. result = dict_create()
  119. all_links = allOutgoingAssociationInstances(model, element, "Attribute")
  120. while (set_len(all_links) > 0):
  121. link = set_pop(all_links)
  122. // WARNING: do not change this to dict_add_fast, as this crashes random code...
  123. dict_add(result, read_attribute(model, link, "name"), read_type(model, readAssociationDestination(model, link)))
  124. return result!
  125. String function print_dict(dict : Element):
  126. Element keys
  127. Element key
  128. String result
  129. keys = dict_keys(dict)
  130. result = ""
  131. while (0 < list_len(keys)):
  132. key = set_pop(keys)
  133. result = result + cast_v2s(key)
  134. result = result + ": "
  135. result = result + cast_v2s(dict[key])
  136. result = result + "\n"
  137. return result!
  138. String function readAssociationSource(model : Element, name : String):
  139. return reverseKeyLookup(model["model"], read_edge_src(model["model"][name]))!
  140. String function readAssociationDestination(model : Element, name : String):
  141. return reverseKeyLookup(model["model"], read_edge_dst(model["model"][name]))!
  142. Element function allAssociationDestinations(model : Element, name : String, association_type : String):
  143. Element tmp
  144. Element result
  145. result = set_create()
  146. tmp = allOutgoingAssociationInstances(model, name, association_type)
  147. while (set_len(tmp) > 0):
  148. set_add(result, readAssociationDestination(model, set_pop(tmp)))
  149. return result!
  150. Element function allAssociationOrigins(model : Element, name : String, association_type : String):
  151. Element tmp
  152. Element result
  153. result = set_create()
  154. tmp = allIncomingAssociationInstances(model, name, association_type)
  155. while (set_len(tmp) > 0):
  156. set_add(result, readAssociationSource(model, set_pop(tmp)))
  157. return result!
  158. Element function allowedAssociationsBetween(model : Element, src : String, dst : String):
  159. // Go to the type and find all possibilities
  160. String type
  161. Element all_types
  162. Integer nr_edges
  163. Integer i
  164. Element result
  165. Element edge
  166. String edge_name
  167. String dst_name
  168. result = set_create()
  169. type = read_type(model, src)
  170. all_types = get_superclasses(model["metamodel"], type)
  171. while (set_len(all_types) > 0):
  172. type = set_pop(all_types)
  173. nr_edges = read_nr_out(model["metamodel"]["model"][type])
  174. i = 0
  175. while (i < nr_edges):
  176. edge = read_out(model["metamodel"]["model"][type], i)
  177. edge_name = reverseKeyLookup(model["metamodel"]["model"], edge)
  178. if (dict_in(model["metamodel"]["model"], edge_name)):
  179. // Find destination
  180. dst_name = reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(edge))
  181. if (is_nominal_instance(model, dst, dst_name)):
  182. // Find out whether our dst is an instance of the found destination type
  183. if (is_nominal_instance(model["metamodel"], edge_name, "Association")):
  184. set_add(result, edge_name)
  185. i = i + 1
  186. return result!