runner_translate.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. from state.devstate import DevState
  2. from bootstrap.scd import bootstrap_scd
  3. from concrete_syntax.textual_od import parser, renderer
  4. from concrete_syntax.plantuml.renderer import render_object_diagram, render_class_diagram
  5. from concrete_syntax.plantuml.make_url import make_url
  6. from api.od import ODAPI
  7. from transformation.ramify import ramify
  8. from transformation.topify.topify import Topifier
  9. from transformation.merger import merge_models
  10. from transformation.ramify import ramify
  11. from transformation.rule import RuleMatcherRewriter
  12. from util import loader
  13. from examples.semantics.operational.simulator import Simulator, RandomDecisionMaker, InteractiveDecisionMaker
  14. from examples.semantics.operational.port import models
  15. from examples.semantics.operational.port.helpers import design_to_state, state_to_design, get_time
  16. from examples.semantics.operational.port.renderer import render_port_textual, render_port_graphviz
  17. from examples.petrinet.renderer import render_petri_net
  18. import os
  19. THIS_DIR = os.path.dirname(__file__)
  20. # get file contents as string
  21. def read_file(filename):
  22. with open(THIS_DIR+'/'+filename) as file:
  23. return file.read()
  24. if __name__ == "__main__":
  25. state = DevState()
  26. scd_mmm = bootstrap_scd(state)
  27. print('loading merged MM...')
  28. merged_mm = loader.parse_and_check(state, read_file("merged_mm.od"), scd_mmm, "merged_mm.od",
  29. check_conformance=False, # no need to check conformance every time
  30. )
  31. print('ramifying...')
  32. ramified_merged_mm = ramify(state, merged_mm)
  33. ###################################
  34. # This is the main part you want to edit (by adding/changing the transformation rules)
  35. # | | |
  36. # V V V
  37. rule_names = [
  38. # high to low priority (the list-order here matters, the alphabetic-order of the names does not):
  39. "00_place2place",
  40. "10_conn2trans",
  41. # The above two rules create a bunch of PN places and PN transitions.
  42. # (with generic_links to the Port-elements)
  43. # One way to continue, is to create PN arcs between the places and transitions.
  44. # Or you can also just start from scratch, if you have a better idea :)
  45. ]
  46. # The script below will keep executing the first rule until it no longer matches, then the second rule, etc.
  47. ###################################
  48. print('loading rules...')
  49. rules = loader.load_rules(state,
  50. lambda rule_name, kind: f"{THIS_DIR}/rules/gen_pn/r_{rule_name}_{kind}.od",
  51. ramified_merged_mm,
  52. rule_names)
  53. print('loading model...')
  54. port_m_rt_initial = loader.parse_and_check(state,
  55. m_cs=models.port_rt_m_cs, # <-- your final solution should work with the full model
  56. # m_cs=models.smaller_model_rt_cs, # <-- simpler model to try first
  57. # m_cs=models.smaller_model2_rt_cs, # <-- simpler model to try first
  58. mm=merged_mm,
  59. descr="initial model",
  60. check_conformance=False, # no need to check conformance every time
  61. )
  62. print('ready!')
  63. port_m_rt = port_m_rt_initial
  64. matcher_rewriter = RuleMatcherRewriter(state, merged_mm, ramified_merged_mm)
  65. ###################################
  66. # Because the matching of many different rules can be slow,
  67. # this script will store intermediate snapshots each time
  68. # after having 'exhausted' a rule.
  69. # When re-running the script, the stored snapshots will be loaded
  70. # from disk instead of re-running the rules.
  71. # You can force re-running the rules (e.g., because you changed the rules)
  72. # by deleting the `snapshot_after_*` files.
  73. ###################################
  74. ###################################
  75. # You are allowed to edit the script below, but you don't have to.
  76. # Changes you may want to make:
  77. # - outcomment the 'render_petri_net'-call (preventing popups)
  78. # - if you really want to do something crazy,
  79. # you can even write a script that uses the lower-level `match_od`/`rewrite` primitives...
  80. # - ??
  81. ###################################
  82. for i, rule_name in enumerate(rule_names):
  83. filename = f"{THIS_DIR}/snapshot_after_{rule_name}.od"
  84. print("rule =", rule_name)
  85. rule = rules[rule_name]
  86. try:
  87. with open(filename, "r") as file:
  88. port_m_rt = parser.parse_od(state, file.read(), merged_mm)
  89. print('loaded', filename)
  90. except FileNotFoundError:
  91. # Fire every rule until it cannot match any longer:
  92. while True:
  93. result = matcher_rewriter.exec_on_first_match(port_m_rt, rule, rule_name,
  94. in_place=True, # faster
  95. )
  96. if result == None:
  97. print(" no matches")
  98. break
  99. else:
  100. port_m_rt, lhs_match, _ = result
  101. print(" rewrote", lhs_match)
  102. txt = renderer.render_od(state, port_m_rt, merged_mm)
  103. with open(filename, "w") as file:
  104. file.write(txt)
  105. print('wrote', filename)
  106. render_petri_net(ODAPI(state, port_m_rt, merged_mm))
  107. ###################################
  108. # Once you have generated a Petri Net, you can execute the petri net:
  109. #
  110. # python runner_exec_pn.py snapshot_after_XX_name_of_my_last_rule.od
  111. ###################################