Bläddra i källkod

add files for assignment 6

Joeri Exelmans 1 år sedan
förälder
incheckning
7391d7d9a6

+ 105 - 0
examples/performance/runner.py

@@ -0,0 +1,105 @@
+# Model transformation experiment
+
+from state.devstate import DevState
+from bootstrap.scd import bootstrap_scd
+from uuid import UUID
+from services.scd import SCD
+from framework.conformance import Conformance
+from services.od import OD
+from transformation.matcher import match_od
+from transformation.ramify import ramify
+from transformation.cloner import clone_od
+from transformation import rewriter
+from services.bottom.V0 import Bottom
+from services.primitives.integer_type import Integer
+from concrete_syntax.plantuml import renderer as plantuml
+from concrete_syntax.plantuml.make_url import make_url as make_plantuml_url
+from concrete_syntax.textual_od import parser, renderer
+from util.timer import Timer
+
+if __name__ == "__main__":
+    state = DevState()
+    root = state.read_root() # id: 0
+
+    # Meta-meta-model: a class diagram that describes the language of class diagrams
+    scd_mmm_id = bootstrap_scd(state)
+    int_mm_id = UUID(state.read_value(state.read_dict(state.read_root(), "Integer")))
+    string_mm_id = UUID(state.read_value(state.read_dict(state.read_root(), "String")))
+
+    dsl_mm_cs = """
+        Rare:Class
+        Many:Class
+        ManyB:Class
+        Other:Class
+        OtherB:Class
+        OtherC:Class
+        ass:Association(Many->ManyB)
+    """
+    dsl_mm_id = parser.parse_od(state, dsl_mm_cs, mm=scd_mmm_id)
+    
+    dsl_m_cs = """
+        rare:Rare
+        many0:Many
+        many1:Many
+        many2:Many
+        many3:Many
+        many4:Many
+        many5:ManyB
+        many6:ManyB
+        many7:ManyB
+        many8:ManyB
+
+        :ass (many2->many6)
+        :ass (many3->many8)
+
+        # other0:Other
+        # other1:OtherC
+        # other2:Other
+        # other3:Other
+        # other4:Other
+        # other5:OtherB
+        # other6:OtherB
+        # other7:OtherB
+        # other8:OtherB
+        # other9:OtherB
+        # other10:OtherB
+        # other11:OtherC
+        # other12:OtherC
+        # other13:OtherC
+        # other14:OtherC
+
+        # other1099:OtherB
+        # other1199:OtherC
+        # other1299:OtherC
+        # other1399:OtherC
+        # other1499:OtherC
+    """
+    dsl_m_id = parser.parse_od(state, dsl_m_cs, mm=dsl_mm_id)
+
+    # RAMify MM
+    prefix = "RAM_" # all ramified types can be prefixed to distinguish them a bit more
+    ramified_mm_id = ramify(state, dsl_mm_id, prefix)
+    ramified_int_mm_id = ramify(state, int_mm_id, prefix)
+
+    # LHS - pattern to match
+
+    # TODO: enable more powerful constraints
+    pattern_cs = f"""
+        # object to match
+        rare:{prefix}Rare {{
+        }}
+
+        many:{prefix}Many
+        manyB:{prefix}ManyB
+        manyB2:{prefix}ManyB
+    """
+    pattern_id = parser.parse_od(state, pattern_cs, mm=ramified_mm_id)
+
+    with Timer("find all matches"):
+        matches = list(match_od(state, dsl_m_id, dsl_mm_id, pattern_id, ramified_mm_id))
+
+
+    for match in matches:
+        print("\nMATCH:\n", match)
+
+    print(len(matches), 'matches')

+ 0 - 35
examples/semantics/translational/runner.py

@@ -1,35 +0,0 @@
-from state.devstate import DevState
-from bootstrap.scd import bootstrap_scd
-from concrete_syntax.textual_od import parser, renderer
-from concrete_syntax.plantuml.renderer import render_object_diagram, render_class_diagram
-from concrete_syntax.plantuml.make_url import make_url
-from api.od import ODAPI
-
-from transformation.ramify import ramify
-from transformation.topify.topify import Topifier
-from transformation.merger import merge_models
-
-from util import loader
-
-from examples.semantics.operational.simulator import Simulator, RandomDecisionMaker, InteractiveDecisionMaker
-from examples.semantics.operational.port import models
-from examples.semantics.operational.port.helpers import design_to_state, state_to_design, get_time
-from examples.semantics.operational.port.renderer import render_port_textual, render_port_graphviz
-
-import os
-THIS_DIR = os.path.dirname(__file__)
-
-# get file contents as string
-def read_file(filename):
-    with open(THIS_DIR+'/'+filename) as file:
-        return file.read()
-
-if __name__ == "__main__":
-    state = DevState()
-    scd_mmm = bootstrap_scd(state)
-
-    # Load merged Petri Net and Port meta-model:
-    merged_mm = loader.parse_and_check(state, read_file("merged_mm.od"), scd_mmm, "merged_mm.od")
-
-    # Load Port initial runtime model:
-    port_m_rt_initial = loader.parse_and_check(state, models.port_rt_m_cs, merged_mm, "Port-M-RT-initial")

