exp_scd.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. # Simple Class Diagram experiment
  2. from state.devstate import DevState
  3. from bootstrap.scd import bootstrap_scd
  4. from uuid import UUID
  5. from services.scd import SCD
  6. from framework.conformance import Conformance
  7. from services.od import OD
  8. from transformation.ramify import ramify
  9. from transformation import rewriter
  10. from services.bottom.V0 import Bottom
  11. from services.primitives.integer_type import Integer
  12. from pattern_matching import mvs_adapter
  13. from pattern_matching.matcher import MatcherVF2
  14. import sys
  15. def create_integer_node(state, i: int):
  16. node = state.create_node()
  17. integer_t = Integer(node, state)
  18. integer_t.create(i)
  19. return node
  20. def main():
  21. state = DevState()
  22. root = state.read_root() # id: 0
  23. scd_mm_id = bootstrap_scd(state)
  24. int_mm_id = UUID(state.read_value(state.read_dict(state.read_root(), "Integer")))
  25. string_mm_id = UUID(state.read_value(state.read_dict(state.read_root(), "String")))
  26. # def print_tree(root, max_depth, depth=0):
  27. # print(" "*depth, "root=", root, "value=", state.read_value(root))
  28. # src,tgt = state.read_edge(root)
  29. # if src != None:
  30. # print(" "*depth, "src...")
  31. # print_tree(src, max_depth, depth+1)
  32. # if tgt != None:
  33. # print(" "*depth, "tgt...")
  34. # print_tree(tgt, max_depth, depth+1)
  35. # for edge in state.read_outgoing(root):
  36. # for edge_label in state.read_outgoing(edge):
  37. # [_,tgt] = state.read_edge(edge_label)
  38. # label = state.read_value(tgt)
  39. # print(" "*depth, " key:", label)
  40. # [_, tgt] = state.read_edge(edge)
  41. # value = state.read_value(tgt)
  42. # if value != None:
  43. # print(" "*depth, " ->", tgt, " (value:", value, ")")
  44. # else:
  45. # print(" "*depth, " ->", tgt)
  46. # if depth < max_depth:
  47. # if isinstance(value, str) and len(value) == 36:
  48. # i = None
  49. # try:
  50. # i = UUID(value)
  51. # except ValueError as e:
  52. # # print("invalid UUID:", value)
  53. # pass
  54. # if i != None:
  55. # print_tree(i, max_depth, depth+1)
  56. # print_tree(tgt, max_depth, depth+1)
  57. # Meta-model for our DSL
  58. dsl_mm_id = state.create_node()
  59. dsl_mm_scd = SCD(dsl_mm_id, state)
  60. dsl_mm_scd.create_class("Animal", abstract=True)
  61. dsl_mm_scd.create_class("Man", min_c=1, max_c=2)
  62. dsl_mm_scd.create_inheritance("Man", "Animal")
  63. dsl_mm_scd.create_model_ref("Integer", int_mm_id)
  64. dsl_mm_scd.create_attribute_link("Man", "Integer", "weight", optional=False)
  65. dsl_mm_scd.create_class("Bear")
  66. dsl_mm_scd.create_inheritance("Bear", "Animal")
  67. dsl_mm_scd.create_association("afraidOf", "Man", "Animal",
  68. # Every Man afraid of at least one Animal:
  69. src_min_c=0,
  70. src_max_c=None,
  71. tgt_min_c=1,
  72. tgt_max_c=None,
  73. )
  74. print(dsl_mm_scd.list_elements())
  75. conf = Conformance(state, dsl_mm_id, scd_mm_id)
  76. print("conforms?", conf.check_nominal(log=True))
  77. # Model in our DSL
  78. dsl_m_id = state.create_node()
  79. dsl_m_od = OD(dsl_mm_id, dsl_m_id, state)
  80. # dsl_m_od.create_object("animal", "Animal")
  81. dsl_m_od.create_object("george", "Man")
  82. dsl_m_od.create_slot("weight", "george",
  83. dsl_m_od.create_integer_value("george.weight", 80))
  84. # "george_weight"
  85. dsl_m_od.create_object("bear1", "Bear")
  86. dsl_m_od.create_object("bear2", "Bear")
  87. dsl_m_od.create_link("georgeAfraidOfBear1", "afraidOf", "george", "bear1")
  88. dsl_m_od.create_link("georgeAfraidOfBear2", "afraidOf", "george", "bear2")
  89. conf2 = Conformance(state, dsl_m_id, dsl_mm_id)
  90. print("DSL instance conforms?", conf2.check_nominal(log=True))
  91. print(conf2.type_mapping)
  92. # RAMify MM
  93. ramified_mm_id = ramify(state, dsl_mm_id)
  94. # LHS of our rule
  95. lhs_id = state.create_node()
  96. lhs_od = OD(ramified_mm_id, lhs_id, state)
  97. lhs_od.create_object("man", "Man")
  98. lhs_od.create_slot("weight", "man", lhs_od.create_string_value("man.weight", 'v < 99'))
  99. lhs_od.create_object("scaryAnimal", "Animal")
  100. lhs_od.create_link("manAfraidOfAnimal", "afraidOf", "man", "scaryAnimal")
  101. conf3 = Conformance(state, lhs_id, ramified_mm_id)
  102. print("LHS conforms?", conf3.check_nominal(log=True))
  103. # RHS of our rule
  104. rhs_id = state.create_node()
  105. rhs_od = OD(ramified_mm_id, rhs_id, state)
  106. rhs_od.create_object("man", "Man")
  107. rhs_od.create_slot("weight", "man", rhs_od.create_string_value("man.weight", 'v + 5'))
  108. rhs_od.create_object("bill", "Man")
  109. rhs_od.create_slot("weight", "bill", rhs_od.create_string_value("bill.weight", '100'))
  110. rhs_od.create_link("billAfraidOfMan", "afraidOf", "bill", "man")
  111. conf4 = Conformance(state, rhs_id, ramified_mm_id)
  112. print("RHS conforms?", conf4.check_nominal(log=True))
  113. # Convert to format understood by matching algorithm
  114. host = mvs_adapter.model_to_graph(state, dsl_m_id, dsl_mm_id)
  115. guest = mvs_adapter.model_to_graph(state, lhs_id, ramified_mm_id)
  116. print("HOST:")
  117. print(host.vtxs)
  118. print(host.edges)
  119. print("GUEST:")
  120. print(guest.vtxs)
  121. print(guest.edges)
  122. print("matching...")
  123. matcher = MatcherVF2(host, guest, mvs_adapter.RAMCompare(Bottom(state), dsl_m_od))
  124. for m in matcher.match():
  125. print("\nMATCH:\n", m)
  126. name_to_matched = {}
  127. for guest_vtx, host_vtx in m.mapping_vtxs.items():
  128. if isinstance(guest_vtx, mvs_adapter.NamedNode) and isinstance(host_vtx, mvs_adapter.NamedNode):
  129. name_to_matched[guest_vtx.name] = host_vtx.name
  130. print(name_to_matched)
  131. rewriter.rewrite(state, lhs_id, rhs_id, ramified_mm_id, name_to_matched, dsl_m_id, dsl_mm_id)
  132. break
  133. print("DONE")
  134. conf5 = Conformance(state, dsl_m_id, dsl_mm_id)
  135. print("Updated model conforms?", conf5.check_nominal(log=True))
  136. if __name__ == "__main__":
  137. main()