Jelajahi Sumber

nice visualization

Joeri Exelmans 2 minggu lalu
induk
melakukan
e046f2f972

+ 9 - 4
tutorial/00_metamodeling.py

@@ -27,7 +27,10 @@ m_cs = """
     myLnk:a2b (myA -> myB)
 """
 
-# So far we've only created text strings. To parse the models, we first create our 'state', which is a mutable graph that will contain our models and meta-models:
+# Notice that the syntax for meta-model and model is the same: We always declare a named object/link, followed by a colon (:) and the name of the type. The type name refers to the name of an object/link in the meta-model of our model.
+
+
+# So far we've only created text strings in Python. To parse them as models, we first create our 'state', which is a mutable graph that will contain our models and meta-models:
 
 
 from state.devstate import DevState
@@ -37,7 +40,9 @@ state = DevState()
 
 # Next, we must load the Simple Class Diagrams (SCD) meta-meta-model into our 'state'. The SCD meta-meta-model is a meta-model for our meta-model, and it is also a meta-model for itself.
 
-# The meta-meta-model is not specified in textual syntax because it is typed by itself, and the parser cannot resolve circular dependencies. Therefore, we load the meta-meta-model by mutating the 'state' directly at a very low level:
+# The meta-meta-model is not specified in textual syntax because it is typed by itself. In textual syntax, it would contain things like:
+#    Class:Class
+# which is an object typed by itself. The parser cannot handle this (or circular dependencies in general). Therefore, we load the meta-meta-model by mutating the 'state' directly at a very low level:
 
 from bootstrap.scd import bootstrap_scd
 
@@ -50,7 +55,7 @@ print("OK")
 from concrete_syntax.textual_od import parser
 
 print()
-print("Parsing 'woods' meta-model...")
+print("Parsing meta-model...")
 mm = parser.parse_od(
     state,
     m_text=mm_cs, # the string of text to parse
@@ -62,7 +67,7 @@ print("OK")
 # And we can parse our model, the same way:
 
 print()
-print("Parsing 'woods' model...")
+print("Parsing model...")
 m = parser.parse_od(
     state,
     m_text=m_cs,

+ 0 - 3
tutorial/02_inheritance.py

@@ -1,4 +1,3 @@
-
 # The following meta-model has an inheritance relation:
 
 mm_cs = """
@@ -33,8 +32,6 @@ m_nonconform_cs = """
 
 from state.devstate import DevState
 from bootstrap.scd import bootstrap_scd
-# from concrete_syntax.textual_od import parser
-# from framework.conformance import Conformance, render_conformance_check_result
 from util import loader
 
 state = DevState()

+ 0 - 1
tutorial/03_api.py

@@ -14,7 +14,6 @@ mm_cs = """
     myZ:Association (MyAbstractClass -> Z) {
         target_lower_cardinality = 1;
     }
-
 """
 
 m_cs = """

+ 23 - 1
tutorial/05_advanced_transformation.py

@@ -61,6 +61,7 @@ from transformation.cloner import clone_od
 from transformation import rewriter
 from concrete_syntax.textual_od.renderer import render_od
 from concrete_syntax.common import indent
+from api.od import ODAPI
 
 state = DevState()
 mmm = bootstrap_scd(state)
@@ -166,11 +167,32 @@ def fire_transition(m, transition_match):
     for match_outgoing in match_od(state, m, mm, lhs_outgoing, mm_ramified, pivot=transition_match):
         rewriter.rewrite(state, lhs_outgoing, rhs_outgoing, mm_ramified, match_outgoing, m, mm)
 
+def show_petri_net(m):
+    odapi = ODAPI(state, m, mm)
+    p1 = odapi.get_slot_value(odapi.get("p1"), "tokens")
+    p2 = odapi.get_slot_value(odapi.get("p2"), "tokens")
+    cp1 = odapi.get_slot_value(odapi.get("cp1"), "tokens")
+    cp2 = odapi.get_slot_value(odapi.get("cp2"), "tokens")
+    return f"""
+     t1                   t2                   t3  
+     ┌─┐        p1        ┌─┐        p2        ┌─┐ 
+     │ │        ---       │ │        ---       │ │ 
+     │ ├─────► ( {p1} )─────►│ │─────► ( {p2} )─────►│ │ 
+     └─┘        ---       └─┘        ---       └─┘ 
+      ▲                   │ ▲                   │  
+      │                   │ │                   │  
+      │                   │ │                   │  
+      │                   │ │                   │  
+      │        ---        │ │       ---         │  
+      └───────( {cp1} )◄──────┘ └──────( {cp2} )◄───────┘  
+               ---                  ---            
+               cp1                  cp2            """
 
 # Let's see if it works:
 while len(enabled) > 0:
+    print(show_petri_net(m))
+    print("\nenabled PN transitions:", enabled)
     print("press ENTER to fire", enabled[0]['t'])
     input()
     fire_transition(m, enabled[0])
     enabled = list(find_enabled_transitions(m))
-    print("\nenabled PN transitions:", enabled)

+ 3 - 0
util/loader.py

@@ -39,8 +39,11 @@ KINDS = ["nac", "lhs", "rhs"]
 # Phony name generator that raises an error if you try to use it :)
 class LHSNameGenerator:
     def __call__(self, type_name):
+        if type_name == "GlobalCondition":
+            return parser.DefaultNameGenerator()(type_name)
         raise Exception(f"Error: Object or link of type '{type_name}' does not have a name.\nAnonymous objects/links are not allowed in the LHS of a rule, because they can have unintended consequences. Please give all of the elements in the LHS explicit names.")
 
+
 # load model transformation rules
 def load_rules(state, get_filename, rt_mm_ramified, rule_names, check_conformance=True):
     rules = {}