scd.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. from state.base import State, UUID
  2. from services.bottom.V0 import Bottom
  3. from services.primitives.boolean_type import Boolean
  4. from services.primitives.string_type import String
  5. from bootstrap.primitive import (
  6. bootstrap_primitive_types
  7. # bootstrap_boolean_type,
  8. # bootstrap_float_type,
  9. # bootstrap_integer_type,
  10. # bootstrap_string_type,
  11. # bootstrap_type_type,
  12. # bootstrap_actioncode_type
  13. )
  14. def create_model_root(bottom: Bottom, model_name: str) -> UUID:
  15. model_root = bottom.create_node()
  16. mcl_root_id = bottom.create_node(value=str(model_root))
  17. bottom.create_edge(bottom.state.read_root(), mcl_root_id, label=model_name)
  18. return model_root
  19. def bootstrap_scd(state: State) -> UUID:
  20. # init model roots and store their UUIDs attached to state root
  21. bottom = Bottom(state)
  22. mcl_root = create_model_root(bottom, "SCD")
  23. # Create model roots for primitive types
  24. integer_type_root = create_model_root(bottom, "Integer")
  25. boolean_type_root = create_model_root(bottom, "Boolean")
  26. string_type_root = create_model_root(bottom, "String")
  27. float_type_root = create_model_root(bottom, "Float")
  28. type_type_root = create_model_root(bottom, "Type")
  29. actioncode_type_root = create_model_root(bottom, "ActionCode")
  30. # create MCL, without morphism links
  31. def add_node_element(element_name, node_value=None):
  32. """ Helper function, adds node to model with given name and value """
  33. _node = bottom.create_node(value=node_value)
  34. bottom.create_edge(mcl_root, _node, element_name)
  35. return _node
  36. def add_edge_element(element_name, source, target):
  37. """ Helper function, adds edge to model with given name """
  38. _edge = bottom.create_edge(source, target)
  39. bottom.create_edge(mcl_root, _edge, element_name)
  40. return _edge
  41. def add_attribute_attributes(attribute_element_name, attribute_element):
  42. _name_model = bottom.create_node()
  43. _name_node = add_node_element(f"{attribute_element_name}.name", str(_name_model))
  44. _name_edge = add_edge_element(f"{attribute_element_name}_name", attribute_element, _name_node)
  45. _optional_model = bottom.create_node()
  46. _optional_node = add_node_element(f"{attribute_element_name}.optional", str(_optional_model))
  47. _optional_edge = add_edge_element(f"{attribute_element_name}_optional", attribute_element, _optional_node)
  48. return _name_model, _optional_model
  49. ##### SCD META-MODEL #####
  50. # # CLASSES, i.e. elements typed by Class
  51. # # Element
  52. element_node = add_node_element("Element")
  53. # # Class
  54. class_node = add_node_element("Class")
  55. # # Attribute
  56. attr_node = add_node_element("Attribute")
  57. # # ModelRef
  58. model_ref_node = add_node_element("ModelRef")
  59. # # Global Constraint
  60. glob_constr_node = add_node_element("GlobalConstraint")
  61. # # ASSOCIATIONS, i.e. elements typed by Association
  62. # # Association
  63. assoc_edge = add_edge_element("Association", class_node, class_node)
  64. # # Inheritance
  65. inh_edge = add_edge_element("Inheritance", element_node, element_node)
  66. # # Attribute Link
  67. attr_link_edge = add_edge_element("AttributeLink", element_node, attr_node)
  68. # # INHERITANCES, i.e. elements typed by Inheritance
  69. # # Class inherits from Element
  70. add_edge_element("class_inh_element", class_node, element_node)
  71. # # GlobalConstraint inherits from Element
  72. add_edge_element("gc_inh_element", glob_constr_node, element_node)
  73. # # Attribute inherits from Element
  74. add_edge_element("attr_inh_element", attr_node, element_node)
  75. # # Association inherits from Element
  76. add_edge_element("assoc_inh_element", assoc_edge, element_node)
  77. # # AttributeLink inherits from Element
  78. add_edge_element("attr_link_inh_element", attr_link_edge, element_node)
  79. # # ModelRef inherits from Attribute
  80. add_edge_element("model_ref_inh_attr", model_ref_node, attr_node)
  81. # # ATTRIBUTES, i.e. elements typed by Attribute
  82. # # Action Code # TODO: Update to ModelRef when action code is explicitly modelled
  83. # action_code_node = add_node_element("ActionCode")
  84. # # MODELREFS, i.e. elements typed by ModelRef
  85. # # Integer
  86. integer_node = add_node_element("Integer", str(integer_type_root))
  87. # # String
  88. string_node = add_node_element("String", str(string_type_root))
  89. # # Boolean
  90. boolean_node = add_node_element("Boolean", str(boolean_type_root))
  91. # # ActionCode
  92. actioncode_node = add_node_element("ActionCode", str(actioncode_type_root))
  93. # # ATTRIBUTE LINKS, i.e. elements typed by AttributeLink
  94. # # name attribute of AttributeLink
  95. attr_name_edge = add_edge_element("AttributeLink_name", attr_link_edge, string_node)
  96. # # optional attribute of AttributeLink
  97. attr_opt_edge = add_edge_element("AttributeLink_optional", attr_link_edge, boolean_node)
  98. # # constraint attribute of Element
  99. elem_constr_edge = add_edge_element("Element_constraint", element_node, actioncode_node)
  100. # # abstract attribute of Class
  101. class_abs_edge = add_edge_element("Class_abstract", class_node, boolean_node)
  102. # # multiplicity attributes of Class
  103. class_l_c_edge = add_edge_element("Class_lower_cardinality", class_node, integer_node)
  104. class_u_c_edge = add_edge_element("Class_upper_cardinality", class_node, integer_node)
  105. # # multiplicity attributes of Association
  106. assoc_s_l_c_edge = add_edge_element("Association_source_lower_cardinality", assoc_edge, integer_node)
  107. assoc_s_u_c_edge = add_edge_element("Association_source_upper_cardinality", assoc_edge, integer_node)
  108. assoc_t_l_c_edge = add_edge_element("Association_target_lower_cardinality", assoc_edge, integer_node)
  109. assoc_t_u_c_edge = add_edge_element("Association_target_upper_cardinality", assoc_edge, integer_node)
  110. # # bootstrap primitive types
  111. bootstrap_primitive_types(mcl_root, state,
  112. integer_type_root,
  113. boolean_type_root,
  114. float_type_root,
  115. string_type_root,
  116. type_type_root,
  117. actioncode_type_root)
  118. # bootstrap_integer_type(mcl_root, integer_type_root, integer_type_root, actioncode_type_root, state)
  119. # bootstrap_boolean_type(mcl_root, boolean_type_root, integer_type_root, actioncode_type_root, state)
  120. # bootstrap_float_type(mcl_root, float_type_root, integer_type_root, actioncode_type_root, state)
  121. # bootstrap_string_type(mcl_root, string_type_root, integer_type_root, actioncode_type_root, state)
  122. # bootstrap_type_type(mcl_root, type_type_root, integer_type_root, actioncode_type_root, state)
  123. # bootstrap_actioncode_type(mcl_root, actioncode_type_root, integer_type_root, actioncode_type_root, state)
  124. # # ATTRIBUTE ATTRIBUTES, assign 'name' and 'optional' attributes to all AttributeLinks
  125. # # AttributeLink_name
  126. m_name, m_opt = add_attribute_attributes("AttributeLink_name", attr_name_edge)
  127. String(m_name, state).create("name")
  128. Boolean(m_opt, state).create(False)
  129. # # AttributeLink_opt
  130. m_name, m_opt = add_attribute_attributes("AttributeLink_optional", attr_opt_edge)
  131. String(m_name, state).create("optional")
  132. Boolean(m_opt, state).create(False)
  133. # # Element_constraint
  134. m_name, m_opt = add_attribute_attributes("Element_constraint", elem_constr_edge)
  135. String(m_name, state).create("constraint")
  136. Boolean(m_opt, state).create(True)
  137. # # Class_abstract
  138. m_name, m_opt = add_attribute_attributes("Class_abstract", class_abs_edge)
  139. String(m_name, state).create("abstract")
  140. Boolean(m_opt, state).create(True)
  141. # # Class_lower_cardinality
  142. m_name, m_opt = add_attribute_attributes("Class_lower_cardinality", class_l_c_edge)
  143. String(m_name, state).create("lower_cardinality")
  144. Boolean(m_opt, state).create(True)
  145. # # Class_upper_cardinality
  146. m_name, m_opt = add_attribute_attributes("Class_upper_cardinality", class_u_c_edge)
  147. String(m_name, state).create("upper_cardinality")
  148. Boolean(m_opt, state).create(True)
  149. # # Association_source_lower_cardinality
  150. m_name, m_opt = add_attribute_attributes("Association_source_lower_cardinality", assoc_s_l_c_edge)
  151. String(m_name, state).create("source_lower_cardinality")
  152. Boolean(m_opt, state).create(True)
  153. # # Association_source_upper_cardinality
  154. m_name, m_opt = add_attribute_attributes("Association_source_upper_cardinality", assoc_s_u_c_edge)
  155. String(m_name, state).create("source_upper_cardinality")
  156. Boolean(m_opt, state).create(True)
  157. # # Association_target_lower_cardinality
  158. m_name, m_opt = add_attribute_attributes("Association_target_lower_cardinality", assoc_t_l_c_edge)
  159. String(m_name, state).create("target_lower_cardinality")
  160. Boolean(m_opt, state).create(True)
  161. # # Association_target_upper_cardinality
  162. m_name, m_opt = add_attribute_attributes("Association_target_upper_cardinality", assoc_t_u_c_edge)
  163. String(m_name, state).create("target_upper_cardinality")
  164. Boolean(m_opt, state).create(True)
  165. # # Make Element abstract
  166. abs_model = bottom.create_node()
  167. abs_node = add_node_element(f"Element.abstract", str(abs_model))
  168. abs_edge = add_edge_element(f"Element_abstract", element_node, abs_node)
  169. Boolean(abs_model, state).create(True)
  170. # create phi(SCD,SCD) to type MCL with itself
  171. def add_mcl_morphism(element_name, type_name):
  172. # get elements from mcl by name
  173. _element_edge, = bottom.read_outgoing_edges(mcl_root, element_name)
  174. _element_node = bottom.read_edge_target(_element_edge)
  175. _type_edge, = bottom.read_outgoing_edges(mcl_root, type_name)
  176. _type_node = bottom.read_edge_target(_type_edge)
  177. # create morphism link
  178. bottom.create_edge(_element_node, _type_node, "Morphism")
  179. # Class
  180. add_mcl_morphism("Element", "Class")
  181. add_mcl_morphism("Class", "Class")
  182. add_mcl_morphism("Attribute", "Class")
  183. add_mcl_morphism("ModelRef", "Class")
  184. add_mcl_morphism("GlobalConstraint", "Class")
  185. # Association
  186. add_mcl_morphism("Association", "Association")
  187. add_mcl_morphism("Inheritance", "Association")
  188. add_mcl_morphism("AttributeLink", "Association")
  189. # Inheritance
  190. add_mcl_morphism("class_inh_element", "Inheritance")
  191. add_mcl_morphism("gc_inh_element", "Inheritance")
  192. add_mcl_morphism("attr_inh_element", "Inheritance")
  193. add_mcl_morphism("assoc_inh_element", "Inheritance")
  194. add_mcl_morphism("attr_link_inh_element", "Inheritance")
  195. add_mcl_morphism("model_ref_inh_attr", "Inheritance")
  196. # Attribute
  197. # add_mcl_morphism("ActionCode", "Attribute")
  198. # ModelRef
  199. add_mcl_morphism("Integer", "ModelRef")
  200. add_mcl_morphism("String", "ModelRef")
  201. add_mcl_morphism("Boolean", "ModelRef")
  202. add_mcl_morphism("ActionCode", "ModelRef")
  203. # AttributeLink
  204. add_mcl_morphism("AttributeLink_name", "AttributeLink")
  205. add_mcl_morphism("AttributeLink_optional", "AttributeLink")
  206. add_mcl_morphism("Element_constraint", "AttributeLink")
  207. add_mcl_morphism("Class_abstract", "AttributeLink")
  208. add_mcl_morphism("Class_lower_cardinality", "AttributeLink")
  209. add_mcl_morphism("Class_upper_cardinality", "AttributeLink")
  210. add_mcl_morphism("Association_source_lower_cardinality", "AttributeLink")
  211. add_mcl_morphism("Association_source_upper_cardinality", "AttributeLink")
  212. add_mcl_morphism("Association_target_lower_cardinality", "AttributeLink")
  213. add_mcl_morphism("Association_target_upper_cardinality", "AttributeLink")
  214. # AttributeLink_name
  215. add_mcl_morphism("AttributeLink_name_name", "AttributeLink_name")
  216. add_mcl_morphism("AttributeLink_optional_name", "AttributeLink_name")
  217. add_mcl_morphism("Element_constraint_name", "AttributeLink_name")
  218. add_mcl_morphism("Class_abstract_name", "AttributeLink_name")
  219. add_mcl_morphism("Class_lower_cardinality_name", "AttributeLink_name")
  220. add_mcl_morphism("Class_upper_cardinality_name", "AttributeLink_name")
  221. add_mcl_morphism("Association_source_lower_cardinality_name", "AttributeLink_name")
  222. add_mcl_morphism("Association_source_upper_cardinality_name", "AttributeLink_name")
  223. add_mcl_morphism("Association_target_lower_cardinality_name", "AttributeLink_name")
  224. add_mcl_morphism("Association_target_upper_cardinality_name", "AttributeLink_name")
  225. # AttributeLink_optional
  226. add_mcl_morphism("AttributeLink_name_optional", "AttributeLink_optional")
  227. add_mcl_morphism("AttributeLink_optional_optional", "AttributeLink_optional")
  228. add_mcl_morphism("Element_constraint_optional", "AttributeLink_optional")
  229. add_mcl_morphism("Class_abstract_optional", "AttributeLink_optional")
  230. add_mcl_morphism("Class_lower_cardinality_optional", "AttributeLink_optional")
  231. add_mcl_morphism("Class_upper_cardinality_optional", "AttributeLink_optional")
  232. add_mcl_morphism("Association_source_lower_cardinality_optional", "AttributeLink_optional")
  233. add_mcl_morphism("Association_source_upper_cardinality_optional", "AttributeLink_optional")
  234. add_mcl_morphism("Association_target_lower_cardinality_optional", "AttributeLink_optional")
  235. add_mcl_morphism("Association_target_upper_cardinality_optional", "AttributeLink_optional")
  236. # String
  237. add_mcl_morphism("AttributeLink_name.name", "String")
  238. add_mcl_morphism("AttributeLink_optional.name", "String")
  239. add_mcl_morphism("Element_constraint.name", "String")
  240. add_mcl_morphism("Class_abstract.name", "String")
  241. add_mcl_morphism("Class_lower_cardinality.name", "String")
  242. add_mcl_morphism("Class_upper_cardinality.name", "String")
  243. add_mcl_morphism("Association_source_lower_cardinality.name", "String")
  244. add_mcl_morphism("Association_source_upper_cardinality.name", "String")
  245. add_mcl_morphism("Association_target_lower_cardinality.name", "String")
  246. add_mcl_morphism("Association_target_upper_cardinality.name", "String")
  247. # Boolean
  248. add_mcl_morphism("AttributeLink_name.optional", "Boolean")
  249. add_mcl_morphism("AttributeLink_optional.optional", "Boolean")
  250. add_mcl_morphism("Element_constraint.optional", "Boolean")
  251. add_mcl_morphism("Class_abstract.optional", "Boolean")
  252. add_mcl_morphism("Class_lower_cardinality.optional", "Boolean")
  253. add_mcl_morphism("Class_upper_cardinality.optional", "Boolean")
  254. add_mcl_morphism("Association_source_lower_cardinality.optional", "Boolean")
  255. add_mcl_morphism("Association_source_upper_cardinality.optional", "Boolean")
  256. add_mcl_morphism("Association_target_lower_cardinality.optional", "Boolean")
  257. add_mcl_morphism("Association_target_upper_cardinality.optional", "Boolean")
  258. add_mcl_morphism("Element.abstract", "Boolean")
  259. # Class_abstract
  260. add_mcl_morphism("Element_abstract", "Class_abstract")
  261. return mcl_root
  262. if __name__ == '__main__':
  263. from state.devstate import DevState as State
  264. s = State()
  265. bootstrap_scd(s)
  266. r = s.read_root()
  267. for n in s.read_dict_keys(r):
  268. print(s.read_value(n))