+ 79 - 0
examples/semantics/translational/runner_exec_pn.py

@@ -0,0 +1,79 @@
+from state.devstate import DevState
+from bootstrap.scd import bootstrap_scd
+from concrete_syntax.textual_od import parser, renderer
+from concrete_syntax.plantuml.renderer import render_object_diagram, render_class_diagram
+from concrete_syntax.plantuml.make_url import make_url
+from api.od import ODAPI
+
+from transformation.ramify import ramify
+from transformation.topify.topify import Topifier
+from transformation.merger import merge_models
+from transformation.ramify import ramify
+from transformation.rule import RuleMatcherRewriter, ActionGenerator
+
+from util import loader
+
+from examples.semantics.operational.simulator import Simulator, RandomDecisionMaker, InteractiveDecisionMaker
+from examples.semantics.operational.port import models
+from examples.semantics.operational.port.helpers import design_to_state, state_to_design, get_time
+from examples.semantics.operational.port.renderer import render_port_textual, render_port_graphviz
+from examples.petrinet.renderer import render_petri_net
+from examples.semantics.operational import simulator
+
+import os
+import sys
+THIS_DIR = os.path.dirname(__file__)
+
+# get file contents as string
+def read_file(filename):
+    with open(THIS_DIR+'/'+filename) as file:
+        return file.read()
+
+if __name__ == "__main__":
+    if len(sys.argv) != 2:
+        print("Usage:")
+        print(f"  python {__file__} model.od")
+        print("where `model.od` is a valid instance of Port+Petri-Net.")
+        sys.exit(1)
+
+    model_to_open = sys.argv[1]
+
+    state = DevState()
+    scd_mmm = bootstrap_scd(state)
+
+    print('loading merged MM...')
+    merged_mm = loader.parse_and_check(state, read_file("merged_mm.od"), scd_mmm, "merged_mm.od", 
+        check_conformance=False, # no need to check conformance every time
+    )
+
+    print('ramifying...')
+    ramified_merged_mm = ramify(state, merged_mm)
+
+    print('loading petri net rules...')
+    rules = loader.load_rules(state,
+        lambda rule_name, kind: f"{THIS_DIR}/../../petrinet/operational_semantics/r_{rule_name}_{kind}.od",
+        ramified_merged_mm,
+        ["fire_transition"])
+
+    print('loading model...')
+    filename = f"{THIS_DIR}/{model_to_open}"
+    with open(filename, "r") as file:
+        model = loader.parse_and_check(state, file.read(), merged_mm, "model",
+            check_conformance=False, # no need to check conformance every time
+        )
+        print('loaded', filename)
+
+    print('ready!')
+
+    matcher_rewriter = RuleMatcherRewriter(state, merged_mm, ramified_merged_mm)
+    action_generator = ActionGenerator(matcher_rewriter, rules)
+
+    sim = simulator.Simulator(
+        action_generator=action_generator,
+        decision_maker=simulator.InteractiveDecisionMaker(auto_proceed=False),
+        # decision_maker=simulator.RandomDecisionMaker(seed=0),
+        renderer=lambda od: render_petri_net(od) + renderer.render_od(state, od.m, od.mm),
+        # renderer=lambda od: render_od(state, od.m, od.mm),
+    )
+
+    sim.run(ODAPI(state, model, merged_mm))

+ 8 - 0
transformation/rule.py

@@ -50,6 +50,9 @@ class RuleMatcherRewriter:
                         lhs_match = lhs_matcher.__next__()
                     x += 1
 
+                    # Uncomment to see matches attempted - may give insight into why your rule is not matching
+                    # print("  lhs_match:", lhs_match)
+
                     nac_matched = False
 
                     with Timer(f"MATCH NACs {rule_name}"):
@@ -122,6 +125,11 @@ class RuleMatcherRewriter:
 
         return (cloned_m, rhs_match)
 
+    # This is often what you want: find a match, and execute the rule
+    def exec_on_first_match(self, host: UUID, rule: Rule, rule_name: str, in_place=False):
+        for lhs_match in self.match_rule(host, rule.lhs, rule.nacs, rule_name):
+            (rewritten_host, rhs_match) = self.exec_rule(host, rule.lhs, rule.rhs, lhs_match, rule_name, in_place)
+            return rewritten_host, lhs_match, rhs_match
 
 # Generator that yields actions in the format expected by 'Simulator' class
 class ActionGenerator: