浏览代码

Merge with Robbe's scheduling language

Joeri Exelmans 2 周之前
父节点
当前提交
4ba0ed09b2
共有 100 个文件被更改,包括 4105 次插入3349 次删除
  1. 0 0
      api/__init__.py
  2. 42 70
      api/od.py
  3. 9 0
      api/od_stub.pyi
  4. 18 0
      api/od_stub_readonly.pyi
  5. 0 0
      benchmark/runner.py
  6. 2 2
      concrete_syntax/textual_cd/parser.py
  7. 34 0
      examples/geraniums/geraniums_renderer.j2
  8. 9 0
      examples/geraniums/metamodels/mm.od
  9. 44 0
      examples/geraniums/models/eval_context.py
  10. 17 0
      examples/geraniums/models/example1.od
  11. 47 0
      examples/geraniums/models/example2.od
  12. 45 0
      examples/geraniums/renderer.py
  13. 3 0
      examples/geraniums/rules/cracked_pots.od
  14. 3 0
      examples/geraniums/rules/create_pot.od
  15. 7 0
      examples/geraniums/rules/flowering_flowers_in_pot.od
  16. 8 0
      examples/geraniums/rules/repot_flower_in_pot.od
  17. 48 0
      examples/geraniums/runner.py
  18. 645 0
      examples/geraniums/schedules/schedule.drawio
  19. 0 0
      examples/geraniums/schedules/schedule.od
  20. 0 139
      examples/model_transformation/woods.plantuml
  21. 0 245
      examples/model_transformation/woods.py
  22. 12 1
      examples/petrinet/models/m_example_simple.od
  23. 18 0
      examples/petrinet/models/m_example_simple_rt_initial.od
  24. 13 0
      examples/petrinet/models/rules/all_incoming.od
  25. 13 0
      examples/petrinet/models/rules/all_incomming.od
  26. 13 0
      examples/petrinet/models/rules/all_outgoing.od
  27. 13 0
      examples/petrinet/models/rules/increase_outgoing.od
  28. 0 0
      examples/petrinet/models/rules/input_without_token.od
  29. 3 0
      examples/petrinet/models/rules/places.od
  30. 13 0
      examples/petrinet/models/rules/reduce_incoming.od
  31. 13 0
      examples/petrinet/models/rules/reduce_incomming.od
  32. 1 0
      examples/petrinet/models/rules/transition.od
  33. 0 66
      examples/petrinet/models/schedule.od
  34. 526 0
      examples/petrinet/models/schedules/combinatory.drawio
  35. 23 0
      examples/petrinet/models/schedules/foo.od
  36. 66 0
      examples/petrinet/models/schedules/petrinet.od
  37. 1160 0
      examples/petrinet/models/schedules/petrinet2.drawio
  38. 915 0
      examples/petrinet/models/schedules/petrinet3.drawio
  39. 217 0
      examples/petrinet/models/schedules/recursion.drawio
  40. 4 0
      examples/petrinet/models/schedules/schedule.od
  41. 13 0
      examples/petrinet/operational_semantics/all_inputs_reduced.od
  42. 13 0
      examples/petrinet/operational_semantics/all_outputs.od
  43. 13 0
      examples/petrinet/operational_semantics/all_outputs_increased.od
  44. 13 0
      examples/petrinet/operational_semantics/input_without_token.od
  45. 1 1
      examples/petrinet/operational_semantics/transition.od
  46. 12 0
      examples/petrinet/petrinet_renderer.j2
  47. 21 6
      examples/petrinet/renderer.py
  48. 15 37
      examples/petrinet/runner.py
  49. 0 49
      examples/schedule/RuleExecuter.py
  50. 0 104
      examples/schedule/ScheduledActionGenerator.py
  51. 0 129
      examples/schedule/generator.py
  52. 0 26
      examples/schedule/models/README.md
  53. 0 46
      examples/schedule/models/scheduling_MM.od
  54. 0 12
      examples/schedule/schedule_lib/__init__.py
  55. 0 63
      examples/schedule/schedule_lib/data.py
  56. 0 26
      examples/schedule/schedule_lib/data_modify.py
  57. 0 47
      examples/schedule/schedule_lib/data_node.py
  58. 0 21
      examples/schedule/schedule_lib/end.py
  59. 0 34
      examples/schedule/schedule_lib/exec_node.py
  60. 0 10
      examples/schedule/schedule_lib/funcs.py
  61. 0 8
      examples/schedule/schedule_lib/id_generator.py
  62. 0 57
      examples/schedule/schedule_lib/loop.py
  63. 0 42
      examples/schedule/schedule_lib/match.py
  64. 0 25
      examples/schedule/schedule_lib/null_node.py
  65. 0 28
      examples/schedule/schedule_lib/print.py
  66. 0 38
      examples/schedule/schedule_lib/rewrite.py
  67. 0 16
      examples/schedule/schedule_lib/start.py
  68. 0 9
      examples/schedule/templates/schedule_dot.j2
  69. 0 35
      examples/schedule/templates/schedule_template.j2
  70. 0 47
      examples/schedule/templates/schedule_template_wrap.j2
  71. 0 142
      examples/semantics/operational/port/assignment.py
  72. 0 18
      examples/semantics/operational/port/helpers.py
  73. 0 407
      examples/semantics/operational/port/models.py
  74. 0 78
      examples/semantics/operational/port/renderer.py
  75. 0 62
      examples/semantics/operational/port/rulebased_runner.py
  76. 0 67
      examples/semantics/operational/port/rulebased_sem.py
  77. 0 13
      examples/semantics/operational/port/rules/README.txt
  78. 0 4
      examples/semantics/operational/port/rules/r_ship_appears_in_berth_lhs.od
  79. 0 4
      examples/semantics/operational/port/rules/r_ship_appears_in_berth_rhs.od
  80. 0 5
      examples/semantics/operational/port/rules/r_ship_sinks_lhs.od
  81. 0 4
      examples/semantics/operational/port/rules/r_ship_sinks_rhs.od
  82. 0 56
      examples/semantics/operational/port/runner.py
  83. 0 70
      examples/semantics/operational/simulator.py
  84. 0 4
      examples/semantics/translational/.gitignore
  85. 0 197
      examples/semantics/translational/merged_mm.od
  86. 0 65
      examples/semantics/translational/regenerate_mm.py
  87. 0 90
      examples/semantics/translational/renderer.py
  88. 0 5
      examples/semantics/translational/rules/gen_pn/r_00_place2place_lhs.od
  89. 0 14
      examples/semantics/translational/rules/gen_pn/r_00_place2place_nac.od
  90. 0 22
      examples/semantics/translational/rules/gen_pn/r_00_place2place_rhs.od
  91. 0 7
      examples/semantics/translational/rules/gen_pn/r_10_conn2trans_lhs.od
  92. 0 10
      examples/semantics/translational/rules/gen_pn/r_10_conn2trans_nac.od
  93. 0 28
      examples/semantics/translational/rules/gen_pn/r_10_conn2trans_rhs.od
  94. 0 82
      examples/semantics/translational/runner_exec_pn.py
  95. 0 140
      examples/semantics/translational/runner_translate.py
  96. 0 58
      examples/woods/common.py
  97. 0 158
      examples/woods/models.py
  98. 0 75
      examples/woods/opsem_python.py
  99. 0 25
      examples/woods/opsem_rulebased.py
  100. 0 0
      examples/woods/rules/r_advance_time_lhs.od

examples/schedule/__init__.py → api/__init__.py


+ 42 - 70
api/od.py

@@ -5,13 +5,10 @@ from services.primitives.boolean_type import Boolean
 from services.primitives.integer_type import Integer
 from services.primitives.string_type import String
 from services.primitives.actioncode_type import ActionCode
-from services.primitives.bytes_type import Bytes
 from uuid import UUID
-from typing import Optional
-from util.timer import Timer
+from typing import Optional, Any
 
-NEXT_LINK_ID = 0
-NEXT_OBJ_ID = 0
+NEXT_ID = 0
 
 # Models map names to elements
 # This builds the inverse mapping, so we can quickly lookup the name of an element
@@ -43,12 +40,11 @@ class ODAPI:
         self.create_integer_value = self.od.create_integer_value
         self.create_string_value = self.od.create_string_value
         self.create_actioncode_value = self.od.create_actioncode_value
-        self.create_bytes_value = self.od.create_bytes_value
 
-        self.__recompute_mappings()
+        self.recompute_mappings()
 
     # Called after every change - makes querying faster but modifying slower
-    def __recompute_mappings(self):
+    def recompute_mappings(self):
         self.m_obj_to_name = build_name_mapping(self.state, self.m)
         self.mm_obj_to_name = build_name_mapping(self.state, self.mm)
         self.type_to_objs = { type_name : set() for type_name in self.bottom.read_keys(self.mm)}
@@ -63,25 +59,33 @@ class ODAPI:
     def get_value(self, obj: UUID):
         return od.read_primitive_value(self.bottom, obj, self.mm)[0]
 
-    def get_target(self, link: UUID):
+    def get_target(self, link: UUID) -> UUID:
         return self.bottom.read_edge_target(link)
 
-    def get_source(self, link: UUID):
+    def get_source(self, link: UUID) -> UUID:
         return self.bottom.read_edge_source(link)
 
-    def get_slot(self, obj: UUID, attr_name: str):
+    def get_slot(self, obj: UUID, attr_name: str) -> UUID:
         slot = self.od.get_slot(obj, attr_name)
         if slot == None:
             raise NoSuchSlotException(f"Object '{self.m_obj_to_name[obj]}' has no slot '{attr_name}'")
         return slot
 
-    def get_slot_link(self, obj: UUID, attr_name: str):
+    def get_slot_link(self, obj: UUID, attr_name: str) -> UUID:
         return self.od.get_slot_link(obj, attr_name)
 
     # Parameter 'include_subtypes': whether to include subtypes of the given association
-    def get_outgoing(self, obj: UUID, assoc_name: str, include_subtypes=True):
+    def get_outgoing(self, obj: UUID, assoc_name: str, include_subtypes=True) -> list[UUID]:
         outgoing = self.bottom.read_outgoing_edges(obj)
-        result = []
+        return self.filter_edges_by_type(outgoing, assoc_name, include_subtypes)
+
+    # Parameter 'include_subtypes': whether to include subtypes of the given association
+    def get_incoming(self, obj: UUID, assoc_name: str, include_subtypes=True):
+        incoming = self.bottom.read_incoming_edges(obj)
+        return self.filter_edges_by_type(incoming, assoc_name, include_subtypes)
+
+    def filter_edges_by_type(self, outgoing: list[UUID], assoc_name: str, include_subtypes=True) -> list[UUID]:
+        result: list[UUID] = []
         for o in outgoing:
             try:
                 type_of_outgoing_link = self.get_type_name(o)
@@ -92,23 +96,8 @@ class ODAPI:
                     result.append(o)
         return result
 
-
-    # Parameter 'include_subtypes': whether to include subtypes of the given association
-    def get_incoming(self, obj: UUID, assoc_name: str, include_subtypes=True):
-        incoming = self.bottom.read_incoming_edges(obj)
-        result = []
-        for i in incoming:
-            try:
-                type_of_incoming_link = self.get_type_name(i)
-            except:
-                continue # OK, not all edges are typed
-            if (include_subtypes and self.cdapi.is_subtype(super_type_name=assoc_name, sub_type_name=type_of_incoming_link)
-                or not include_subtypes and type_of_incoming_link == assoc_name):
-                    result.append(i)
-        return result
-
     # Returns list of tuples (name, obj)
-    def get_all_instances(self, type_name: str, include_subtypes=True):
+    def get_all_instances(self, type_name: str, include_subtypes=True) -> list[UUID]:
         if include_subtypes:
             all_types = self.cdapi.transitive_sub_types[type_name]
         else:
@@ -130,7 +119,7 @@ class ODAPI:
         else:
             raise Exception(f"Couldn't find name of {obj} - are you sure it exists in the (meta-)model?")
 
-    def get(self, name: str):
+    def get(self, name: str) -> UUID:
         results = self.bottom.read_outgoing_elements(self.m, name)
         if len(results) == 1:
             return results[0]
@@ -139,10 +128,10 @@ class ODAPI:
         else:
             raise Exception(f"No such element in model: '{name}'")
 
-    def get_type_name(self, obj: UUID):
+    def get_type_name(self, obj: UUID) -> str:
         return self.get_name(self.get_type(obj))
 
-    def is_instance(self, obj: UUID, type_name: str, include_subtypes=True):
+    def is_instance(self, obj: UUID, type_name: str, include_subtypes=True) -> bool:
         typ = self.cdapi.get_type(type_name)
         types = set(typ) if not include_subtypes else self.cdapi.transitive_sub_types[type_name]
         for type_of_obj in self.bottom.read_outgoing_elements(obj, "Morphism"):
@@ -150,18 +139,21 @@ class ODAPI:
                 return True
         return False
 
-    def delete(self, obj: UUID):
+    def delete(self, obj: UUID) -> None:
         self.bottom.delete_element(obj)
-        self.__recompute_mappings()
+        self.recompute_mappings()
 
     # Does the the object have the given attribute?
-    def has_slot(self, obj: UUID, attr_name: str):
-        return self.od.get_slot_link(obj, attr_name) != None
+    def has_slot(self, obj: UUID, attr_name: str) -> bool:
+        class_name = self.get_name(self.get_type(obj))
+        if self.od.get_attr_link_name(class_name, attr_name) is None:
+            return False
+        return self.od.get_slot_link(obj, attr_name) is not None
 
     def get_slots(self, obj: UUID) -> list[str]:
         return [attr_name for attr_name, _ in self.od.get_slots(obj)]
 
-    def get_slot_value(self, obj: UUID, attr_name: str):
+    def get_slot_value(self, obj: UUID, attr_name: str) -> Any:
         slot = self.get_slot(obj, attr_name)
         return self.get_value(slot)
 
@@ -174,14 +166,14 @@ class ODAPI:
     # Returns the given default value if the slot does not exist on the object.
     # The attribute must exist in the object's class, or an exception will be thrown.
     # The slot may not exist however, if the attribute is defined as 'optional' in the class.
-    def get_slot_value_default(self, obj: UUID, attr_name: str, default: any):
+    def get_slot_value_default(self, obj: UUID, attr_name: str, default: any) -> any:
         try:
             return self.get_slot_value(obj, attr_name)
         except NoSuchSlotException:
             return default
 
     # create or update slot value
-    def set_slot_value(self, obj: UUID, attr_name: str, new_value: any, is_code=False):
+    def set_slot_value(self, obj: UUID, attr_name: str, new_value: any, is_code=False) -> None:
         obj_name = self.get_name(obj)
 
         link_name = f"{obj_name}_{attr_name}"
@@ -196,7 +188,7 @@ class ODAPI:
         new_target = self.create_primitive_value(target_name, new_value, is_code)
         slot_type = self.cdapi.find_attribute_type(self.get_type_name(obj), attr_name)
         new_link = self.od._create_link(link_name, slot_type, obj, new_target)
-        self.__recompute_mappings()
+        self.recompute_mappings()
 
     def create_primitive_value(self, name: str, value: any, is_code=False):
         # watch out: in Python, 'bool' is subtype of 'int'
@@ -210,44 +202,29 @@ class ODAPI:
                 tgt = self.create_actioncode_value(name, value)
             else:
                 tgt = self.create_string_value(name, value)
-        elif isinstance(value, bytes):
-            tgt = self.create_bytes_value(name, value)
         else:
             raise Exception("Unimplemented type "+value)
-        self.__recompute_mappings()
+        self.recompute_mappings()
         return tgt
 
     def overwrite_primitive_value(self, name: str, value: any, is_code=False):
         referred_model = UUID(self.bottom.read_value(self.get(name)))
-        to_overwrite_type = self.get_type_name(self.get(name))
         # watch out: in Python, 'bool' is subtype of 'int'
         #  so we must check for 'bool' first
         if isinstance(value, bool):
-            if to_overwrite_type != "Boolean":
-                raise Exception(f"Cannot assign boolean value '{value}' to value of type {to_overwrite_type}.")
             Boolean(referred_model, self.state).create(value)
         elif isinstance(value, int):
-            if to_overwrite_type != "Integer":
-                raise Exception(f"Cannot assign integer value '{value}' to value of type {to_overwrite_type}.")
             Integer(referred_model, self.state).create(value)
         elif isinstance(value, str):
             if is_code:
-                if to_overwrite_type != "ActionCode":
-                    raise Exception(f"Cannot assign code to value of type {to_overwrite_type}.")
                 ActionCode(referred_model, self.state).create(value)
             else:
-                if to_overwrite_type != "String":
-                    raise Exception(f"Cannot assign string value '{value}' to value of type {to_overwrite_type}.")
                 String(referred_model, self.state).create(value)
-        elif isinstance(value, bytes):
-            if to_overwrite_type != "Bytes":
-                raise Exception(f"Cannot assign bytes value '{value}' to value of type {to_overwrite_type}.")
-            Bytes(referred_model, self.state).create(value)
         else:
             raise Exception("Unimplemented type "+value)
 
-    def create_link(self, link_name: Optional[str], assoc_name: str, src: UUID, tgt: UUID):
-        global NEXT_LINK_ID
+    def create_link(self, link_name: Optional[str], assoc_name: str, src: UUID, tgt: UUID) -> UUID:
+        global NEXT_ID
         types = self.bottom.read_outgoing_elements(self.mm, assoc_name) 
         if len(types) == 0:
             raise Exception(f"No such association: '{assoc_name}'")
@@ -255,20 +232,15 @@ class ODAPI:
             raise Exception(f"More than one association exists with name '{assoc_name}' - this means the MM is invalid.")
         typ = types[0]
         if link_name == None:
-            link_name = f"__{assoc_name}{NEXT_LINK_ID}"
-            NEXT_LINK_ID += 1
+            link_name = f"__{assoc_name}{NEXT_ID}"
+            NEXT_ID += 1
         link_id = self.od._create_link(link_name, typ, src, tgt)
-        self.__recompute_mappings()
-
+        self.recompute_mappings()
         return link_id
 
-    def create_object(self, object_name: Optional[str], class_name: str):
-        global NEXT_OBJ_ID
-        if object_name == None:
-            object_name = f"__{class_name}{NEXT_OBJ_ID}"
-            NEXT_OBJ_ID += 1
+    def create_object(self, object_name: Optional[str], class_name: str) -> UUID:
         obj = self.od.create_object(object_name, class_name)
-        self.__recompute_mappings()
+        self.recompute_mappings()
         return obj
 
 # internal use
@@ -307,6 +279,6 @@ def bind_api(odapi):
         'create_object': odapi.create_object,
         'create_link': odapi.create_link,
         'delete': odapi.delete,
-        'set_slot_value': odapi.set_slot_value,
+        'set_slot_value': odapi.set_slot_value
     }
     return funcs

+ 9 - 0
api/od_stub.pyi

@@ -0,0 +1,9 @@
+from typing import Optional
+from uuid import UUID
+
+from od_stub_readonly import *
+
+def create_object(object_name: Optional[str], class_name: str) -> UUID: ...
+def create_link(link_name: Optional[str], assoc_name: str, src: UUID, tgt: UUID) -> UUID: ...
+def delete(obj: UUID) -> None: ...
+def set_slot_value(obj: UUID, attr_name: str, new_value: any, is_code=False) -> None: ...

+ 18 - 0
api/od_stub_readonly.pyi

@@ -0,0 +1,18 @@
+from typing import Any
+from uuid import UUID
+
+def get(name: str) -> UUID: ...
+def get_value(obj: UUID) -> Any: ...
+def get_target(link: UUID) -> UUID: ...
+def get_source(link: UUID) -> UUID: ...
+def get_slot(obj: UUID, attr_name: str) -> UUID: ...
+def get_slots(obj: UUID) -> list[str]: ...
+def get_slot_value(obj: UUID, attr_name: str) -> Any: ...
+def get_slot_value_default(obj: UUID, attr_name: str, default: any) -> Any: ...
+def get_all_instances(type_name: str, include_subtypes=True) -> list[UUID]: ...
+def get_name(obj: UUID) -> str: ...
+def get_type_name(obj: UUID) -> str: ...
+def get_outgoing(obj: UUID, assoc_name: str, include_subtypes=True) -> list[UUID]: ...
+def get_incoming(obj: UUID, assoc_name: str, include_subtypes: object = True) -> list[UUID]: ...
+def has_slot(obj: UUID, attr_name: str) -> bool: ...
+def is_instance(obj: UUID, type_name: str, include_subtypes=True) -> bool: ...

examples/performance/runner.py → benchmark/runner.py


+ 2 - 2
concrete_syntax/textual_cd/parser.py

@@ -40,7 +40,7 @@ attrs: attr*
 
 constraint: CODE | INDENTED_CODE
 
-class_: [ABSTRACT] "class" IDENTIFIER [multiplicity] ["(" superclasses ")"]  ["{" attrs [constraint] "}"]
+class_: [ABSTRACT] "class" IDENTIFIER [multiplicity] ["(" superclasses ")"]  ["{" attrs [constraint ";"] "}"]
 
 association: "association" IDENTIFIER  [multiplicity] IDENTIFIER "->" IDENTIFIER [multiplicity] ["{" attrs [constraint] "}"]
 
@@ -75,7 +75,7 @@ def parse_cd(state, m_text):
 
     primitive_types = {
         type_name : UUID(state.read_value(state.read_dict(state.read_root(), type_name)))
-            for type_name in ["Integer", "String", "Boolean"]
+            for type_name in ["Integer", "String", "Boolean", "ActionCode"]
     }
 
     class T(TBase):

+ 34 - 0
examples/geraniums/geraniums_renderer.j2

@@ -0,0 +1,34 @@
+digraph G {
+    rankdir=LR;
+    center=true;
+    margin=1;
+    nodesep=1;
+
+    node [fontname="Arial", fontsize=10, shape=box, style=filled, fillcolor=white];
+
+    // Geraniums
+    {% for id, name, flowering in geraniums %}
+    g{{ id }} [
+        label="geranium: {{ name }}\n({{ 'flowering' if flowering else 'not flowering' }})",
+        shape=ellipse,
+        fillcolor="{{ 'lightpink' if flowering else 'lightgray' }}",
+        fontcolor=black
+    ];
+    {% endfor %}
+
+    // Pots
+    {% for id, name, cracked in pots %}
+    p{{ id }} [
+        label="pot: {{ name }}\n({{ 'cracked' if cracked else 'pristine' }})",
+        shape=box,
+        fillcolor="{{ 'mistyrose' if cracked else 'lightgreen' }}",
+        fontcolor=black,
+        style="filled,bold"
+    ];
+    {% endfor %}
+
+    // Connections: geranium -> pot
+    {% for source, target in planted %}
+    g{{ source }} -> p{{ target }};
+    {% endfor %}
+}

+ 9 - 0
examples/geraniums/metamodels/mm.od

@@ -0,0 +1,9 @@
+class Geranium {
+    Boolean flowering;
+}
+
+class Pot {
+    Boolean cracked;
+}
+
+association Planted [0..*] Geranium -> Pot [1..1]

+ 44 - 0
examples/geraniums/models/eval_context.py

@@ -0,0 +1,44 @@
+import os
+
+from jinja2 import Environment, FileSystemLoader
+
+from api.od import ODAPI
+from framework.conformance import eval_context_decorator
+
+
+@eval_context_decorator
+def _render_geraniums_dot(od: ODAPI, file: str) -> str:
+    __DIR__ = os.path.dirname(__file__)
+    env = Environment(
+        loader=FileSystemLoader(
+            __DIR__
+        )
+    )
+    env.trim_blocks = True
+    env.lstrip_blocks = True
+    template_dot = env.get_template("geraniums_renderer.j2")
+
+    id_count = 0
+    id_map = {}
+    render = {"geraniums": [], "pots": [], "planted": []}
+
+    for name, uuid in od.get_all_instances("Geranium"):
+        render["geraniums"].append((id_count, name, od.get_slot_value(uuid, "flowering")))
+        id_map[uuid] = id_count
+        id_count += 1
+
+    for name, uuid in od.get_all_instances("Pot"):
+        render["pots"].append((id_count, name, od.get_slot_value(uuid, "cracked")))
+        id_map[uuid] = id_count
+        id_count += 1
+
+    for name, uuid in od.get_all_instances("Planted"):
+        render["planted"].append((id_map[od.get_source(uuid)], id_map[od.get_target(uuid)]))
+
+    with open(file, "w", encoding="utf-8") as f_dot:
+        f_dot.write(template_dot.render(**render))
+    return ""
+
+eval_context = {
+    "render_geraniums_dot": _render_geraniums_dot,
+}

+ 17 - 0
examples/geraniums/models/example1.od

@@ -0,0 +1,17 @@
+f1:Geranium {
+    flowering = True;
+}
+f2:Geranium {
+    flowering = False;
+}
+f3:Geranium {
+    flowering = True;
+}
+
+p1:Pot {
+    cracked = True;
+}
+
+:Planted (f1 -> p1)
+:Planted (f2 -> p1)
+:Planted (f3 -> p1)

+ 47 - 0
examples/geraniums/models/example2.od

@@ -0,0 +1,47 @@
+f1:Geranium {
+    flowering = True;
+}
+f2:Geranium {
+    flowering = True;
+}
+f3:Geranium {
+    flowering = False;
+}
+
+p1:Pot {
+    cracked = True;
+}
+
+:Planted (f1 -> p1)
+:Planted (f2 -> p1)
+:Planted (f3 -> p1)
+
+
+
+
+f4:Geranium {
+    flowering = True;
+}
+p2:Pot {
+    cracked = True;
+}
+:Planted (f4 -> p2)
+
+
+
+f5:Geranium {
+    flowering = True;
+}
+p3:Pot {
+    cracked = False;
+}
+:Planted (f5 -> p3)
+
+
+f6:Geranium {
+    flowering = False;
+}
+p4:Pot {
+    cracked = True;
+}
+:Planted (f6 -> p4)

+ 45 - 0
examples/geraniums/renderer.py

@@ -0,0 +1,45 @@
+import os
+
+from jinja2 import Environment, FileSystemLoader
+
+from api.od import ODAPI
+from concrete_syntax.graphviz.make_url import show_graphviz
+from concrete_syntax.graphviz.renderer import make_graphviz_id
+
+try:
+    import graphviz
+    HAVE_GRAPHVIZ = True
+except ImportError:
+    HAVE_GRAPHVIZ = False
+
+def render_geraniums_dot(od: ODAPI, file: str) -> str:
+    __DIR__ = os.path.dirname(__file__)
+    env = Environment(
+        loader=FileSystemLoader(
+            __DIR__
+        )
+    )
+    env.trim_blocks = True
+    env.lstrip_blocks = True
+    template_dot = env.get_template("geraniums_renderer.j2")
+
+    id_count = 0
+    id_map = {}
+    render = {"geraniums": [], "pots": [], "planted": []}
+
+    for name, uuid in od.get_all_instances("Geranium"):
+        render["geraniums"].append((id_count, name, od.get_slot_value(uuid, "flowering")))
+        id_map[uuid] = id_count
+        id_count += 1
+
+    for name, uuid in od.get_all_instances("Pot"):
+        render["pots"].append((id_count, name, od.get_slot_value(uuid, "cracked")))
+        id_map[uuid] = id_count
+        id_count += 1
+
+    for name, uuid in od.get_all_instances("Planted"):
+        render["planted"].append((id_map[od.get_source(uuid)], id_map[od.get_target(uuid)]))
+
+    with open(file, "w", encoding="utf-8") as f_dot:
+        f_dot.write(template_dot.render(**render))
+    return ""

+ 3 - 0
examples/geraniums/rules/cracked_pots.od

@@ -0,0 +1,3 @@
+pot:RAM_Pot {
+    RAM_cracked = `get_value(this)`;
+}

+ 3 - 0
examples/geraniums/rules/create_pot.od

@@ -0,0 +1,3 @@
+pot:RAM_Pot {
+    RAM_cracked = `False`;
+}

+ 7 - 0
examples/geraniums/rules/flowering_flowers_in_pot.od

@@ -0,0 +1,7 @@
+pot:RAM_Pot
+
+flower:RAM_Geranium {
+    RAM_flowering = `get_value(this)`;
+}
+
+:RAM_Planted (flower -> pot)

+ 8 - 0
examples/geraniums/rules/repot_flower_in_pot.od

@@ -0,0 +1,8 @@
+pot:RAM_Pot
+new_pot:RAM_Pot
+
+flower:RAM_Geranium {
+    RAM_flowering = `get_value(this)`;
+}
+
+replant:RAM_Planted (flower -> new_pot)

+ 48 - 0
examples/geraniums/runner.py

@@ -0,0 +1,48 @@
+from examples.geraniums.renderer import render_geraniums_dot
+from transformation.ramify import ramify
+
+from models.eval_context import eval_context
+
+from transformation.schedule.rule_scheduler import *
+
+if __name__ == "__main__":
+    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()
+
+
+    state = DevState()
+    scd_mmm = bootstrap_scd(state)
+
+    mm_cs           =         read_file('metamodels/mm.od')
+    m_cs            =         read_file('models/example2.od')
+
+    mm = parser_cd.parse_cd(
+        state,
+        m_text=mm_cs,
+    )
+    m = parser_od.parse_od(
+        state, m_text=m_cs, mm=mm
+    )
+    conf_err = Conformance(
+        state, m, mm
+    ).check_nominal()
+    print(render_conformance_check_result(conf_err))
+    mm_ramified = ramify(state, mm)
+
+    action_generator = RuleScheduler(state, mm, mm_ramified, verbose=True, directory="examples/geraniums", eval_context=eval_context)
+    od = ODAPI(state, m, mm)
+    render_geraniums_dot(od, f"{THIS_DIR}/geraniums.dot")
+
+    # if action_generator.load_schedule(f"petrinet.od"):
+    # if action_generator.load_schedule("schedules/combinatory.drawio"):
+    if action_generator.load_schedule("schedules/schedule.drawio"):
+
+        action_generator.generate_dot("../dot.dot")
+        code, message = action_generator.run(od)
+        print(f"{code}: {message}")
+    render_geraniums_dot(od, f"{THIS_DIR}/geraniums_final.dot")

+ 645 - 0
examples/geraniums/schedules/schedule.drawio

@@ -0,0 +1,645 @@
+<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/27.0.5 Chrome/134.0.6998.205 Electron/35.3.0 Safari/537.36" version="27.0.5" pages="2">
+  <diagram name="main" id="pASKGN4qU69vjyreTE56">
+    <mxGraphModel dx="1389" dy="835" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="start" type="Start" ports_exec_out="[&quot;out&quot;]" ports_data_out="[]" id="cchbAGZklJLD93cgxIrT-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="80" y="110" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="cchbAGZklJLD93cgxIrT-1" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-2" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-2" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="cchbAGZklJLD93cgxIrT-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%&#xa;%file%&#xa;matches: %n%" placeholders="1" name="cracked pots" type="Match" file="rules/cracked_pots.od" n="" id="cchbAGZklJLD93cgxIrT-6">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=60;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="280" y="90" width="160" height="220" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-7" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="cchbAGZklJLD93cgxIrT-6" vertex="1">
+          <mxGeometry y="60" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-8" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-7" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="cchbAGZklJLD93cgxIrT-9">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="cchbAGZklJLD93cgxIrT-8" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="cchbAGZklJLD93cgxIrT-10">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-8" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-11" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-7" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="cchbAGZklJLD93cgxIrT-12">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="cchbAGZklJLD93cgxIrT-11" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="success" type="exec" id="cchbAGZklJLD93cgxIrT-13">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-11" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="fail" type="exec" id="cchbAGZklJLD93cgxIrT-14">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-11" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="cchbAGZklJLD93cgxIrT-5" target="cchbAGZklJLD93cgxIrT-10" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="end" type="End" ports_exec_in="[&quot;in&quot;]" ports_data_in="[]" id="cchbAGZklJLD93cgxIrT-24">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="520" y="350" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-25" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="cchbAGZklJLD93cgxIrT-24" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-26" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-25" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="cchbAGZklJLD93cgxIrT-27">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-26" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-28" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-25" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="cchbAGZklJLD93cgxIrT-14" target="cchbAGZklJLD93cgxIrT-27" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="500" y="230" />
+              <mxPoint x="500" y="420" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="remove cracked status&#xa;" type="Modify" rename="{}" delete="[&quot;pot_RAM_cracked&quot;, &quot;pot.RAM_cracked&quot;]" id="cchbAGZklJLD93cgxIrT-32">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="270" y="350" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-33" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="cchbAGZklJLD93cgxIrT-32" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-34" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-33" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="cchbAGZklJLD93cgxIrT-35">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="cchbAGZklJLD93cgxIrT-34" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-36" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-33" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="cchbAGZklJLD93cgxIrT-37">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="cchbAGZklJLD93cgxIrT-36" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="cchbAGZklJLD93cgxIrT-12" target="cchbAGZklJLD93cgxIrT-35" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="460" y="280" />
+              <mxPoint x="460" y="330" />
+              <mxPoint x="250" y="330" />
+              <mxPoint x="250" y="420" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%&#xa;matches: %n%" placeholders="1" name="flowering flower" type="Match" file="rules/flowering_flowers_in_pot.od" n="" id="cchbAGZklJLD93cgxIrT-41">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=60;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="760" y="40" width="160" height="220" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-42" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="cchbAGZklJLD93cgxIrT-41" vertex="1">
+          <mxGeometry y="60" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-43" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-42" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="cchbAGZklJLD93cgxIrT-44">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="cchbAGZklJLD93cgxIrT-43" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="cchbAGZklJLD93cgxIrT-45">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-43" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-46" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-42" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="cchbAGZklJLD93cgxIrT-47">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="cchbAGZklJLD93cgxIrT-46" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="success" type="exec" id="cchbAGZklJLD93cgxIrT-48">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-46" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="fail" type="exec" id="cchbAGZklJLD93cgxIrT-49">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-46" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="iterate pots" type="Loop" id="cchbAGZklJLD93cgxIrT-53">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="520" y="110" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-54" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="cchbAGZklJLD93cgxIrT-53" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-55" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-54" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="cchbAGZklJLD93cgxIrT-56">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="cchbAGZklJLD93cgxIrT-55" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="cchbAGZklJLD93cgxIrT-57">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-55" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-58" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="cchbAGZklJLD93cgxIrT-54" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="cchbAGZklJLD93cgxIrT-59">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="cchbAGZklJLD93cgxIrT-58" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="it" type="exec" id="cchbAGZklJLD93cgxIrT-60">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-58" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="exec" id="cchbAGZklJLD93cgxIrT-61">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="cchbAGZklJLD93cgxIrT-58" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="cchbAGZklJLD93cgxIrT-62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="cchbAGZklJLD93cgxIrT-13" target="cchbAGZklJLD93cgxIrT-57" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="460" y="180" />
+              <mxPoint x="460" y="180" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-63" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="cchbAGZklJLD93cgxIrT-37" target="cchbAGZklJLD93cgxIrT-56" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="480" y="420" />
+              <mxPoint x="480" y="280" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-65" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="cchbAGZklJLD93cgxIrT-60" target="cchbAGZklJLD93cgxIrT-45" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="cchbAGZklJLD93cgxIrT-84" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="cchbAGZklJLD93cgxIrT-49" target="cchbAGZklJLD93cgxIrT-57" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="940" y="180" />
+              <mxPoint x="940" y="20" />
+              <mxPoint x="500" y="20" />
+              <mxPoint x="500" y="180" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="repot flowers" type="Schedule" file="repot_flowers" id="COygDAZokINshI2ZcMDj-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="980" y="60" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="COygDAZokINshI2ZcMDj-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="COygDAZokINshI2ZcMDj-1" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="COygDAZokINshI2ZcMDj-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="COygDAZokINshI2ZcMDj-2" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="COygDAZokINshI2ZcMDj-4">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="COygDAZokINshI2ZcMDj-3" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="flowers" type="data" id="OE_qcAbxz6Js6tdFO397-1">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="COygDAZokINshI2ZcMDj-3" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="COygDAZokINshI2ZcMDj-5" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="COygDAZokINshI2ZcMDj-2" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="COygDAZokINshI2ZcMDj-6">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="COygDAZokINshI2ZcMDj-5" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="OE_qcAbxz6Js6tdFO397-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="cchbAGZklJLD93cgxIrT-47" target="OE_qcAbxz6Js6tdFO397-1" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="960" y="230" />
+              <mxPoint x="960" y="180" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="OE_qcAbxz6Js6tdFO397-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="cchbAGZklJLD93cgxIrT-48" target="COygDAZokINshI2ZcMDj-4" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="OE_qcAbxz6Js6tdFO397-6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="COygDAZokINshI2ZcMDj-6" target="cchbAGZklJLD93cgxIrT-57" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="1200" y="130" />
+              <mxPoint x="1200" y="20" />
+              <mxPoint x="500" y="20" />
+              <mxPoint x="500" y="180" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="EqK5vrE8kE92bJcIEnmP-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="cchbAGZklJLD93cgxIrT-61" target="cchbAGZklJLD93cgxIrT-27" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="720" y="230" />
+              <mxPoint x="720" y="330" />
+              <mxPoint x="500" y="330" />
+              <mxPoint x="500" y="420" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="tqyI29rS8I0LFEd-KlyY-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" edge="1" parent="1" source="cchbAGZklJLD93cgxIrT-59" target="cchbAGZklJLD93cgxIrT-44">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="740" y="280" />
+              <mxPoint x="740" y="230" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram id="c3Tuc6LHjhM7aXRdpPRx" name="repot_flowers">
+    <mxGraphModel dx="1042" dy="626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="start_repotting" type="Start" ports_exec_out="[&quot;out&quot;]" ports_data_out="[&quot;flowers&quot;, &quot;old_pot&quot;]" id="gjxSdUMfFO3v8k7oyOzM-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="80" y="240" width="160" height="160" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="gjxSdUMfFO3v8k7oyOzM-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="gjxSdUMfFO3v8k7oyOzM-1" vertex="1">
+          <mxGeometry y="40" width="160" height="120" as="geometry" />
+        </mxCell>
+        <mxCell id="gjxSdUMfFO3v8k7oyOzM-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="gjxSdUMfFO3v8k7oyOzM-2" vertex="1">
+          <mxGeometry width="80" height="120" as="geometry">
+            <mxRectangle width="80" height="120" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="gjxSdUMfFO3v8k7oyOzM-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="gjxSdUMfFO3v8k7oyOzM-2" vertex="1">
+          <mxGeometry x="80" width="80" height="120" as="geometry">
+            <mxRectangle width="80" height="120" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="gjxSdUMfFO3v8k7oyOzM-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="gjxSdUMfFO3v8k7oyOzM-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="flowers" type="data" id="gjxSdUMfFO3v8k7oyOzM-6">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="gjxSdUMfFO3v8k7oyOzM-4" vertex="1">
+            <mxGeometry x="10" y="70" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="end" type="End" ports_exec_in="[&quot;in&quot;]" ports_data_in="[]" id="gjxSdUMfFO3v8k7oyOzM-8">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="740" y="410" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="gjxSdUMfFO3v8k7oyOzM-9" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="gjxSdUMfFO3v8k7oyOzM-8" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="gjxSdUMfFO3v8k7oyOzM-10" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="gjxSdUMfFO3v8k7oyOzM-9" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="gjxSdUMfFO3v8k7oyOzM-11">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="gjxSdUMfFO3v8k7oyOzM-10" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="gjxSdUMfFO3v8k7oyOzM-12" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="gjxSdUMfFO3v8k7oyOzM-9" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="iterate flowers" type="Loop" id="rgPZtlXADXUwMSGqODkz-8">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="500" y="240" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-9" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="rgPZtlXADXUwMSGqODkz-8" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-10" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rgPZtlXADXUwMSGqODkz-9" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="rgPZtlXADXUwMSGqODkz-11">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-10" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="rgPZtlXADXUwMSGqODkz-12">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="rgPZtlXADXUwMSGqODkz-10" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-13" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rgPZtlXADXUwMSGqODkz-9" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="rgPZtlXADXUwMSGqODkz-14">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-13" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="it" type="exec" id="rgPZtlXADXUwMSGqODkz-15">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="rgPZtlXADXUwMSGqODkz-13" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="exec" id="rgPZtlXADXUwMSGqODkz-16">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="rgPZtlXADXUwMSGqODkz-13" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="create new pot" type="Rewrite" file="rules/create_pot.od" id="rgPZtlXADXUwMSGqODkz-17">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="280" y="240.0000000000001" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-18" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="rgPZtlXADXUwMSGqODkz-17" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-19" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rgPZtlXADXUwMSGqODkz-18" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="rgPZtlXADXUwMSGqODkz-20">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="rgPZtlXADXUwMSGqODkz-19" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-21" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rgPZtlXADXUwMSGqODkz-18" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="rgPZtlXADXUwMSGqODkz-22">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="rgPZtlXADXUwMSGqODkz-21" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="data" id="rgPZtlXADXUwMSGqODkz-23">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-21" vertex="1">
+            <mxGeometry x="-70" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="data" id="rgPZtlXADXUwMSGqODkz-24">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-21" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="remove cracked status&#xa;" type="Modify" rename="{&quot;pot&quot;: &quot;new_pot&quot;}" delete="[&quot;pot_RAM_cracked&quot;, &quot;pot.RAM_cracked&quot;]" id="rgPZtlXADXUwMSGqODkz-32">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="280" y="450" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-33" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="rgPZtlXADXUwMSGqODkz-32" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-34" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rgPZtlXADXUwMSGqODkz-33" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="rgPZtlXADXUwMSGqODkz-35">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-34" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-36" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rgPZtlXADXUwMSGqODkz-33" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="rgPZtlXADXUwMSGqODkz-37">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-36" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="gjxSdUMfFO3v8k7oyOzM-5" target="rgPZtlXADXUwMSGqODkz-20" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-40" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="rgPZtlXADXUwMSGqODkz-24" target="rgPZtlXADXUwMSGqODkz-35" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="460" y="360" />
+              <mxPoint x="460" y="430" />
+              <mxPoint x="260" y="430" />
+              <mxPoint x="260" y="520" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-42" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="gjxSdUMfFO3v8k7oyOzM-6" target="rgPZtlXADXUwMSGqODkz-11" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="260" y="370" />
+              <mxPoint x="260" y="410" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="combine new pot and flower&#xa;" type="Merge" ports_data_in="[&quot;flower&quot;, &quot;new_pot&quot;]" id="rgPZtlXADXUwMSGqODkz-43">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="500" y="480" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-44" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="rgPZtlXADXUwMSGqODkz-43" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-45" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rgPZtlXADXUwMSGqODkz-44" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="flower" type="data" id="rgPZtlXADXUwMSGqODkz-46">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-45" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="new_pot" type="data" id="rgPZtlXADXUwMSGqODkz-47">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-45" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-48" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rgPZtlXADXUwMSGqODkz-44" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="rgPZtlXADXUwMSGqODkz-49">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rgPZtlXADXUwMSGqODkz-48" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-50" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="rgPZtlXADXUwMSGqODkz-14" target="rgPZtlXADXUwMSGqODkz-46" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="680" y="410" />
+              <mxPoint x="680" y="460" />
+              <mxPoint x="480" y="460" />
+              <mxPoint x="480" y="550" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="rgPZtlXADXUwMSGqODkz-60" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="rgPZtlXADXUwMSGqODkz-37" target="rgPZtlXADXUwMSGqODkz-47" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="460" y="520" />
+              <mxPoint x="460" y="600" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="move flower to new pot&#xa;" type="Rewrite" file="rules/repot_flower_in_pot.od" id="rggt9Ju99cdMwxSiOdaC-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="740" y="240.0000000000001" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rggt9Ju99cdMwxSiOdaC-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="rggt9Ju99cdMwxSiOdaC-1" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="rggt9Ju99cdMwxSiOdaC-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rggt9Ju99cdMwxSiOdaC-2" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="rggt9Ju99cdMwxSiOdaC-4">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="rggt9Ju99cdMwxSiOdaC-3" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rggt9Ju99cdMwxSiOdaC-5" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="rggt9Ju99cdMwxSiOdaC-2" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="rggt9Ju99cdMwxSiOdaC-6">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="rggt9Ju99cdMwxSiOdaC-5" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="data" id="rggt9Ju99cdMwxSiOdaC-7">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rggt9Ju99cdMwxSiOdaC-5" vertex="1">
+            <mxGeometry x="-70" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="data" id="rggt9Ju99cdMwxSiOdaC-8">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="rggt9Ju99cdMwxSiOdaC-5" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="rggt9Ju99cdMwxSiOdaC-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="rgPZtlXADXUwMSGqODkz-15" target="rggt9Ju99cdMwxSiOdaC-4" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="rggt9Ju99cdMwxSiOdaC-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="rgPZtlXADXUwMSGqODkz-49" target="rggt9Ju99cdMwxSiOdaC-7" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="720" y="550" />
+              <mxPoint x="720" y="360" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="rggt9Ju99cdMwxSiOdaC-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="rggt9Ju99cdMwxSiOdaC-6" target="rgPZtlXADXUwMSGqODkz-12" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="920" y="310" />
+              <mxPoint x="920" y="220" />
+              <mxPoint x="480" y="220" />
+              <mxPoint x="480" y="310" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="rggt9Ju99cdMwxSiOdaC-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="rgPZtlXADXUwMSGqODkz-16" target="gjxSdUMfFO3v8k7oyOzM-11" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="700" y="360" />
+              <mxPoint x="700" y="480" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="nF2FpsghIUv3jzvNKQr9-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="rgPZtlXADXUwMSGqODkz-22" target="rgPZtlXADXUwMSGqODkz-12">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>

+ 0 - 0
examples/geraniums/schedules/schedule.od


+ 0 - 139
examples/model_transformation/woods.plantuml

@@ -1,139 +0,0 @@
-package "DSL Meta-Model" {
-class "Bear" as 00000000_0000_0000_0000_00000000046d {
-}
-abstract class "Animal" as 00000000_0000_0000_0000_000000000474 {
-}
-class "Man" as 00000000_0000_0000_0000_000000000491 {
-  weight : Integer
-}
-
-00000000_0000_0000_0000_000000000474 <|-- 00000000_0000_0000_0000_000000000491
-00000000_0000_0000_0000_000000000474 <|-- 00000000_0000_0000_0000_00000000046d
-
-00000000_0000_0000_0000_000000000491 " " --> "1 .. *" 00000000_0000_0000_0000_000000000474 : afraidOf
-}
-package "Int Meta-Model" {
-class "Integer" as 00000000_0000_0000_0000_000000000094 {
-}
-
-
-}
-package "RAMified DSL Meta-Model" {
-class "RAM_Bear" as 00000000_0000_0000_0000_0000000005bb {
-}
-class "RAM_Animal" as 00000000_0000_0000_0000_0000000005c5 {
-}
-class "RAM_Man" as 00000000_0000_0000_0000_0000000005cf {
-  RAM_weight : ActionCode
-}
-
-00000000_0000_0000_0000_0000000005c5 <|-- 00000000_0000_0000_0000_0000000005cf
-00000000_0000_0000_0000_0000000005c5 <|-- 00000000_0000_0000_0000_0000000005bb
-
-00000000_0000_0000_0000_0000000005cf " " --> "0 .. *" 00000000_0000_0000_0000_0000000005c5 : RAM_afraidOf
-}
-package "RAMified Int Meta-Model" {
-class "RAM_Integer" as 00000000_0000_0000_0000_00000000064c {
-}
-
-
-}
-00000000_0000_0000_0000_0000000005bb ..> 00000000_0000_0000_0000_00000000046d #line:green;text:green : RAMifies
-00000000_0000_0000_0000_0000000005c5 ..> 00000000_0000_0000_0000_000000000474 #line:green;text:green : RAMifies
-00000000_0000_0000_0000_0000000005cf ..> 00000000_0000_0000_0000_000000000491 #line:green;text:green : RAMifies
-00000000_0000_0000_0000_0000000005cf::RAM_weight ..> 00000000_0000_0000_0000_000000000491::weight #line:green;text:green : RAMifies
-00000000_0000_0000_0000_00000000064c ..> 00000000_0000_0000_0000_000000000094 #line:green;text:green : RAMifies
-package "LHS" {
-map "scaryAnimal : RAM_Animal" as 00000000_0000_0000_0000_00000000068a {
-}
-map "man : RAM_Man" as 00000000_0000_0000_0000_00000000066d {
-RAM_weight => `v > 60`
-}
-
-00000000_0000_0000_0000_00000000066d -> 00000000_0000_0000_0000_00000000068a : :RAM_afraidOf
-}
-00000000_0000_0000_0000_00000000068a ..> 00000000_0000_0000_0000_0000000005c5 #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_00000000066d ..> 00000000_0000_0000_0000_0000000005cf #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_00000000066d::RAM_weight ..> 00000000_0000_0000_0000_0000000005cf::RAM_weight #line:blue;text:blue : instanceOf
-
-package "RHS" {
-map "man : RAM_Man" as 00000000_0000_0000_0000_000000000699 {
-RAM_weight => `v + 5`
-}
-map "bill : RAM_Man" as 00000000_0000_0000_0000_0000000006b6 {
-RAM_weight => `100`
-}
-
-00000000_0000_0000_0000_0000000006b6 -> 00000000_0000_0000_0000_000000000699 : :RAM_afraidOf
-}
-00000000_0000_0000_0000_000000000699 ..> 00000000_0000_0000_0000_0000000005cf #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_000000000699::RAM_weight ..> 00000000_0000_0000_0000_0000000005cf::RAM_weight #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_0000000006b6 ..> 00000000_0000_0000_0000_0000000005cf #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_0000000006b6::RAM_weight ..> 00000000_0000_0000_0000_0000000005cf::RAM_weight #line:blue;text:blue : instanceOf
-
-package "Model (before rewrite)" {
-map "bear2 : Bear" as 00000000_0000_0000_0000_000000000597 {
-}
-map "bear1 : Bear" as 00000000_0000_0000_0000_000000000590 {
-}
-map "george : Man" as 00000000_0000_0000_0000_000000000573 {
-weight => 80
-}
-
-00000000_0000_0000_0000_000000000573 -> 00000000_0000_0000_0000_000000000590 : :afraidOf
-00000000_0000_0000_0000_000000000573 -> 00000000_0000_0000_0000_000000000597 : :afraidOf
-}
-00000000_0000_0000_0000_000000000597 ..> 00000000_0000_0000_0000_00000000046d #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_000000000590 ..> 00000000_0000_0000_0000_00000000046d #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_000000000573 ..> 00000000_0000_0000_0000_000000000491 #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_000000000573::weight ..> 00000000_0000_0000_0000_000000000491::weight #line:blue;text:blue : instanceOf
-
-00000000_0000_0000_0000_00000000068a ..> 00000000_0000_0000_0000_000000000590 #line:red;line.dotted;text:red : matchedWith
-00000000_0000_0000_0000_00000000066d ..> 00000000_0000_0000_0000_000000000573 #line:red;line.dotted;text:red : matchedWith
-00000000_0000_0000_0000_00000000066d::RAM_weight ..> 00000000_0000_0000_0000_000000000573::weight #line:red;line.dotted;text:red : matchedWith
-package "Model (after rewrite 0)" {
-map "bear2 : Bear" as 00000000_0000_0000_0000_0000000006db {
-}
-map "george : Man" as 00000000_0000_0000_0000_0000000006e9 {
-weight => 85
-}
-map "bill0 : Man" as 00000000_0000_0000_0000_000000000723 {
-weight => 100
-}
-
-00000000_0000_0000_0000_000000000723 -> 00000000_0000_0000_0000_0000000006e9 : :afraidOf
-00000000_0000_0000_0000_0000000006e9 -> 00000000_0000_0000_0000_0000000006db : :afraidOf
-}
-00000000_0000_0000_0000_000000000699 ..> 00000000_0000_0000_0000_0000000006e9 #line:red;line.dotted;text:red : matchedWith
-00000000_0000_0000_0000_000000000699::RAM_weight ..> 00000000_0000_0000_0000_0000000006e9::weight #line:red;line.dotted;text:red : matchedWith
-00000000_0000_0000_0000_0000000006b6 ..> 00000000_0000_0000_0000_000000000723 #line:red;line.dotted;text:red : matchedWith
-00000000_0000_0000_0000_0000000006db ..> 00000000_0000_0000_0000_00000000046d #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_0000000006e9 ..> 00000000_0000_0000_0000_000000000491 #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_0000000006e9::weight ..> 00000000_0000_0000_0000_000000000491::weight #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_000000000723 ..> 00000000_0000_0000_0000_000000000491 #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_000000000723::weight ..> 00000000_0000_0000_0000_000000000491::weight #line:blue;text:blue : instanceOf
-
-00000000_0000_0000_0000_00000000068a ..> 00000000_0000_0000_0000_000000000597 #line:orange;line.dotted;text:orange : matchedWith
-00000000_0000_0000_0000_00000000066d ..> 00000000_0000_0000_0000_000000000573 #line:orange;line.dotted;text:orange : matchedWith
-00000000_0000_0000_0000_00000000066d::RAM_weight ..> 00000000_0000_0000_0000_000000000573::weight #line:orange;line.dotted;text:orange : matchedWith
-package "Model (after rewrite 1)" {
-map "bear1 : Bear" as 00000000_0000_0000_0000_000000000747 {
-}
-map "george : Man" as 00000000_0000_0000_0000_00000000074e {
-weight => 85
-}
-map "bill0 : Man" as 00000000_0000_0000_0000_000000000788 {
-weight => 100
-}
-
-00000000_0000_0000_0000_000000000788 -> 00000000_0000_0000_0000_00000000074e : :afraidOf
-00000000_0000_0000_0000_00000000074e -> 00000000_0000_0000_0000_000000000747 : :afraidOf
-}
-00000000_0000_0000_0000_000000000699 ..> 00000000_0000_0000_0000_00000000074e #line:orange;line.dotted;text:orange : matchedWith
-00000000_0000_0000_0000_000000000699::RAM_weight ..> 00000000_0000_0000_0000_00000000074e::weight #line:orange;line.dotted;text:orange : matchedWith
-00000000_0000_0000_0000_0000000006b6 ..> 00000000_0000_0000_0000_000000000788 #line:orange;line.dotted;text:orange : matchedWith
-00000000_0000_0000_0000_000000000747 ..> 00000000_0000_0000_0000_00000000046d #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_00000000074e ..> 00000000_0000_0000_0000_000000000491 #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_00000000074e::weight ..> 00000000_0000_0000_0000_000000000491::weight #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_000000000788 ..> 00000000_0000_0000_0000_000000000491 #line:blue;text:blue : instanceOf
-00000000_0000_0000_0000_000000000788::weight ..> 00000000_0000_0000_0000_000000000491::weight #line:blue;text:blue : instanceOf

+ 0 - 245
examples/model_transformation/woods.py

@@ -1,245 +0,0 @@
-# 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
-
-def 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")))
-
-    # conf = Conformance(state, scd_mmm_id, scd_mmm_id)
-    # print("Conformance SCD_MM -> SCD_MM?", conf.check_nominal(log=True))
-    # print("--------------------------------------")
-    # print(renderer.render_od(state, scd_mmm_id, scd_mmm_id, hide_names=True))
-    # print("--------------------------------------")
-
-    # Create DSL MM with parser
-    dsl_mm_cs = """
-        # Integer:ModelRef
-        Bear:Class
-        Animal:Class {
-            abstract = True;
-        }
-        Man:Class {
-            lower_cardinality = 1;
-            upper_cardinality = 2;
-            constraint = ```
-                get_value(get_slot(this, "weight")) > 20
-            ```;
-        }
-        Man_weight:AttributeLink (Man -> Integer) {
-            name = "weight";
-            optional = False;
-            constraint = ```
-                # this is the same constraint as above, but this time, part of the attributelink itself (and thus shorter)
-                tgt = get_target(this)
-                tgt_type = get_type_name(tgt)
-                get_value(tgt) > 20
-            ```;
-        }
-        afraidOf:Association (Man -> Animal) {
-            target_lower_cardinality = 1;
-        }
-        :Inheritance (Man -> Animal)
-        :Inheritance (Bear -> Animal)
-
-        not_too_fat:GlobalConstraint {
-            constraint = ```
-                # total weight of all men low enough
-                total_weight = 0
-                for man_name, man_id in get_all_instances("Man"):
-                    total_weight += get_value(get_slot(man_id, "weight"))
-                total_weight < 85
-            ```;
-        }
-    """
-    dsl_mm_id = parser.parse_od(state, dsl_mm_cs, mm=scd_mmm_id)
-    
-    # Create DSL M with parser
-    dsl_m_cs = """
-        george:Man {
-            weight = 80;
-        }
-        bear1:Bear
-        bear2:Bear
-        :afraidOf (george -> bear1)
-        :afraidOf (george -> bear2)
-    """
-    dsl_m_id = parser.parse_od(state, dsl_m_cs, mm=dsl_mm_id)
-
-    # print("DSL MM:")
-    # print("--------------------------------------")
-    # print(renderer.render_od(state, dsl_mm_id, scd_mmm_id, hide_names=True))
-    # print("--------------------------------------")
-
-    conf = Conformance(state, dsl_mm_id, scd_mmm_id)
-    print("Conformance DSL_MM -> SCD_MM?", conf.check_nominal(log=True))
-
-    # print("DSL M:")
-    # print("--------------------------------------")
-    # print(renderer.render_od(state, dsl_m_id, dsl_mm_id, hide_names=True))
-    # print("--------------------------------------")
-
-    conf = Conformance(state, dsl_m_id, dsl_mm_id)
-    print("Conformance DSL_M -> DSL_MM?", conf.check_nominal(log=True))
-
-    # 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
-    lhs_cs = f"""
-        # object to match
-        man:{prefix}Man {{
-            # match only men heavy enough
-            {prefix}weight = `get_value(this) > 60`;
-        }}
-
-        # object to delete
-        scaryAnimal:{prefix}Animal
-
-        # link to delete
-        manAfraidOfAnimal:{prefix}afraidOf (man -> scaryAnimal)
-    """
-    lhs_id = parser.parse_od(state, lhs_cs, mm=ramified_mm_id)
-
-
-    conf = Conformance(state, lhs_id, ramified_mm_id)
-    print("Conformance LHS_M -> RAM_DSL_MM?", conf.check_nominal(log=True))
-
-    # RHS of our rule
-
-    # TODO: enable more powerful actions
-    rhs_cs = f"""
-        # matched object
-        man:{prefix}Man {{
-            # man gains weight
-            {prefix}weight = `get_value(this) + 5`;
-        }}
-
-        # object to create
-        bill:{prefix}Man {{
-            # name = `"billie"+str(get_slot_value(matched("man"), "weight"))`;
-            {prefix}weight = `100`;
-        }}
-
-        # link to create
-        billAfraidOfMan:{prefix}afraidOf (bill -> man)
-    """
-    rhs_id = parser.parse_od(state, rhs_cs, mm=ramified_mm_id)
-
-    conf = Conformance(state, rhs_id, ramified_mm_id)
-    print("Conformance RHS_M -> RAM_DSL_MM?", conf.check_nominal(log=True))
-
-    def render_ramification():
-        uml = (""
-            # Render original and RAMified meta-models
-            + plantuml.render_package("DSL Meta-Model", plantuml.render_class_diagram(state, dsl_mm_id))
-            + plantuml.render_package("Int Meta-Model", plantuml.render_class_diagram(state, int_mm_id))
-            + plantuml.render_package("RAMified DSL Meta-Model", plantuml.render_class_diagram(state, ramified_mm_id))
-            + plantuml.render_package("RAMified Int Meta-Model", plantuml.render_class_diagram(state, ramified_int_mm_id))
-
-            # Render RAMification traceability links
-            + plantuml.render_trace_ramifies(state, dsl_mm_id, ramified_mm_id)
-            + plantuml.render_trace_ramifies(state, int_mm_id, ramified_int_mm_id)
-        )
-
-        return uml
-
-    def render_lhs_rhs():
-        uml = render_ramification()
-        # Render pattern
-        uml += plantuml.render_package("LHS", plantuml.render_object_diagram(state, lhs_id, ramified_mm_id))
-        uml += plantuml.render_trace_conformance(state, lhs_id, ramified_mm_id)
-
-        # Render pattern
-        uml += plantuml.render_package("RHS", plantuml.render_object_diagram(state, rhs_id, ramified_mm_id))
-        uml += plantuml.render_trace_conformance(state, rhs_id, ramified_mm_id)
-        return uml
-
-
-    def render_all_matches():
-        uml = render_lhs_rhs()
-        # Render host graph (before rewriting)
-        uml += plantuml.render_package("Model (before rewrite)", plantuml.render_object_diagram(state, dsl_m_id, dsl_mm_id))
-        # Render conformance
-        uml += plantuml.render_trace_conformance(state, dsl_m_id, dsl_mm_id)
-
-        print("matching...")
-        generator = match_od(state, dsl_m_id, dsl_mm_id, lhs_id, ramified_mm_id)
-        for match, color in zip(generator, ["red", "orange"]):
-            print("\nMATCH:\n", match)
-
-            # Render every match
-            uml += plantuml.render_trace_match(state, match, lhs_id, dsl_m_id, color)
-
-        print("DONE")
-        return uml
-
-    def render_rewrite():
-        uml = render_lhs_rhs()
-
-        # Render host graph (before rewriting)
-        uml += plantuml.render_package("Model (before rewrite)", plantuml.render_object_diagram(state, dsl_m_id, dsl_mm_id))
-        # Render conformance
-        uml += plantuml.render_trace_conformance(state, dsl_m_id, dsl_mm_id)
-
-        generator = match_od(state, dsl_m_id, dsl_mm_id, lhs_id, ramified_mm_id)
-        for i, (match, color) in enumerate(zip(generator, ["red", "orange"])):
-            print("\nMATCH:\n", match)
-            uml += plantuml.render_trace_match(state, match, lhs_id, dsl_m_id, color)
-
-            # rewrite happens in-place (which sucks), so we will only modify a clone:
-            snapshot_dsl_m_id = clone_od(state, dsl_m_id, dsl_mm_id)
-            rewriter.rewrite(state, lhs_id, rhs_id, ramified_mm_id, match, snapshot_dsl_m_id, dsl_mm_id)
-
-            conf = Conformance(state, snapshot_dsl_m_id, dsl_mm_id)
-            print(f"Conformance DSL_M (after rewrite {i}) -> DSL_MM?", conf.check_nominal(log=True))
-
-            # Render host graph (after rewriting)
-            uml += plantuml.render_package(f"Model (after rewrite {i})", plantuml.render_object_diagram(state, snapshot_dsl_m_id, dsl_mm_id))
-            # Render match
-            uml += plantuml.render_trace_match(state, match, rhs_id, snapshot_dsl_m_id, color)
-            # Render conformance
-            uml += plantuml.render_trace_conformance(state, snapshot_dsl_m_id, dsl_mm_id)
-
-        return uml
-
-    # plantuml_str = render_ramification()
-    # plantuml_str = render_all_matches()
-    plantuml_str = render_rewrite()
-
-    print()
-    print("==============================================")
-    print("BEGIN PLANTUML")
-    print("==============================================")
-
-    print(make_plantuml_url(plantuml_str))
-
-    print("==============================================")
-    print("END PLANTUML")
-    print("==============================================")
-
-if __name__ == "__main__":
-    main()

+ 12 - 1
examples/petrinet/models/m_example_simple.od

@@ -1,5 +1,8 @@
 p0:PNPlace
 p1:PNPlace
+p2:PNPlace
+p3:PNPlace
+p4:PNPlace
 
 t0:PNTransition
 :arc (p0 -> t0)
@@ -7,4 +10,12 @@ t0:PNTransition
 
 t1:PNTransition
 :arc (p1 -> t1)
-:arc (t1 -> p0)
+:arc (t1 -> p2)
+
+t2:PNTransition
+:arc (p2 -> t2)
+:arc (t2 -> p0)
+
+
+t3:PNTransition
+:arc (t3 -> p4)

+ 18 - 0
examples/petrinet/models/m_example_simple_rt_initial.od

@@ -9,3 +9,21 @@ p1s:PNPlaceState {
 }
 
 :pn_of (p1s -> p1)
+
+p2s:PNPlaceState {
+  numTokens = 0;
+}
+
+:pn_of (p2s -> p2)
+
+p3s:PNPlaceState {
+  numTokens = 0;
+}
+
+:pn_of (p3s -> p3)
+
+p4s:PNPlaceState {
+  numTokens = 0;
+}
+
+:pn_of (p4s -> p4)

+ 13 - 0
examples/petrinet/models/rules/all_incoming.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `True`;
+}
+:RAM_pn_of (ps -> p)
+
+# An incoming arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (p -> t)

+ 13 - 0
examples/petrinet/models/rules/all_incomming.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `True`;
+}
+:RAM_pn_of (ps -> p)
+
+# An incoming arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (p -> t)

+ 13 - 0
examples/petrinet/models/rules/all_outgoing.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `True`;
+}
+:RAM_pn_of (ps -> p)
+
+# An incoming arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (t -> p)

+ 13 - 0
examples/petrinet/models/rules/increase_outgoing.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `get_value(this) + 1`;
+}
+:RAM_pn_of (ps -> p)
+
+# An outgoing arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (t -> p)

examples/petrinet/operational_semantics/all_input_have_token.od → examples/petrinet/models/rules/input_without_token.od


+ 3 - 0
examples/petrinet/models/rules/places.od

@@ -0,0 +1,3 @@
+# A place with no tokens:
+
+p:RAM_PNPlace

+ 13 - 0
examples/petrinet/models/rules/reduce_incoming.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `get_value(this) -1`;
+}
+:RAM_pn_of (ps -> p)
+
+# An incoming arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (p -> t)

+ 13 - 0
examples/petrinet/models/rules/reduce_incomming.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `get_value(this) -1`;
+}
+:RAM_pn_of (ps -> p)
+
+# An incoming arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (p -> t)

+ 1 - 0
examples/petrinet/models/rules/transition.od

@@ -0,0 +1 @@
+t:RAM_PNTransition

+ 0 - 66
examples/petrinet/models/schedule.od

@@ -1,66 +0,0 @@
-start:Start
-end:End
-
-transitions:Match{
-    file = "operational_semantics/transition";
-}
-
-
-d:Data_modify
-{
-    modify_dict = '
-    {
-    "tr": "t"
-    }';
-}
-
-nac_input_without:Match{
-    file = "operational_semantics/all_input_have_token";
-    n = "1";
-}
-
-inputs:Match{
-    file = "operational_semantics/all_inputs";
-}
-
-rewrite_incoming:Rewrite
-{
-    file = "operational_semantics/remove_incoming";
-}
-
-loop_trans:Loop
-loop_input:Loop
-
-p:Print
-{
-event = True;
-label = "transition: ";
-}
-
-p2:Print
-{
-event = True;
-label = "inputs: ";
-}
-
-:Exec_con(start -> transitions){gate_from = 0;gate_to = 0;}
-:Exec_con(transitions -> end){gate_from = 1;gate_to = 0;}
-:Exec_con(transitions -> loop_trans){gate_from = 0;gate_to = 0;}
-:Exec_con(loop_trans -> nac_input_without){gate_from = 0;gate_to = 0;}
-
-[//]: # (:Exec_con&#40;nac_input_without -> loop_trans&#41;{gate_from = 0;gate_to = 0;})
-:Exec_con(nac_input_without -> inputs){gate_from = 1;gate_to = 0;}
-:Exec_con(inputs -> loop_input){gate_from = 0;gate_to = 0;}
-:Exec_con(inputs -> loop_trans){gate_from = 1;gate_to = 0;}
-
-:Exec_con(loop_trans -> end){gate_from = 1;gate_to = 0;}
-
-:Data_con(transitions -> loop_trans)
-:Data_con(nac_input_without -> p)
-:Data_con(d -> nac_input_without)
-:Data_con(loop_trans -> d)
-:Data_con(loop_trans -> rewrite_incoming)
-
-
-
-

+ 526 - 0
examples/petrinet/models/schedules/combinatory.drawio

@@ -0,0 +1,526 @@
+<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/27.0.5 Chrome/134.0.6998.205 Electron/35.3.0 Safari/537.36" version="27.0.5" pages="2">
+  <diagram name="main" id="PAlQ5KCi60ZyLzQCaE8o">
+    <mxGraphModel dx="1042" dy="626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="start_name" type="Start" ports_exec_out="[&quot;out&quot;]" ports_data_out="[]" id="XJBxcrHkF3XFgZlLdMPd-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="20" y="260" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="XJBxcrHkF3XFgZlLdMPd-1" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-2" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-2" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="XJBxcrHkF3XFgZlLdMPd-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="XJBxcrHkF3XFgZlLdMPd-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="schedule_name" type="Schedule" file="recursion" id="XJBxcrHkF3XFgZlLdMPd-6">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="425" y="260" width="160" height="180" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-7" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="XJBxcrHkF3XFgZlLdMPd-6" vertex="1">
+          <mxGeometry y="40" width="160" height="140" as="geometry" />
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-8" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-7" vertex="1">
+          <mxGeometry width="80" height="140" as="geometry">
+            <mxRectangle width="80" height="140" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="XJBxcrHkF3XFgZlLdMPd-9">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="XJBxcrHkF3XFgZlLdMPd-8" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="all_places" type="data" id="tqCyT2AFxwHsmUbf2qyE-12">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="XJBxcrHkF3XFgZlLdMPd-8" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-10" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-7" vertex="1">
+          <mxGeometry x="80" width="80" height="140" as="geometry">
+            <mxRectangle width="80" height="140" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="XJBxcrHkF3XFgZlLdMPd-11">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="XJBxcrHkF3XFgZlLdMPd-10" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="end_name" type="End" ports_exec_in="[&quot;in&quot;]" ports_data_in="[]" id="XJBxcrHkF3XFgZlLdMPd-13">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="635" y="260" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-14" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="XJBxcrHkF3XFgZlLdMPd-13" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-15" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-14" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="XJBxcrHkF3XFgZlLdMPd-16">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="XJBxcrHkF3XFgZlLdMPd-15" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-17" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-14" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="XJBxcrHkF3XFgZlLdMPd-11" target="XJBxcrHkF3XFgZlLdMPd-16" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%&#xa;matches: %n%" placeholders="1" name="match_name" type="Match" file="rules/places.od" n="4" id="tqCyT2AFxwHsmUbf2qyE-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=60;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="220" y="240" width="160" height="220" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="tqCyT2AFxwHsmUbf2qyE-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="tqCyT2AFxwHsmUbf2qyE-1" vertex="1">
+          <mxGeometry y="60" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="tqCyT2AFxwHsmUbf2qyE-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="tqCyT2AFxwHsmUbf2qyE-2" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="tqCyT2AFxwHsmUbf2qyE-4">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="tqCyT2AFxwHsmUbf2qyE-3" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="tqCyT2AFxwHsmUbf2qyE-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="tqCyT2AFxwHsmUbf2qyE-3" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="tqCyT2AFxwHsmUbf2qyE-6" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="tqCyT2AFxwHsmUbf2qyE-2" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="tqCyT2AFxwHsmUbf2qyE-7">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="tqCyT2AFxwHsmUbf2qyE-6" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="success" type="exec" id="tqCyT2AFxwHsmUbf2qyE-8">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="tqCyT2AFxwHsmUbf2qyE-6" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="fail" type="exec" id="tqCyT2AFxwHsmUbf2qyE-9">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="tqCyT2AFxwHsmUbf2qyE-6" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="tqCyT2AFxwHsmUbf2qyE-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="XJBxcrHkF3XFgZlLdMPd-5" target="tqCyT2AFxwHsmUbf2qyE-5" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="tqCyT2AFxwHsmUbf2qyE-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="tqCyT2AFxwHsmUbf2qyE-8" target="XJBxcrHkF3XFgZlLdMPd-9" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="tqCyT2AFxwHsmUbf2qyE-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="tqCyT2AFxwHsmUbf2qyE-7" target="tqCyT2AFxwHsmUbf2qyE-12" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram id="0adWAH9EoXTSZy_ri1wc" name="recursion">
+    <mxGraphModel dx="1042" dy="626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="start_name" type="Start" ports_exec_out="[&quot;out&quot;]" ports_data_out="[&quot;all_places&quot;, &quot;comb&quot;]" id="Kt-HEspv_mNIOeUF0m9y-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="10" y="260" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="Kt-HEspv_mNIOeUF0m9y-1" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="Kt-HEspv_mNIOeUF0m9y-2" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="Kt-HEspv_mNIOeUF0m9y-2" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="Kt-HEspv_mNIOeUF0m9y-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="Kt-HEspv_mNIOeUF0m9y-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="all_places" type="data" id="UXJI6ZzX8LQdl2j_TMXK-2">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="Kt-HEspv_mNIOeUF0m9y-4" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="comb" type="data" id="UXJI6ZzX8LQdl2j_TMXK-17">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="Kt-HEspv_mNIOeUF0m9y-4" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="end_name" type="End" ports_exec_in="[&quot;in&quot;]" ports_data_in="[]" id="Kt-HEspv_mNIOeUF0m9y-6">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="540" y="550" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-7" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="Kt-HEspv_mNIOeUF0m9y-6" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-8" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="Kt-HEspv_mNIOeUF0m9y-7" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="Kt-HEspv_mNIOeUF0m9y-9">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="Kt-HEspv_mNIOeUF0m9y-8" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-10" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="Kt-HEspv_mNIOeUF0m9y-7" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="schedule_name" type="Schedule" file="recursion" id="UQ9mEoFXoNfb_A1GJxno-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="960" y="260" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UQ9mEoFXoNfb_A1GJxno-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="UQ9mEoFXoNfb_A1GJxno-1" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="UQ9mEoFXoNfb_A1GJxno-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UQ9mEoFXoNfb_A1GJxno-2" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="UQ9mEoFXoNfb_A1GJxno-4">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UQ9mEoFXoNfb_A1GJxno-3" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="all_places" type="data" id="UXJI6ZzX8LQdl2j_TMXK-3">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="UQ9mEoFXoNfb_A1GJxno-3" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="comb" type="data" id="UXJI6ZzX8LQdl2j_TMXK-50">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="UQ9mEoFXoNfb_A1GJxno-3" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UQ9mEoFXoNfb_A1GJxno-5" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UQ9mEoFXoNfb_A1GJxno-2" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="UQ9mEoFXoNfb_A1GJxno-6">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UQ9mEoFXoNfb_A1GJxno-5" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="action_name" type="Action" ports_exec_in="[&quot;in&quot;]" ports_exec_out="[&quot;out&quot;, &quot;stop&quot;]" ports_data_in="[&quot;all_places&quot;, &quot;comb&quot;]" ports_data_out="[]" action="if len(data_in[&quot;all_places&quot;]) == len(data_in[&quot;comb&quot;]):&#xa;  var[&quot;output_gate&quot;] = &quot;stop&quot;" init="" id="v4SniQMLU1hr-XtfmYLd-9">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="200" y="260" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="v4SniQMLU1hr-XtfmYLd-10" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="v4SniQMLU1hr-XtfmYLd-9" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="v4SniQMLU1hr-XtfmYLd-11" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="v4SniQMLU1hr-XtfmYLd-10" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="v4SniQMLU1hr-XtfmYLd-12">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="v4SniQMLU1hr-XtfmYLd-11" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="all_places" type="data" id="UXJI6ZzX8LQdl2j_TMXK-4">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="v4SniQMLU1hr-XtfmYLd-11" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="comb" type="data" id="UXJI6ZzX8LQdl2j_TMXK-31">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="v4SniQMLU1hr-XtfmYLd-11" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="v4SniQMLU1hr-XtfmYLd-13" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="v4SniQMLU1hr-XtfmYLd-10" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="v4SniQMLU1hr-XtfmYLd-14">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="v4SniQMLU1hr-XtfmYLd-13" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="stop" type="exec" id="3555_PH_8KkFF3nkISFi-1">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="v4SniQMLU1hr-XtfmYLd-13" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="store_name" type="Store" ports="[&quot;input1&quot;, &quot;input2&quot;]" id="UXJI6ZzX8LQdl2j_TMXK-7">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="710" y="260" width="160" height="380" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-8" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-7" vertex="1">
+          <mxGeometry y="40" width="160" height="340" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-9" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-8" vertex="1">
+          <mxGeometry width="80" height="340" as="geometry">
+            <mxRectangle width="80" height="340" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-10">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-9" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="input1" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-11">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-9" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="input1" type="data" id="UXJI6ZzX8LQdl2j_TMXK-12">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="UXJI6ZzX8LQdl2j_TMXK-9" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="input2" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-42">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-9" vertex="1">
+            <mxGeometry x="10" y="160" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="input2" type="data" id="UXJI6ZzX8LQdl2j_TMXK-43">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="UXJI6ZzX8LQdl2j_TMXK-9" vertex="1">
+            <mxGeometry x="10" y="210" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-13" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-8" vertex="1">
+          <mxGeometry x="80" width="80" height="340" as="geometry">
+            <mxRectangle width="80" height="340" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="UXJI6ZzX8LQdl2j_TMXK-14">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="UXJI6ZzX8LQdl2j_TMXK-13" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-15">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-13" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="input1" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-16">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-13" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="input2" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-44">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-13" vertex="1">
+            <mxGeometry x="10" y="160" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-46" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="UXJI6ZzX8LQdl2j_TMXK-8" source="UXJI6ZzX8LQdl2j_TMXK-44" target="UXJI6ZzX8LQdl2j_TMXK-10" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="190" y="180" />
+              <mxPoint x="190" y="-60" />
+              <mxPoint x="-10" y="-60" />
+              <mxPoint x="-10" y="30" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="vNqiF5lz3jAjMHvjg_tr-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="UXJI6ZzX8LQdl2j_TMXK-8" source="UXJI6ZzX8LQdl2j_TMXK-16" target="UXJI6ZzX8LQdl2j_TMXK-42" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="170" y="80" />
+              <mxPoint x="170" y="110" />
+              <mxPoint x="40" y="110" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="loop_name" type="Loop" id="UXJI6ZzX8LQdl2j_TMXK-22">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="430" y="260" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-23" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-22" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-24" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-23" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="UXJI6ZzX8LQdl2j_TMXK-25">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="UXJI6ZzX8LQdl2j_TMXK-24" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-26">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-24" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-27" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-23" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="UXJI6ZzX8LQdl2j_TMXK-28">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="UXJI6ZzX8LQdl2j_TMXK-27" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="it" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-29">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-27" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-30">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-27" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-17" target="UXJI6ZzX8LQdl2j_TMXK-31" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-2" target="UXJI6ZzX8LQdl2j_TMXK-4" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="Kt-HEspv_mNIOeUF0m9y-5" target="v4SniQMLU1hr-XtfmYLd-12" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-2" target="UXJI6ZzX8LQdl2j_TMXK-25" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="190" y="380" />
+              <mxPoint x="190" y="490" />
+              <mxPoint x="400" y="490" />
+              <mxPoint x="400" y="430" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="v4SniQMLU1hr-XtfmYLd-14" target="UXJI6ZzX8LQdl2j_TMXK-26" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-41" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-29" target="UXJI6ZzX8LQdl2j_TMXK-11" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-47" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-17" target="UXJI6ZzX8LQdl2j_TMXK-43" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="180" y="430" />
+              <mxPoint x="180" y="530" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-48" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-15" target="UQ9mEoFXoNfb_A1GJxno-4" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-51" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-14" target="UXJI6ZzX8LQdl2j_TMXK-50" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-52" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UQ9mEoFXoNfb_A1GJxno-6" target="UXJI6ZzX8LQdl2j_TMXK-26" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="1130" y="330" />
+              <mxPoint x="1130" y="190" />
+              <mxPoint x="420" y="190" />
+              <mxPoint x="420" y="330" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-53" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-2" target="UXJI6ZzX8LQdl2j_TMXK-3" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="190" y="380" />
+              <mxPoint x="190" y="730" />
+              <mxPoint x="930" y="730" />
+              <mxPoint x="930" y="380" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="print_name" type="Print" event="False" custom="" id="UXJI6ZzX8LQdl2j_TMXK-54">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="370" y="550" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-55" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-54" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-56" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-55" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-57">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-56" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-58" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UXJI6ZzX8LQdl2j_TMXK-55" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="UXJI6ZzX8LQdl2j_TMXK-59">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UXJI6ZzX8LQdl2j_TMXK-58" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="data" id="UXJI6ZzX8LQdl2j_TMXK-60">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="UXJI6ZzX8LQdl2j_TMXK-58" vertex="1">
+            <mxGeometry x="-70" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-61" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-17" target="UXJI6ZzX8LQdl2j_TMXK-60" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="180" y="430" />
+              <mxPoint x="180" y="670" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-63" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="3555_PH_8KkFF3nkISFi-1" target="UXJI6ZzX8LQdl2j_TMXK-57" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="UXJI6ZzX8LQdl2j_TMXK-64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-59" target="Kt-HEspv_mNIOeUF0m9y-9" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="8zcSqG1YZsmCVL_NL7U9-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-30" target="Kt-HEspv_mNIOeUF0m9y-9" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="vNqiF5lz3jAjMHvjg_tr-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UXJI6ZzX8LQdl2j_TMXK-28" target="UXJI6ZzX8LQdl2j_TMXK-12" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>

+ 23 - 0
examples/petrinet/models/schedules/foo.od

@@ -0,0 +1,23 @@
+start:Start {
+    ports_exec = `["F","FF"]`;
+}
+end:End {
+    ports_exec = `["F"]`;
+}
+
+p1:Print{
+    custom = "Foo";
+}
+
+p2:Print{
+    custom = "FooFoo";
+}
+
+p3:Print{
+    custom = "FooFooFoo";
+}
+
+:Conn_exec (start -> p1) {from="F";to="in";}
+:Conn_exec (p1 -> end) {from="out";to="F";}
+:Conn_exec (start -> p2) {from="FF";to="in";}
+:Conn_exec (p2 -> end) {from="out";to="F";}

+ 66 - 0
examples/petrinet/models/schedules/petrinet.od

@@ -0,0 +1,66 @@
+start:Start
+end:End
+
+m:Match{
+    file = "operational_semantics/transition";
+}
+
+nac1:Match{
+    file = "operational_semantics/all_input_have_token";
+    n = "1";
+}
+
+inputs:Match{
+    file = "operational_semantics/all_inputs";
+}
+rinput:Rewrite{
+    file = "operational_semantics/all_inputs_reduced";
+}
+
+outputs:Match{
+    file = "operational_semantics/all_outputs";
+}
+routput:Rewrite{
+    file = "operational_semantics/all_outputs_increased";
+}
+
+p:Print{
+    event = True;
+}
+p2:Print{
+    event = False;
+    custom = `"succesfully execuded a petrinet transition"`;
+}
+
+l:Loop
+l2:Loop
+l3:Loop
+
+
+:Conn_exec (start -> m) {from="out"; to="in";}
+:Conn_exec (m -> l) {from="success"; to="in";}
+:Conn_exec (l -> nac1) {from="it"; to="in";}
+:Conn_exec (l -> end) {from="out"; to="in";}
+:Conn_exec (nac1 -> l) {from="success"; to="in";}
+:Conn_exec (nac1 -> inputs) {from="fail"; to="in";}
+:Conn_exec (inputs -> l2) {from="success"; to="in";}
+:Conn_exec (inputs -> l2) {from="fail"; to="in";}
+:Conn_exec (l2 -> rinput) {from="it"; to="in";}
+:Conn_exec (rinput -> l2) {from="out"; to="in";}
+:Conn_exec (l2 -> outputs) {from="out"; to="in";}
+:Conn_exec (outputs -> l3) {from="success"; to="in";}
+:Conn_exec (outputs -> l3) {from="fail"; to="in";}
+:Conn_exec (l3 -> routput) {from="it"; to="in";}
+:Conn_exec (routput -> l3) {from="out"; to="in";}
+:Conn_exec (l3 -> p2) {from="out"; to="in";}
+:Conn_exec (p2 -> end) {from="out"; to="in";}
+
+
+:Conn_data (m -> l) {from="out"; to="in";}
+:Conn_data (l -> nac1) {from="out"; to="in";}
+:Conn_data (l -> inputs) {from="out"; to="in";}
+:Conn_data (inputs -> l2) {from="out"; to="in";}
+:Conn_data (l2 -> rinput) {from="out"; to="in";}
+:Conn_data (l -> outputs) {from="out"; to="in";}
+:Conn_data (outputs -> l3) {from="out"; to="in";}
+:Conn_data (l3 -> routput) {from="out"; to="in";}

文件差异内容过多而无法显示
+ 1160 - 0
examples/petrinet/models/schedules/petrinet2.drawio


+ 915 - 0
examples/petrinet/models/schedules/petrinet3.drawio

@@ -0,0 +1,915 @@
+<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/27.0.5 Chrome/134.0.6998.205 Electron/35.3.0 Safari/537.36" version="27.0.5" pages="4">
+  <diagram name="main" id="7loCSpFFTrw_GtNaECtm">
+    <mxGraphModel dx="1042" dy="626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="start" type="Start" id="okR2fhRwQtHO20KEb0BA-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="100" y="240" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="okR2fhRwQtHO20KEb0BA-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="okR2fhRwQtHO20KEb0BA-1" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="okR2fhRwQtHO20KEb0BA-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="okR2fhRwQtHO20KEb0BA-2" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="okR2fhRwQtHO20KEb0BA-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="okR2fhRwQtHO20KEb0BA-2" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="okR2fhRwQtHO20KEb0BA-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="okR2fhRwQtHO20KEb0BA-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%&#xa;%file%&#xa;matches: %n%" placeholders="1" name="all transtions" type="Match" file="rules/transition.od" n="" id="okR2fhRwQtHO20KEb0BA-11">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=60;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="300" y="220" width="160" height="220" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="okR2fhRwQtHO20KEb0BA-12" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="okR2fhRwQtHO20KEb0BA-11" vertex="1">
+          <mxGeometry y="60" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="okR2fhRwQtHO20KEb0BA-13" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="okR2fhRwQtHO20KEb0BA-12" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="okR2fhRwQtHO20KEb0BA-14">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="okR2fhRwQtHO20KEb0BA-13" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="okR2fhRwQtHO20KEb0BA-15">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="okR2fhRwQtHO20KEb0BA-13" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="okR2fhRwQtHO20KEb0BA-16" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="okR2fhRwQtHO20KEb0BA-12" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="okR2fhRwQtHO20KEb0BA-17">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="okR2fhRwQtHO20KEb0BA-16" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="success" type="exec" id="okR2fhRwQtHO20KEb0BA-18">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="okR2fhRwQtHO20KEb0BA-16" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="fail" type="exec" id="okR2fhRwQtHO20KEb0BA-19">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="okR2fhRwQtHO20KEb0BA-16" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="okR2fhRwQtHO20KEb0BA-20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="okR2fhRwQtHO20KEb0BA-5" target="okR2fhRwQtHO20KEb0BA-15" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="find first that can fire" type="Schedule" file="check_nac" id="AWz2q_jGxnOfZjJ20oEo-31">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="520" y="240" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="AWz2q_jGxnOfZjJ20oEo-32" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="AWz2q_jGxnOfZjJ20oEo-31" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="AWz2q_jGxnOfZjJ20oEo-33" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="AWz2q_jGxnOfZjJ20oEo-32" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="AWz2q_jGxnOfZjJ20oEo-34">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="AWz2q_jGxnOfZjJ20oEo-33" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="t" type="data" id="_ZUP5PYB2ZkPahpFH5fo-1">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="AWz2q_jGxnOfZjJ20oEo-33" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="AWz2q_jGxnOfZjJ20oEo-35" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="AWz2q_jGxnOfZjJ20oEo-32" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="AWz2q_jGxnOfZjJ20oEo-36">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="AWz2q_jGxnOfZjJ20oEo-35" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="t" type="data" id="_ZUP5PYB2ZkPahpFH5fo-3">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="AWz2q_jGxnOfZjJ20oEo-35" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="_ZUP5PYB2ZkPahpFH5fo-6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="okR2fhRwQtHO20KEb0BA-17" target="_ZUP5PYB2ZkPahpFH5fo-1" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="500" y="410" />
+              <mxPoint x="500" y="360" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="reduce incoming" type="Schedule" file="reduce_incoming" id="7FO2QKo1IHTQBZ6BJbAA-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="759.9300000000001" y="130" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="7FO2QKo1IHTQBZ6BJbAA-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="7FO2QKo1IHTQBZ6BJbAA-1" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="7FO2QKo1IHTQBZ6BJbAA-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="7FO2QKo1IHTQBZ6BJbAA-2" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="7FO2QKo1IHTQBZ6BJbAA-4">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="7FO2QKo1IHTQBZ6BJbAA-3" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="t" type="data" id="7FO2QKo1IHTQBZ6BJbAA-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="7FO2QKo1IHTQBZ6BJbAA-3" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="7FO2QKo1IHTQBZ6BJbAA-6" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="7FO2QKo1IHTQBZ6BJbAA-2" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="7FO2QKo1IHTQBZ6BJbAA-7">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="7FO2QKo1IHTQBZ6BJbAA-6" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="increase outgoing&#xa;" type="Schedule" file="increase_outgoing" id="7FO2QKo1IHTQBZ6BJbAA-10">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="759.9300000000001" y="360" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="7FO2QKo1IHTQBZ6BJbAA-11" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="7FO2QKo1IHTQBZ6BJbAA-10" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="7FO2QKo1IHTQBZ6BJbAA-12" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="7FO2QKo1IHTQBZ6BJbAA-11" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="7FO2QKo1IHTQBZ6BJbAA-13">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="7FO2QKo1IHTQBZ6BJbAA-12" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="t" type="data" id="7FO2QKo1IHTQBZ6BJbAA-14">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="7FO2QKo1IHTQBZ6BJbAA-12" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="7FO2QKo1IHTQBZ6BJbAA-15" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="7FO2QKo1IHTQBZ6BJbAA-11" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="7FO2QKo1IHTQBZ6BJbAA-16">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="7FO2QKo1IHTQBZ6BJbAA-15" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="qfxbZ8cPFIYkKl1hvR_z-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="7FO2QKo1IHTQBZ6BJbAA-7" target="7FO2QKo1IHTQBZ6BJbAA-13" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="939.9300000000001" y="200" />
+              <mxPoint x="939.9300000000001" y="315" />
+              <mxPoint x="739.9300000000001" y="315" />
+              <mxPoint x="739.9300000000001" y="430" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="end" type="End" ports_exec_in="[&quot;in&quot;]" ports_data_in="[]" id="qfxbZ8cPFIYkKl1hvR_z-8">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="759.9300000000001" y="550" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="qfxbZ8cPFIYkKl1hvR_z-9" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="qfxbZ8cPFIYkKl1hvR_z-8" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="qfxbZ8cPFIYkKl1hvR_z-10" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="qfxbZ8cPFIYkKl1hvR_z-9" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="qfxbZ8cPFIYkKl1hvR_z-11">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="qfxbZ8cPFIYkKl1hvR_z-10" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="qfxbZ8cPFIYkKl1hvR_z-12" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="qfxbZ8cPFIYkKl1hvR_z-9" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="16WNXanlPmjoLkNVfXpS-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="okR2fhRwQtHO20KEb0BA-18" target="AWz2q_jGxnOfZjJ20oEo-34">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="16WNXanlPmjoLkNVfXpS-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="7FO2QKo1IHTQBZ6BJbAA-16" target="qfxbZ8cPFIYkKl1hvR_z-11">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="939.9300000000001" y="430" />
+              <mxPoint x="939.9300000000001" y="530" />
+              <mxPoint x="739.9300000000001" y="530" />
+              <mxPoint x="739.9300000000001" y="620" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="16WNXanlPmjoLkNVfXpS-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;curved=0;jumpStyle=gap;jumpSize=10;" edge="1" parent="1" source="okR2fhRwQtHO20KEb0BA-19" target="qfxbZ8cPFIYkKl1hvR_z-11">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="480" y="360" />
+              <mxPoint x="480" y="620" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="HUEgSa0tznzWzqEGNiE2-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="_ZUP5PYB2ZkPahpFH5fo-3" target="7FO2QKo1IHTQBZ6BJbAA-5">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="HUEgSa0tznzWzqEGNiE2-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="_ZUP5PYB2ZkPahpFH5fo-3" target="7FO2QKo1IHTQBZ6BJbAA-14">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="HUEgSa0tznzWzqEGNiE2-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="AWz2q_jGxnOfZjJ20oEo-36" target="7FO2QKo1IHTQBZ6BJbAA-4">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="700" y="310" />
+              <mxPoint x="700" y="200" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram id="tn9M2oGm5-WwrC7q8hvp" name="check_nac">
+    <mxGraphModel dx="1158" dy="696" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="sub_start" type="Start" ports_data_out="[&quot;t&quot;, &quot;foo&quot;]" ports_exec_out="[&quot;out&quot;, &quot;foo&quot;]" id="45lnt7s__IUFePRUFwyU-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="40" y="240" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="45lnt7s__IUFePRUFwyU-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="45lnt7s__IUFePRUFwyU-1" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="45lnt7s__IUFePRUFwyU-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="45lnt7s__IUFePRUFwyU-2" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="45lnt7s__IUFePRUFwyU-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="45lnt7s__IUFePRUFwyU-2" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="45lnt7s__IUFePRUFwyU-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="45lnt7s__IUFePRUFwyU-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="t" type="data" id="45lnt7s__IUFePRUFwyU-39">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="45lnt7s__IUFePRUFwyU-4" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="sub_end" type="End" ports_data_in="[&quot;t&quot;]" ports_exec_in="[&quot;rrrreee&quot;, &quot;in&quot;]" id="45lnt7s__IUFePRUFwyU-6">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="640" y="290" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="45lnt7s__IUFePRUFwyU-7" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="45lnt7s__IUFePRUFwyU-6" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="45lnt7s__IUFePRUFwyU-8" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="45lnt7s__IUFePRUFwyU-7" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="45lnt7s__IUFePRUFwyU-9">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="45lnt7s__IUFePRUFwyU-8" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="t" type="data" id="2n85NC4Wvb6VNMCIjbAe-2">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="45lnt7s__IUFePRUFwyU-8" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="45lnt7s__IUFePRUFwyU-10" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="45lnt7s__IUFePRUFwyU-7" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="iterate transitions" type="Loop" id="L95llld_XDiE7aqnH3Eh-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="240" y="240" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="L95llld_XDiE7aqnH3Eh-1" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="L95llld_XDiE7aqnH3Eh-2" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="L95llld_XDiE7aqnH3Eh-4">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="L95llld_XDiE7aqnH3Eh-3" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="L95llld_XDiE7aqnH3Eh-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="L95llld_XDiE7aqnH3Eh-3" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-6" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="L95llld_XDiE7aqnH3Eh-2" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="L95llld_XDiE7aqnH3Eh-7">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="L95llld_XDiE7aqnH3Eh-6" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="it" type="exec" id="L95llld_XDiE7aqnH3Eh-8">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="L95llld_XDiE7aqnH3Eh-6" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="exec" id="L95llld_XDiE7aqnH3Eh-9">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="L95llld_XDiE7aqnH3Eh-6" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="45lnt7s__IUFePRUFwyU-5" target="L95llld_XDiE7aqnH3Eh-5" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="45lnt7s__IUFePRUFwyU-39" target="L95llld_XDiE7aqnH3Eh-4" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%&#xa;matches: %n%" placeholders="1" name="check nac" type="Match" file="rules/input_without_token.od" n="1" id="L95llld_XDiE7aqnH3Eh-12">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=60;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="440" y="220" width="160" height="220" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-13" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="L95llld_XDiE7aqnH3Eh-12" vertex="1">
+          <mxGeometry y="60" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-14" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="L95llld_XDiE7aqnH3Eh-13" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="L95llld_XDiE7aqnH3Eh-15">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="L95llld_XDiE7aqnH3Eh-14" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="L95llld_XDiE7aqnH3Eh-16">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="L95llld_XDiE7aqnH3Eh-14" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-17" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="L95llld_XDiE7aqnH3Eh-13" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="L95llld_XDiE7aqnH3Eh-18">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="L95llld_XDiE7aqnH3Eh-17" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="success" type="exec" id="L95llld_XDiE7aqnH3Eh-19">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="L95llld_XDiE7aqnH3Eh-17" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="fail" type="exec" id="L95llld_XDiE7aqnH3Eh-20">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="L95llld_XDiE7aqnH3Eh-17" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="L95llld_XDiE7aqnH3Eh-8" target="L95llld_XDiE7aqnH3Eh-16" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="L95llld_XDiE7aqnH3Eh-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="L95llld_XDiE7aqnH3Eh-7" target="L95llld_XDiE7aqnH3Eh-15" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="iKvoEYQEFeyBr_GkI9vg-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="L95llld_XDiE7aqnH3Eh-19" target="L95llld_XDiE7aqnH3Eh-5" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <mxPoint x="630" y="200" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="620" y="310" />
+              <mxPoint x="620" y="200" />
+              <mxPoint x="220" y="200" />
+              <mxPoint x="220" y="300" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="dMiStd5tzY-ImjgYRODK-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="L95llld_XDiE7aqnH3Eh-20" target="45lnt7s__IUFePRUFwyU-9">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="dMiStd5tzY-ImjgYRODK-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="L95llld_XDiE7aqnH3Eh-7" target="2n85NC4Wvb6VNMCIjbAe-2">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="420" y="410" />
+              <mxPoint x="420" y="470" />
+              <mxPoint x="620" y="470" />
+              <mxPoint x="620" y="410" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram id="EAsDi4mdSkZfbsRIt0-E" name="reduce_incoming">
+    <mxGraphModel dx="1892" dy="626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="sub_start" type="Start" ports_data_out="[&quot;t&quot;, &quot;foo&quot;]" ports_exec_out="[&quot;out&quot;, &quot;foo&quot;]" id="BUnm0WgavkPBicxchqk0-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="-200" y="240" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="BUnm0WgavkPBicxchqk0-1" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-2" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-2" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="BUnm0WgavkPBicxchqk0-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="t" type="data" id="BUnm0WgavkPBicxchqk0-6">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="BUnm0WgavkPBicxchqk0-4" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="sub_end" type="End" ports_data_in="[]" ports_exec_in="[&quot;rrrreee&quot;, &quot;in&quot;]" id="BUnm0WgavkPBicxchqk0-7">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="640" y="240" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-8" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="BUnm0WgavkPBicxchqk0-7" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-9" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-8" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="BUnm0WgavkPBicxchqk0-10">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-9" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-12" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-8" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="iterate places" type="Loop" id="BUnm0WgavkPBicxchqk0-13">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="200" y="240" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-14" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="BUnm0WgavkPBicxchqk0-13" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-15" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-14" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="BUnm0WgavkPBicxchqk0-16">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="BUnm0WgavkPBicxchqk0-15" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="BUnm0WgavkPBicxchqk0-17">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-15" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-18" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-14" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="BUnm0WgavkPBicxchqk0-19">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="BUnm0WgavkPBicxchqk0-18" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="it" type="exec" id="BUnm0WgavkPBicxchqk0-20">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-18" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="exec" id="BUnm0WgavkPBicxchqk0-21">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-18" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%&#xa;%file%&#xa;matches: %n%" placeholders="1" name="incoming places" type="Match" file="rules/all_incoming.od" n="1" id="BUnm0WgavkPBicxchqk0-52">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=60;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry y="220" width="160" height="220" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-53" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="BUnm0WgavkPBicxchqk0-52" vertex="1">
+          <mxGeometry y="60" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-54" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-53" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="BUnm0WgavkPBicxchqk0-55">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="BUnm0WgavkPBicxchqk0-54" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="BUnm0WgavkPBicxchqk0-56">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-54" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-57" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-53" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="BUnm0WgavkPBicxchqk0-58">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="BUnm0WgavkPBicxchqk0-57" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="success" type="exec" id="BUnm0WgavkPBicxchqk0-59">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-57" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="fail" type="exec" id="BUnm0WgavkPBicxchqk0-60">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-57" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-61" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BUnm0WgavkPBicxchqk0-5" target="BUnm0WgavkPBicxchqk0-56" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BUnm0WgavkPBicxchqk0-6" target="BUnm0WgavkPBicxchqk0-55" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-63" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BUnm0WgavkPBicxchqk0-60" target="BUnm0WgavkPBicxchqk0-17" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="180" y="360" />
+              <mxPoint x="180" y="310" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BUnm0WgavkPBicxchqk0-59" target="BUnm0WgavkPBicxchqk0-17" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-65" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BUnm0WgavkPBicxchqk0-58" target="BUnm0WgavkPBicxchqk0-16" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="reduce place" type="Rewrite" file="rules/reduce_incoming.od" id="BUnm0WgavkPBicxchqk0-66">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="420" y="240.0000000000001" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-67" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="BUnm0WgavkPBicxchqk0-66" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="BUnm0WgavkPBicxchqk0-68" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-67" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="BUnm0WgavkPBicxchqk0-69">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-68" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-70" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="BUnm0WgavkPBicxchqk0-67" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="BUnm0WgavkPBicxchqk0-71">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="BUnm0WgavkPBicxchqk0-70" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="data" id="BUnm0WgavkPBicxchqk0-72">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="BUnm0WgavkPBicxchqk0-70" vertex="1">
+            <mxGeometry x="-70" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="data" id="BUnm0WgavkPBicxchqk0-73">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="BUnm0WgavkPBicxchqk0-70" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="BUnm0WgavkPBicxchqk0-74" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BUnm0WgavkPBicxchqk0-19" target="BUnm0WgavkPBicxchqk0-72" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="400" y="410" />
+              <mxPoint x="400" y="360" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="sY74cFRy-IzXkK1T1M-7-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="BUnm0WgavkPBicxchqk0-21" target="BUnm0WgavkPBicxchqk0-10" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="380" y="360" />
+              <mxPoint x="380" y="430" />
+              <mxPoint x="620" y="430" />
+              <mxPoint x="620" y="310" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="sY74cFRy-IzXkK1T1M-7-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BUnm0WgavkPBicxchqk0-20" target="BUnm0WgavkPBicxchqk0-69" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="sY74cFRy-IzXkK1T1M-7-6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BUnm0WgavkPBicxchqk0-71" target="BUnm0WgavkPBicxchqk0-17" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="600" y="310" />
+              <mxPoint x="600" y="220" />
+              <mxPoint x="180" y="220" />
+              <mxPoint x="180" y="310" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram id="_IoT90r4-d_BBqiD0-W3" name="increase_outgoing">
+    <mxGraphModel dx="1892" dy="626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="sub_start" type="Start" ports_data_out="[&quot;t&quot;, &quot;foo&quot;]" ports_exec_out="[&quot;out&quot;, &quot;foo&quot;]" id="xKz7S_Fbuw8o9D4hMjwY-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="-200" y="240" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-1" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-2" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-2" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="t" type="data" id="xKz7S_Fbuw8o9D4hMjwY-6">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="xKz7S_Fbuw8o9D4hMjwY-4" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="sub_end" type="End" ports_data_in="[]" ports_exec_in="[&quot;rrrreee&quot;, &quot;in&quot;]" id="xKz7S_Fbuw8o9D4hMjwY-7">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="640" y="240" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-8" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-7" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-9" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-8" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-10">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-9" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-11" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-8" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="iterate places" type="Loop" id="xKz7S_Fbuw8o9D4hMjwY-12">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="200" y="240" width="160" height="200" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-13" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-12" vertex="1">
+          <mxGeometry y="40" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-14" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-13" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="xKz7S_Fbuw8o9D4hMjwY-15">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="xKz7S_Fbuw8o9D4hMjwY-14" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-16">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-14" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-17" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-13" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="xKz7S_Fbuw8o9D4hMjwY-18">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="xKz7S_Fbuw8o9D4hMjwY-17" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="it" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-19">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-17" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-20">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-17" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-19" target="xKz7S_Fbuw8o9D4hMjwY-40" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <mxPoint x="450" y="310" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%&#xa;matches: %n%" placeholders="1" name="outgoing places" type="Match" file="rules/all_outgoing.od" n="1" id="xKz7S_Fbuw8o9D4hMjwY-23">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=60;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry y="220" width="160" height="220" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-24" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-23" vertex="1">
+          <mxGeometry y="60" width="160" height="160" as="geometry" />
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-25" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-24" vertex="1">
+          <mxGeometry width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="data" id="xKz7S_Fbuw8o9D4hMjwY-26">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="xKz7S_Fbuw8o9D4hMjwY-25" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-27">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-25" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-28" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-24" vertex="1">
+          <mxGeometry x="80" width="80" height="160" as="geometry">
+            <mxRectangle width="80" height="160" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="data" id="xKz7S_Fbuw8o9D4hMjwY-29">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="xKz7S_Fbuw8o9D4hMjwY-28" vertex="1">
+            <mxGeometry x="10" y="110" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="success" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-30">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-28" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="fail" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-31">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-28" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-5" target="xKz7S_Fbuw8o9D4hMjwY-27" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-6" target="xKz7S_Fbuw8o9D4hMjwY-26" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-31" target="xKz7S_Fbuw8o9D4hMjwY-16" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="180" y="360" />
+              <mxPoint x="180" y="310" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-30" target="xKz7S_Fbuw8o9D4hMjwY-16" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-36" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-29" target="xKz7S_Fbuw8o9D4hMjwY-15" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="increase place" type="Rewrite" file="rules/increase_outgoing.od" id="xKz7S_Fbuw8o9D4hMjwY-37">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="420" y="240.0000000000001" width="160" height="150" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-38" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-37" vertex="1">
+          <mxGeometry y="40" width="160" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-39" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-38" vertex="1">
+          <mxGeometry width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-40">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-39" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-41" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="xKz7S_Fbuw8o9D4hMjwY-38" vertex="1">
+          <mxGeometry x="80" width="80" height="110" as="geometry">
+            <mxRectangle width="80" height="110" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="xKz7S_Fbuw8o9D4hMjwY-42">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="xKz7S_Fbuw8o9D4hMjwY-41" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="in" type="data" id="xKz7S_Fbuw8o9D4hMjwY-43">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="xKz7S_Fbuw8o9D4hMjwY-41" vertex="1">
+            <mxGeometry x="-70" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="out" type="data" id="xKz7S_Fbuw8o9D4hMjwY-44">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="xKz7S_Fbuw8o9D4hMjwY-41" vertex="1">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-45" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-18" target="xKz7S_Fbuw8o9D4hMjwY-43" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="400" y="410" />
+              <mxPoint x="400" y="360" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="xKz7S_Fbuw8o9D4hMjwY-46" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;jumpStyle=gap;jumpSize=10;" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-20" target="xKz7S_Fbuw8o9D4hMjwY-10" edge="1">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="380" y="360" />
+              <mxPoint x="380" y="430" />
+              <mxPoint x="620" y="430" />
+              <mxPoint x="620" y="310" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="f9_bY4aOCWeb4ynzbNl7-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="xKz7S_Fbuw8o9D4hMjwY-42" target="xKz7S_Fbuw8o9D4hMjwY-16">
+          <mxGeometry relative="1" as="geometry">
+            <Array as="points">
+              <mxPoint x="600" y="310" />
+              <mxPoint x="600" y="220" />
+              <mxPoint x="180" y="220" />
+              <mxPoint x="180" y="310" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>

+ 217 - 0
examples/petrinet/models/schedules/recursion.drawio

@@ -0,0 +1,217 @@
+<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/27.0.5 Chrome/134.0.6998.205 Electron/35.3.0 Safari/537.36" version="27.0.5" pages="2">
+  <diagram name="main" id="PAlQ5KCi60ZyLzQCaE8o">
+    <mxGraphModel dx="1042" dy="626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="start_name" type="Start" ports_exec_out="[&quot;out&quot;]" ports_data_out="[]" id="XJBxcrHkF3XFgZlLdMPd-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="90" y="260" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="XJBxcrHkF3XFgZlLdMPd-1" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-2" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-2" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="XJBxcrHkF3XFgZlLdMPd-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="XJBxcrHkF3XFgZlLdMPd-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="schedule_name" type="Schedule" file="recursion" id="XJBxcrHkF3XFgZlLdMPd-6">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="340" y="260" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-7" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="XJBxcrHkF3XFgZlLdMPd-6" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-8" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-7" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="XJBxcrHkF3XFgZlLdMPd-9">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="XJBxcrHkF3XFgZlLdMPd-8" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-10" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-7" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="XJBxcrHkF3XFgZlLdMPd-11">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="XJBxcrHkF3XFgZlLdMPd-10" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="XJBxcrHkF3XFgZlLdMPd-5" target="XJBxcrHkF3XFgZlLdMPd-9" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="end_name" type="End" ports_exec_in="[&quot;in&quot;]" ports_data_in="[]" id="XJBxcrHkF3XFgZlLdMPd-13">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="550" y="260" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-14" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="XJBxcrHkF3XFgZlLdMPd-13" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-15" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-14" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="XJBxcrHkF3XFgZlLdMPd-16">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="XJBxcrHkF3XFgZlLdMPd-15" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-17" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="XJBxcrHkF3XFgZlLdMPd-14" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="XJBxcrHkF3XFgZlLdMPd-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="XJBxcrHkF3XFgZlLdMPd-11" target="XJBxcrHkF3XFgZlLdMPd-16" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+  <diagram id="0adWAH9EoXTSZy_ri1wc" name="recursion">
+    <mxGraphModel dx="1042" dy="626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <object label="%name%: %type%" placeholders="1" name="start_name" type="Start" ports_exec_out="[&quot;out&quot;]" ports_data_out="[]" id="Kt-HEspv_mNIOeUF0m9y-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="50" y="260" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="Kt-HEspv_mNIOeUF0m9y-1" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="Kt-HEspv_mNIOeUF0m9y-2" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-4" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="Kt-HEspv_mNIOeUF0m9y-2" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="Kt-HEspv_mNIOeUF0m9y-5">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="Kt-HEspv_mNIOeUF0m9y-4" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="%name%: %type%" placeholders="1" name="end_name" type="End" ports_exec_in="[&quot;in&quot;]" ports_data_in="[]" id="Kt-HEspv_mNIOeUF0m9y-6">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="625" y="260" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-7" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="Kt-HEspv_mNIOeUF0m9y-6" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-8" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="Kt-HEspv_mNIOeUF0m9y-7" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="Kt-HEspv_mNIOeUF0m9y-9">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="Kt-HEspv_mNIOeUF0m9y-8" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="Kt-HEspv_mNIOeUF0m9y-10" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="Kt-HEspv_mNIOeUF0m9y-7" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="%name%: %type%&#xa;%file%" placeholders="1" name="schedule_name" type="Schedule" file="recursion" id="UQ9mEoFXoNfb_A1GJxno-1">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" parent="1" vertex="1">
+            <mxGeometry x="425" y="260" width="160" height="100" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UQ9mEoFXoNfb_A1GJxno-2" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" parent="UQ9mEoFXoNfb_A1GJxno-1" vertex="1">
+          <mxGeometry y="40" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="UQ9mEoFXoNfb_A1GJxno-3" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UQ9mEoFXoNfb_A1GJxno-2" vertex="1">
+          <mxGeometry width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="UQ9mEoFXoNfb_A1GJxno-4">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UQ9mEoFXoNfb_A1GJxno-3" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UQ9mEoFXoNfb_A1GJxno-5" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" parent="UQ9mEoFXoNfb_A1GJxno-2" vertex="1">
+          <mxGeometry x="80" width="80" height="60" as="geometry">
+            <mxRectangle width="80" height="60" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="UQ9mEoFXoNfb_A1GJxno-6">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="UQ9mEoFXoNfb_A1GJxno-5" vertex="1">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="UQ9mEoFXoNfb_A1GJxno-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="UQ9mEoFXoNfb_A1GJxno-6" target="Kt-HEspv_mNIOeUF0m9y-9" edge="1">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <object label="%name%: %type%" placeholders="1" name="action_name" type="Action" ports_exec_in="[&quot;in&quot;]" ports_exec_out="[&quot;out&quot;, &quot;stop&quot;]" ports_data_in="[]" ports_data_out="[]" action="print(f&quot;hello world {globals[&quot;n&quot;]}&quot;)&#xa;globals[&quot;n&quot;] += 1&#xa;if globals[&quot;n&quot;] &gt; 50:&#xa;  var[&quot;output_gate&quot;] = &quot;stop&quot;" init="globals[&quot;n&quot;] = 0" id="v4SniQMLU1hr-XtfmYLd-9">
+          <mxCell style="shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;" vertex="1" parent="1">
+            <mxGeometry x="230" y="120" width="160" height="170" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="v4SniQMLU1hr-XtfmYLd-10" value="" style="shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;" vertex="1" parent="v4SniQMLU1hr-XtfmYLd-9">
+          <mxGeometry y="40" width="160" height="130" as="geometry" />
+        </mxCell>
+        <mxCell id="v4SniQMLU1hr-XtfmYLd-11" value="Input" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" vertex="1" parent="v4SniQMLU1hr-XtfmYLd-10">
+          <mxGeometry width="80" height="130" as="geometry">
+            <mxRectangle width="80" height="130" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="in" type="exec" id="v4SniQMLU1hr-XtfmYLd-12">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="v4SniQMLU1hr-XtfmYLd-11">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="v4SniQMLU1hr-XtfmYLd-13" value="Output" style="swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;" vertex="1" parent="v4SniQMLU1hr-XtfmYLd-10">
+          <mxGeometry x="80" width="80" height="130" as="geometry">
+            <mxRectangle width="80" height="130" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <object label="out" type="exec" id="v4SniQMLU1hr-XtfmYLd-14">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="v4SniQMLU1hr-XtfmYLd-13">
+            <mxGeometry x="10" y="10" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <object label="stop" type="exec" id="3555_PH_8KkFF3nkISFi-1">
+          <mxCell style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="v4SniQMLU1hr-XtfmYLd-13">
+            <mxGeometry x="10" y="60" width="60" height="40" as="geometry" />
+          </mxCell>
+        </object>
+        <mxCell id="v4SniQMLU1hr-XtfmYLd-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Kt-HEspv_mNIOeUF0m9y-5" target="v4SniQMLU1hr-XtfmYLd-12">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="v4SniQMLU1hr-XtfmYLd-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="v4SniQMLU1hr-XtfmYLd-14" target="UQ9mEoFXoNfb_A1GJxno-4">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="3555_PH_8KkFF3nkISFi-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="3555_PH_8KkFF3nkISFi-1" target="Kt-HEspv_mNIOeUF0m9y-9">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>

+ 4 - 0
examples/petrinet/models/schedules/schedule.od

@@ -0,0 +1,4 @@
+start: Start
+end: End
+
+:Conn_exec (start -> end) {from="tfuy"; to="in";}

+ 13 - 0
examples/petrinet/operational_semantics/all_inputs_reduced.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `get_value(this) -1`;
+}
+:RAM_pn_of (ps -> p)
+
+# An incoming arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (t -> p)

+ 13 - 0
examples/petrinet/operational_semantics/all_outputs.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `True`;
+}
+:RAM_pn_of (ps -> p)
+
+# An outgoing arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (t -> p)

+ 13 - 0
examples/petrinet/operational_semantics/all_outputs_increased.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `get_value(this) + 1`;
+}
+:RAM_pn_of (ps -> p)
+
+# An outgoing arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (t -> p)

+ 13 - 0
examples/petrinet/operational_semantics/input_without_token.od

@@ -0,0 +1,13 @@
+# A place with no tokens:
+
+p:RAM_PNPlace
+ps:RAM_PNPlaceState {
+  RAM_numTokens = `get_value(this) == 0`;
+}
+:RAM_pn_of (ps -> p)
+
+# An incoming arc from that place to our transition:
+
+t:RAM_PNTransition
+
+:RAM_arc (p -> t)

+ 1 - 1
examples/petrinet/operational_semantics/transition.od

@@ -1 +1 @@
-tr:RAM_PNTransition
+t:RAM_PNTransition

+ 12 - 0
examples/petrinet/petrinet_renderer.j2

@@ -0,0 +1,12 @@
+digraph G {
+  rankdir=LR;
+  center=true;
+  margin=1;
+  nodesep=1;
+  subgraph places {
+    node [fontname=Arial,fontsize=10,shape=circle,fixedsize=true,label="", height=.35,width=.35];
+    {% for place in places %}
+      {{ place[0] }} [label="{{ place[1] }}_{{ place[2] }}"]
+    {% endfor %}
+  }
+}

+ 21 - 6
examples/petrinet/renderer.py

@@ -1,3 +1,7 @@
+import os
+
+from jinja2 import Environment, FileSystemLoader
+
 from api.od import ODAPI
 from concrete_syntax.graphviz.make_url import show_graphviz
 from concrete_syntax.graphviz.renderer import make_graphviz_id
@@ -16,13 +20,24 @@ def render_tokens(num_tokens: int):
     return str(num_tokens)
 
 def render_petri_net_to_dot(od: ODAPI) -> str:
+    env = Environment(
+        loader=FileSystemLoader(
+            os.path.dirname(__file__)
+        )
+    )
+    env.trim_blocks = True
+    env.lstrip_blocks = True
+    template_dot = env.get_template("petrinet_renderer.j2")
+    with open("test_pet.dot", "w", encoding="utf-8") as f_dot:
+        places = [(make_graphviz_id(place), place_name, render_tokens(od.get_slot_value(od.get_source(od.get_incoming(place, "pn_of")[0]), "numTokens"))) for place_name, place in od.get_all_instances("PNPlace")]
+        f_dot.write(template_dot.render({"places": places}))
     dot = ""
-    dot += "rankdir=LR;"
-    dot += "center=true;"
-    dot += "margin=1;"
-    dot += "nodesep=1;"
-    dot += "subgraph places {"
-    dot += "  node [fontname=Arial,fontsize=10,shape=circle,fixedsize=true,label=\"\", height=.35,width=.35];"
+    dot += "rankdir=LR;\n"
+    dot += "center=true;\n"
+    dot += "margin=1;\n"
+    dot += "nodesep=1;\n"
+    dot += "subgraph places {\n"
+    dot += "  node [fontname=Arial,fontsize=10,shape=circle,fixedsize=true,label=\"\", height=.35,width=.35];\n"
     for place_name, place in od.get_all_instances("PNPlace"):
         # place_name = od.get_name(place)
         try:

+ 15 - 37
examples/petrinet/runner.py

@@ -1,19 +1,12 @@
-from examples.schedule.RuleExecuter import RuleExecuter
-from state.devstate import DevState
-from api.od import ODAPI
+from icecream import ic
+
 from concrete_syntax.textual_od.renderer import render_od
-from concrete_syntax.textual_od.renderer_jinja2 import render_od_jinja2
-from bootstrap.scd import bootstrap_scd
+from transformation.schedule.Tests import Test_xmlparser
 from util import loader
-from transformation.rule import RuleMatcherRewriter, ActionGenerator
 from transformation.ramify import ramify
-from examples.semantics.operational import simulator
 from examples.petrinet.renderer import show_petri_net
 
-from examples.schedule.ScheduledActionGenerator import *
-from examples.schedule.RuleExecuter import *
-
-
+from transformation.schedule.rule_scheduler import *
 
 if __name__ == "__main__":
     import os
@@ -33,43 +26,28 @@ if __name__ == "__main__":
     mm_rt_cs        = mm_cs + read_file('metamodels/mm_runtime.od')
     # m_cs            =         read_file('models/m_example_simple.od')
     # m_rt_initial_cs = m_cs +  read_file('models/m_example_simple_rt_initial.od')
-    m_cs            =         read_file('models/m_example_mutex.od')
-    m_rt_initial_cs = m_cs +  read_file('models/m_example_mutex_rt_initial.od')
-    # m_cs            =         read_file('models/m_example_inharc.od')
-    # m_rt_initial_cs = m_cs +  read_file('models/m_example_inharc_rt_initial.od')
+    # m_cs            =         read_file('models/m_example_mutex.od')
+    # m_rt_initial_cs = m_cs +  read_file('models/m_example_mutex_rt_initial.od')
+    m_cs            =         read_file('models/m_example_simple.od')
+    m_rt_initial_cs = m_cs +  read_file('models/m_example_simple_rt_initial.od')
 
     # Parse them
     mm           = loader.parse_and_check(state, mm_cs,           scd_mmm, "Petri-Net Design meta-model")
     mm_rt        = loader.parse_and_check(state, mm_rt_cs,        scd_mmm, "Petri-Net Runtime meta-model")
     m            = loader.parse_and_check(state, m_cs,            mm,      "Example model")
     m_rt_initial = loader.parse_and_check(state, m_rt_initial_cs, mm_rt,   "Example model initial state")
-
     mm_rt_ramified = ramify(state, mm_rt)
 
-    rules = loader.load_rules(state,
-        lambda rule_name, kind: f"{THIS_DIR}/operational_semantics/r_{rule_name}_{kind}.od",
-        mm_rt_ramified,
-        ["fire_transition"]) # only 1 rule :(
 
-    # matcher_rewriter = RuleMatcherRewriter(state, mm_rt, mm_rt_ramified)
-    # action_generator = ActionGenerator(matcher_rewriter, rules)
 
-    matcher_rewriter2 = RuleExecuter(state, mm_rt, mm_rt_ramified)
-    action_generator = ScheduleActionGenerator(matcher_rewriter2, f"models/schedule.od")
 
-    def render_callback(od):
-        show_petri_net(od)
-        # return render_od(state, od.m, od.mm)
-        return render_od_jinja2(state, od.m, od.mm)
+    scheduler = RuleScheduler(state, mm_rt, mm_rt_ramified, verbose=True, directory="models")
 
-    action_generator.generate_dot()
+    # if scheduler.load_schedule(f"petrinet.od"):
+    # if scheduler.load_schedule("schedules/combinatory.drawio"):
+    if scheduler.load_schedule("schedules/petrinet3.drawio"):
 
-    sim = simulator.MinimalSimulator(
-        action_generator=action_generator,
-        decision_maker=simulator.InteractiveDecisionMaker(auto_proceed=False),
-        # decision_maker=simulator.RandomDecisionMaker(seed=0),
-        termination_condition=action_generator.termination_condition,
-        # renderer=lambda od: render_od(state, od.m, od.mm),
-    )
 
-    sim.run(ODAPI(state, m_rt_initial, mm_rt))
+        scheduler.generate_dot("../dot.dot")
+        code, message = scheduler.run(ODAPI(state, m_rt_initial, mm_rt))
+        print(f"{code}: {message}")

+ 0 - 49
examples/schedule/RuleExecuter.py

@@ -1,49 +0,0 @@
-from concrete_syntax.textual_od.renderer import render_od
-
-import pprint
-from typing import Generator, Callable, Any
-from uuid import UUID
-import functools
-
-from api.od import ODAPI
-from concrete_syntax.common import indent
-from transformation.matcher import match_od
-from transformation.rewriter import rewrite
-from transformation.cloner import clone_od
-from util.timer import Timer
-from util.loader import parse_and_check
-
-class RuleExecuter:
-    def __init__(self, state, mm: UUID, mm_ramified: UUID, eval_context={}):
-        self.state = state
-        self.mm = mm
-        self.mm_ramified = mm_ramified
-        self.eval_context = eval_context
-
-    # Generates matches.
-    # Every match is a dictionary with entries LHS_element_name -> model_element_name
-    def match_rule(self, m: UUID, lhs: UUID, *, pivot:dict[Any, Any]):
-        lhs_matcher = match_od(self.state,
-                               host_m=m,
-                               host_mm=self.mm,
-                               pattern_m=lhs,
-                               pattern_mm=self.mm_ramified,
-                               eval_context=self.eval_context,
-                               pivot= pivot,
-                               )
-        return lhs_matcher
-
-    def rewrite_rule(self, m: UUID, rhs: UUID, *, pivot:dict[Any, Any]):
-        yield rewrite(self.state,
-                rhs_m=rhs,
-                pattern_mm=self.mm_ramified,
-                lhs_match=pivot,
-                host_m=m,
-                host_mm=self.mm,
-                eval_context=self.eval_context,
-            )
-
-
-    def load_match(self, file: str):
-        with open(file, "r") as f:
-            return parse_and_check(self.state, f.read(), self.mm_ramified, file)

+ 0 - 104
examples/schedule/ScheduledActionGenerator.py

@@ -1,104 +0,0 @@
-import importlib.util
-import io
-import os
-
-from jinja2 import FileSystemLoader, Environment
-
-from concrete_syntax.textual_od import parser as parser_od
-from concrete_syntax.textual_cd import parser as parser_cd
-from api.od import ODAPI
-from bootstrap.scd import bootstrap_scd
-from examples.schedule.generator import schedule_generator
-from examples.schedule.schedule_lib import End, NullNode
-from framework.conformance import Conformance, render_conformance_check_result
-from state.devstate import DevState
-
-
-class ScheduleActionGenerator:
-    def __init__(self, rule_executer, schedulefile:str):
-        self.rule_executer = rule_executer
-        self.rule_dict = {}
-        self.schedule: "Schedule"
-
-
-        self.state = DevState()
-        self.load_schedule(schedulefile)
-
-    def load_schedule(self, filename):
-        print("Loading schedule ...")
-        scd_mmm = bootstrap_scd(self.state)
-        with open("../schedule/models/scheduling_MM.od", "r") as f_MM:
-            mm_cs = f_MM.read()
-        with open(f"{filename}", "r") as f_M:
-            m_cs = f_M.read()
-        print("OK")
-
-        print("\nParsing models")
-
-        print(f"\tParsing meta model")
-        scheduling_mm = parser_cd.parse_cd(
-            self.state,
-            m_text=mm_cs,
-        )
-        print(f"\tParsing '{filename}_M.od' model")
-        scheduling_m = parser_od.parse_od(
-            self.state,
-            m_text=m_cs,
-            mm=scheduling_mm
-        )
-        print(f"OK")
-
-        print("\tmeta-meta-model a valid class diagram")
-        conf = Conformance(self.state, scd_mmm, scd_mmm)
-        print(render_conformance_check_result(conf.check_nominal()))
-        print(f"Is our '{filename}_M.od' model a valid '{filename}_MM.od' diagram?")
-        conf = Conformance(self.state, scheduling_m, scheduling_mm)
-        print(render_conformance_check_result(conf.check_nominal()))
-        print("OK")
-
-        od = ODAPI(self.state, scheduling_m, scheduling_mm)
-        g = schedule_generator(od)
-
-        output_buffer = io.StringIO()
-        g.generate_schedule(output_buffer)
-        open(f"schedule.py", "w").write(output_buffer.getvalue())
-        spec = importlib.util.spec_from_file_location("schedule", "schedule.py")
-        scedule_module = importlib.util.module_from_spec(spec)
-        spec.loader.exec_module(scedule_module)
-        self.schedule = scedule_module.Schedule(self.rule_executer)
-        self.load_matchers()
-
-    def load_matchers(self):
-        matchers = dict()
-        for file in self.schedule.get_matchers():
-            matchers[file] = self.rule_executer.load_match(file)
-        self.schedule.init_schedule(matchers)
-
-    def __call__(self, api: ODAPI):
-        exec_op = self.schedule(api)
-        yield from exec_op
-
-    def termination_condition(self, api: ODAPI):
-        if type(self.schedule.cur) == End:
-            return "jay"
-        if type(self.schedule.cur) == NullNode:
-            return "RRRR"
-        return None
-
-    def generate_dot(self):
-        env = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
-        env.trim_blocks = True
-        env.lstrip_blocks = True
-        template_dot = env.get_template('schedule_dot.j2')
-
-        nodes = []
-        edges = []
-        visit = set()
-        self.schedule.generate_dot(nodes, edges, visit)
-        print("Nodes:")
-        print(nodes)
-        print("\nEdges:")
-        print(edges)
-
-        with open("test.dot", "w") as f_dot:
-            f_dot.write(template_dot.render({"nodes": nodes, "edges": edges}))

+ 0 - 129
examples/schedule/generator.py

@@ -1,129 +0,0 @@
-import sys
-import os
-import json
-from uuid import UUID
-
-from jinja2.runtime import Macro
-
-from api.od import ODAPI
-from jinja2 import Environment, FileSystemLoader, meta
-
-
-class schedule_generator:
-    def __init__(self, odApi:ODAPI):
-        self.env = Environment(loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
-        self.env.trim_blocks = True
-        self.env.lstrip_blocks = True
-        self.template = self.env.get_template('schedule_template.j2')
-        self.template_wrap = self.env.get_template('schedule_template_wrap.j2')
-        self.api = odApi
-
-        def get_slot_value_default(item: UUID, slot:str, default):
-            if slot in self.api.get_slots(item):
-                return self.api.get_slot_value(item, slot)
-            return default
-
-        name_dict = lambda item: {"name": self.api.get_name(item)}
-        conn_dict = lambda item: {"name_from": self.api.get_name(self.api.get_source(item)),
-                                  "name_to": self.api.get_name(self.api.get_target(item)),
-                                  "gate_from": self.api.get_slot_value(item, "gate_from"),
-                                  "gate_to": self.api.get_slot_value(item, "gate_to"),
-                                  }
-
-        conn_data_event = {"Match": lambda item: False,
-                           "Rewrite": lambda item: False,
-                           "Data_modify": lambda item: True,
-                           "Loop": lambda item: True,
-                           "Print": lambda item: get_slot_value_default(item, "event", False)
-                           }
-        conn_data_dict = lambda item: {"name_from": self.api.get_name(self.api.get_source(item)),
-                                  "name_to": self.api.get_name(self.api.get_target(item)),
-                                  "event": conn_data_event[self.api.get_type_name(target := self.api.get_target(item))](target)
-                                  }
-        rewrite_dict = lambda item: {"name": self.api.get_name(item),
-                                  "file": self.api.get_slot_value(item, "file"),
-                                  }
-        match_dict = lambda item: {"name": self.api.get_name(item),
-                                  "file": self.api.get_slot_value(item, "file"),
-                                  "n": self.api.get_slot_value(item, "n") \
-                                        if "n" in self.api.get_slots(item) else 'float("inf")'
-                                  }
-        data_modify_dict = lambda item: {"name": self.api.get_name(item),
-                                  "dict": json.loads(self.api.get_slot_value(item, "modify_dict"))
-                                  }
-        loop_dict = lambda item: {"name": self.api.get_name(item),
-                                  "choise": get_slot_value_default(item, "choise", False)}
-        print_dict = lambda item: {"name": self.api.get_name(item),
-                                   "label": get_slot_value_default(item, "label", "")}
-        arg_map = {"Start": name_dict, "End": name_dict,
-                   "Match": match_dict, "Rewrite": rewrite_dict,
-                   "Data_modify": data_modify_dict, "Loop": loop_dict,
-                   "Exec_con": conn_dict, "Data_con": conn_data_dict,
-                   "Print": print_dict}
-        self.macro_args = {tp: (macro, arg_map.get(tp)) for tp, macro in self.template.module.__dict__.items()
-                                                if type(macro) == Macro}
-
-    def _render(self, item):
-        type_name = self.api.get_type_name(item)
-        macro, arg_gen = self.macro_args[type_name]
-        return macro(**arg_gen(item))
-
-    def generate_schedule(self, stream = sys.stdout):
-        start = self.api.get_all_instances("Start")[0][1]
-        stack = [start]
-        out = {"blocks":[], "exec_conn":[], "data_conn":[], "match_files":set(), "matchers":[], "start":self.api.get_name(start)}
-        execBlocks = set()
-        exec_conn = list()
-
-        while len(stack) > 0:
-            exec_obj = stack.pop()
-            if exec_obj in execBlocks:
-                continue
-            execBlocks.add(exec_obj)
-            for conn in self.api.get_outgoing(exec_obj, "Exec_con"):
-                exec_conn.append(conn)
-                stack.append(self.api.get_target(conn))
-
-        stack = list(execBlocks)
-        data_blocks = set()
-        for name, p in self.api.get_all_instances("Print"):
-            if "event" in (event := self.api.get_slots(p)) and event:
-                stack.append(p)
-                execBlocks.add(p)
-
-
-        data_conn = set()
-        while len(stack) > 0:
-            obj = stack.pop()
-            for data_c in self.api.get_incoming(obj, "Data_con"):
-                data_conn.add(data_c)
-                source = self.api.get_source(data_c)
-                if not self.api.is_instance(source, "Exec") and \
-                        source not in execBlocks and \
-                        source not in data_blocks:
-                    stack.append(source)
-                    data_blocks.add(source)
-
-        for exec_item in execBlocks:
-            out["blocks"].append(self._render(exec_item))
-            if self.api.is_instance(exec_item, "Rule"):
-                d = self.macro_args[self.api.get_type_name(exec_item)][1](exec_item)
-                out["match_files"].add(d["file"])
-                out["matchers"].append(d)
-        for exec_c in exec_conn:
-            out["exec_conn"].append(self._render(exec_c))
-
-        for data_c in data_conn:
-            out["data_conn"].append(self._render(data_c))
-
-        for data_b in data_blocks:
-            out["blocks"].append(self._render(data_b))
-
-        print(self.template_wrap.render(out), file=stream)
-
-
-
-
-
-        # print("with open('test.dot', 'w') as f:", file=stream)
-        # print(f"\tf.write({self.api.get_name(start)}.generate_dot())", file=stream)

+ 0 - 26
examples/schedule/models/README.md

@@ -1,26 +0,0 @@
-
-### association Exec_con
-    Integer gate_from;
-    Integer gate_to;
-
-### association Data_con
-
-### class Start [1..1]
-### class End [1..*]
-
-
-### class Match
-    optional Integer n;
-
-### class Rewrite
-
-### class Data_modify
-    String modify_dict;
-
-### class Loop
-    optional Boolean choise;
-
-## debugging tools
-
-### class Print(In_Exec, Out_Exec, In_Data)
-    optional Boolean event;

+ 0 - 46
examples/schedule/models/scheduling_MM.od

@@ -1,46 +0,0 @@
-abstract class Exec
-abstract class In_Exec(Exec)
-abstract class Out_Exec(Exec)
-
-association Exec_con  [0..*] Out_Exec -> In_Exec [0..*] {
-    Integer gate_from;
-    Integer gate_to;
-}
-
-abstract class Data
-abstract class In_Data(Data)
-abstract class Out_Data(Data)
-association Data_con  [0..*] Out_Data -> In_Data [0..*]
-
-class Start [1..1] (Out_Exec)
-class End [1..*] (In_Exec)
-
-
-abstract class Rule (In_Exec, Out_Exec, In_Data, Out_Data)
-{
-    String file;
-}
-class Match (Rule)
-{
-    optional Integer n;
-}
-
-class Rewrite (Rule)
-
-class Data_modify(In_Data, Out_Data)
-{
-    String modify_dict;
-}
-
-class Loop(In_Exec, Out_Exec, In_Data, Out_Data)
-{
-    optional Boolean choise;
-}
-
-# debugging tools
-
-class Print(In_Exec, Out_Exec, In_Data) 
-{
-    optional Boolean event;
-    optional String label;
-}

+ 0 - 12
examples/schedule/schedule_lib/__init__.py

@@ -1,12 +0,0 @@
-from .data_node import DataNode
-from .data_modify import DataModify
-from .end import End
-from .exec_node import ExecNode
-from .loop import Loop
-from .match import Match
-from .null_node import NullNode
-from .print import Print
-from .rewrite import Rewrite
-from .start import Start
-
-__all__ = ["DataNode", "End", "ExecNode", "Loop", "Match", "NullNode", "Rewrite", "Print", "DataModify", "Start"]

+ 0 - 63
examples/schedule/schedule_lib/data.py

@@ -1,63 +0,0 @@
-import functools
-from typing import Any, Generator, Callable
-
-
-class Data:
-    def __init__(self, super) -> None:
-        self.data: list[dict[Any, Any]] = list()
-        self.success: bool = False
-        self.super = super
-
-    @staticmethod
-    def store_output(func: Callable) -> Callable:
-        def wrapper(self, *args, **kwargs) -> Any:
-            output = func(self, *args, **kwargs)
-            self.success = output
-            return output
-        return wrapper
-
-    @store_output
-    def store_data(self, data_gen: Generator, n: int) -> bool:
-        self.data.clear()
-        if n == 0:
-            return True
-        i: int = 0
-        while (match := next(data_gen, None)) is not None:
-            self.data.append(match)
-            i+=1
-            if i >= n:
-                break
-        else:
-            if n == float("inf"):
-                return bool(len(self.data))
-            self.data.clear()
-            return False
-        return True
-
-    def get_super(self) -> int:
-        return self.super
-
-    def replace(self, data: "Data") -> None:
-        self.data.clear()
-        self.data.extend(data.data)
-
-    def append(self, data: Any) -> None:
-        self.data.append(data)
-
-    def clear(self) -> None:
-        self.data.clear()
-
-    def pop(self, index = -1) -> Any:
-        return self.data.pop(index)
-
-    def empty(self) -> bool:
-        return len(self.data) == 0
-
-    def __getitem__(self, index):
-        return self.data[index]
-
-    def __iter__(self):
-        return self.data.__iter__()
-
-    def __len__(self):
-        return self.data.__len__()

+ 0 - 26
examples/schedule/schedule_lib/data_modify.py

@@ -1,26 +0,0 @@
-import functools
-from typing import TYPE_CHECKING, Callable, List
-
-from api.od import ODAPI
-from examples.schedule.RuleExecuter import RuleExecuter
-from .exec_node import ExecNode
-from .data_node import DataNode
-
-
-class DataModify(DataNode):
-    def __init__(self, modify_dict: dict[str,str]) -> None:
-        DataNode.__init__(self)
-        self.modify_dict: dict[str,str] = modify_dict
-
-    def input_event(self, success: bool) -> None:
-        if success or self.data_out.success:
-            self.data_out.data.clear()
-            for data in self.data_in.data:
-                self.data_out.append({self.modify_dict[key]: value for key, value in data.items() if key in self.modify_dict.keys()})
-            DataNode.input_event(self, success)
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        if self.id in visited:
-            return
-        nodes.append(f"{self.id}[label=modify]")
-        super().generate_dot(nodes, edges, visited)

+ 0 - 47
examples/schedule/schedule_lib/data_node.py

@@ -1,47 +0,0 @@
-from typing import Any, Generator, List
-
-from examples.schedule.schedule_lib.id_generator import IdGenerator
-from .data import Data
-
-class DataNode:
-    def __init__(self) -> None:
-        if not hasattr(self, 'id'):
-            self.id = IdGenerator().generate_id()
-        self.data_out : Data = Data(self)
-        self.data_in: Data | None = None
-        self.eventsub: list[DataNode] = list()
-
-    def connect_data(self, data_node: "DataNode", eventsub=True) -> None:
-        data_node.data_in = self.data_out
-        if eventsub:
-            self.eventsub.append(data_node)
-
-    def store_data(self, data_gen: Generator, n: int) -> None:
-        success: bool = self.data_out.store_data(data_gen, n)
-        for sub in self.eventsub:
-            sub.input_event(success)
-
-    def get_input_data(self) -> list[dict[Any, Any]]:
-        if not self.data_in.success:
-            raise Exception("Invalid input data: matching has failed")
-        data = self.data_in.data
-        if len(data) == 0:
-            raise Exception("Invalid input data: no data present")
-        return data
-
-    def input_event(self, success: bool) -> None:
-        self.data_out.success = success
-        for sub in self.eventsub:
-            sub.input_event(success)
-
-    def get_id(self) -> int:
-        return self.id
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        visited.add(self.id)
-        if self.data_in is not None:
-            edges.append(f"{self.data_in.get_super().get_id()} -> {self.get_id()} [color = green]")
-            self.data_in.get_super().generate_dot(nodes, edges, visited)
-        for sub in self.eventsub:
-            sub.generate_dot(nodes, edges, visited)
-

+ 0 - 21
examples/schedule/schedule_lib/end.py

@@ -1,21 +0,0 @@
-import functools
-from typing import TYPE_CHECKING, List, Callable, Generator
-
-from api.od import ODAPI
-from .exec_node import ExecNode
-
-class End(ExecNode):
-    def __init__(self) -> None:
-        super().__init__(out_connections=1)
-
-    def execute(self, od: ODAPI) -> Generator | None:
-        return self.terminate(od)
-
-    @staticmethod
-    def terminate(od: ODAPI) -> Generator:
-        yield f"end:", functools.partial(lambda od:(od, ""), od)
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        if self.id in visited:
-            return
-        nodes.append(f"{self.id}[label=end]")

+ 0 - 34
examples/schedule/schedule_lib/exec_node.py

@@ -1,34 +0,0 @@
-from typing import TYPE_CHECKING, List, Callable, Generator
-from api.od import ODAPI
-
-from .id_generator import IdGenerator
-
-class ExecNode:
-    def __init__(self, out_connections: int = 1) -> None:
-        from .null_node import NullNode
-        self.next_state: list[ExecNode] = []
-        if out_connections > 0:
-            self.next_state = [NullNode()]*out_connections
-        self.id: int = IdGenerator().generate_id()
-
-    def nextState(self) -> "ExecNode":
-        return self.next_state[0]
-
-    def connect(self, next_state: "ExecNode", from_gate: int = 0, to_gate: int = 0) -> None:
-        if from_gate >= len(self.next_state):
-            raise IndexError
-        self.next_state[from_gate] = next_state
-
-    def execute(self, od: ODAPI) -> Generator | None:
-        return None
-
-    def get_id(self) -> int:
-        return self.id
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        visited.add(self.id)
-        for edge in self.next_state:
-            edges.append(f"{self.id} -> {edge.get_id()}")
-        for next in self.next_state:
-            next.generate_dot(nodes, edges, visited)
-

+ 0 - 10
examples/schedule/schedule_lib/funcs.py

@@ -1,10 +0,0 @@
-from typing import Callable
-
-def generate_dot_wrap(func) -> Callable:
-    def wrapper(self, *args, **kwargs) -> str:
-        nodes = []
-        edges = []
-        self.reset_visited()
-        func(self, nodes, edges, *args, **kwargs)
-        return f"digraph G {{\n\t{"\n\t".join(nodes)}\n\t{"\n\t".join(edges)}\n}}"
-    return wrapper

+ 0 - 8
examples/schedule/schedule_lib/id_generator.py

@@ -1,8 +0,0 @@
-from .singleton import Singleton
-
-class IdGenerator(metaclass=Singleton):
-    def __init__(self):
-        self.id = -1
-    def generate_id(self) -> int:
-        self.id += 1
-        return self.id

+ 0 - 57
examples/schedule/schedule_lib/loop.py

@@ -1,57 +0,0 @@
-import functools
-from random import choice
-from typing import TYPE_CHECKING, Callable, List, Generator
-
-from api.od import ODAPI
-from examples.schedule.RuleExecuter import RuleExecuter
-from .exec_node import ExecNode
-from .data_node import DataNode
-from .data_node import Data
-
-
-class Loop(ExecNode, DataNode):
-    def __init__(self, choice) -> None:
-        ExecNode.__init__(self, out_connections=2)
-        DataNode.__init__(self)
-        self.choice: bool = choice
-        self.cur_data: Data = Data(-1)
-
-    def nextState(self) -> ExecNode:
-        return self.next_state[not self.data_out.success]
-
-    def execute(self, od: ODAPI) -> Generator | None:
-        if self.cur_data.empty():
-            self.data_out.clear()
-            self.data_out.success = False
-            DataNode.input_event(self, False)
-            return None
-
-        if self.choice:
-            def select_data() -> Generator:
-                for i in range(len(self.cur_data)):
-                    yield f"choice: {self.cur_data[i]}", functools.partial(self.select_next,od, i)
-            return select_data()
-        else:
-            self.select_next(od, -1)
-        return None
-
-    def input_event(self, success: bool) -> None:
-        if (b := self.data_out.success) or success:
-            self.cur_data.replace(self.data_in)
-            self.data_out.clear()
-            self.data_out.success = False
-            if b:
-                DataNode.input_event(self, False)
-
-    def select_next(self,od: ODAPI, index: int) -> tuple[ODAPI, list[str]]:
-        self.data_out.clear()
-        self.data_out.append(self.cur_data.pop(index))
-        DataNode.input_event(self, True)
-        return (od, ["data selected"])
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        if self.id in visited:
-            return
-        nodes.append(f"{self.id}[label=Loop]")
-        ExecNode.generate_dot(self, nodes, edges, visited)
-        DataNode.generate_dot(self, nodes, edges, visited)

+ 0 - 42
examples/schedule/schedule_lib/match.py

@@ -1,42 +0,0 @@
-import functools
-from typing import TYPE_CHECKING, Callable, List, Generator
-
-from api.od import ODAPI
-from examples.schedule.RuleExecuter import RuleExecuter
-from .exec_node import ExecNode
-from .data_node import DataNode
-
-
-class Match(ExecNode, DataNode):
-    def __init__(self, label: str, n: int | float) -> None:
-        ExecNode.__init__(self, out_connections=2)
-        DataNode.__init__(self)
-        self.label: str = label
-        self.n:int = n
-        self.rule = None
-        self.rule_executer : RuleExecuter
-
-    def nextState(self) -> ExecNode:
-        return self.next_state[not self.data_out.success]
-
-    def execute(self, od: ODAPI) -> Generator | None:
-        self.match(od)
-        return None
-
-    def init_rule(self, rule, rule_executer):
-        self.rule = rule
-        self.rule_executer = rule_executer
-
-    def match(self, od: ODAPI) -> None:
-        pivot = {}
-        if self.data_in is not None:
-            pivot = self.get_input_data()[0]
-        print(f"matching: {self.label}\n\tpivot: {pivot}")
-        self.store_data(self.rule_executer.match_rule(od.m, self.rule, pivot=pivot), self.n)
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        if self.id in visited:
-            return
-        nodes.append(f"{self.id}[label=M_{self.label.split("/")[-1]}_{self.n}]")
-        ExecNode.generate_dot(self, nodes, edges, visited)
-        DataNode.generate_dot(self, nodes, edges, visited)

+ 0 - 25
examples/schedule/schedule_lib/null_node.py

@@ -1,25 +0,0 @@
-import functools
-from symtable import Function
-from typing import List, Callable, Generator
-
-from api.od import ODAPI
-from .singleton import Singleton
-
-from .exec_node import ExecNode
-
-class NullNode(ExecNode, metaclass=Singleton):
-    def __init__(self):
-        ExecNode.__init__(self, out_connections=0)
-
-    def execute(self, od: ODAPI) -> Generator | None:
-        raise Exception('Null node should already have terminated the schedule')
-
-    @staticmethod
-    def terminate(od: ODAPI):
-        return None
-        yield # verrrry important line, dont remove this unreachable code
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        if self.id in visited:
-            return
-        nodes.append(f"{self.id}[label=Null]")

+ 0 - 28
examples/schedule/schedule_lib/print.py

@@ -1,28 +0,0 @@
-import functools
-from typing import TYPE_CHECKING, Callable, List, Generator
-
-from api.od import ODAPI
-from examples.schedule.RuleExecuter import RuleExecuter
-from .exec_node import ExecNode
-from .data_node import DataNode
-
-
-class Print(ExecNode, DataNode):
-    def __init__(self, label: str = "") -> None:
-        ExecNode.__init__(self, out_connections=1)
-        DataNode.__init__(self)
-        self.label = label
-
-    def execute(self, od: ODAPI) -> Generator | None:
-        self.input_event(True)
-        return None
-
-    def input_event(self, success: bool) -> None:
-        print(f"{self.label}{self.data_in.data}")
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        if self.id in visited:
-            return
-        nodes.append(f"{self.id}[label=Print_{self.label.replace(":", "")}]")
-        ExecNode.generate_dot(self, nodes, edges, visited)
-        DataNode.generate_dot(self, nodes, edges, visited)

+ 0 - 38
examples/schedule/schedule_lib/rewrite.py

@@ -1,38 +0,0 @@
-import functools
-from typing import List, Callable, Generator
-
-from api.od import ODAPI
-from .exec_node import ExecNode
-from .data_node import DataNode
-from ..RuleExecuter import RuleExecuter
-
-
-class Rewrite(ExecNode, DataNode):
-    def __init__(self, label: str) -> None:
-        ExecNode.__init__(self, out_connections=1)
-        DataNode.__init__(self)
-        self.label = label
-        self.rule = None
-        self.rule_executer : RuleExecuter
-
-    def init_rule(self, rule, rule_executer):
-        self.rule = rule
-        self.rule_executer= rule_executer
-
-    def execute(self, od: ODAPI) -> Generator | None:
-        yield "ghello", functools.partial(self.rewrite, od)
-
-    def rewrite(self, od):
-        print("rewrite" + self.label)
-        pivot = {}
-        if self.data_in is not None:
-            pivot = self.get_input_data()[0]
-        self.store_data(self.rule_executer.rewrite_rule(od.m, self.rule, pivot=pivot), 1)
-        return ODAPI(od.state, od.m, od.mm),[f"rewrite {self.label}\n\tpivot: {pivot}\n\t{"success" if self.data_out.success else "failure"}\n"]
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        if self.id in visited:
-            return
-        nodes.append(f"{self.id}[label=R_{self.label.split("/")[-1]}]")
-        ExecNode.generate_dot(self, nodes, edges, visited)
-        DataNode.generate_dot(self, nodes, edges, visited)

+ 0 - 16
examples/schedule/schedule_lib/start.py

@@ -1,16 +0,0 @@
-from typing import TYPE_CHECKING, Callable, List, Any
-
-from .funcs import generate_dot_wrap
-
-from .exec_node import ExecNode
-
-
-class Start(ExecNode):
-    def __init__(self) -> None:
-        ExecNode.__init__(self, out_connections=1)
-
-    def generate_dot(self, nodes: List[str], edges: List[str], visited: set[int]) -> None:
-        if self.id in visited:
-            return
-        nodes.append(f"{self.id}[label=start]")
-        super().generate_dot(nodes, edges, visited)

+ 0 - 9
examples/schedule/templates/schedule_dot.j2

@@ -1,9 +0,0 @@
-digraph G {
-{% for node in nodes %}
-    {{ node }}
-{% endfor %}
-
-{% for edge in edges %}
-    {{ edge }}
-{% endfor %}
-}

+ 0 - 35
examples/schedule/templates/schedule_template.j2

@@ -1,35 +0,0 @@
-{% macro Start(name) %}
-{{ name }} = Start()
-{%- endmacro %}
-
-{% macro End(name) %}
-{{ name }} = End()
-{%- endmacro %}
-
-{% macro Match(name, file, n) %}
-{{ name }} = Match("{{ file }}", {{ n }})
-{%- endmacro %}
-
-{% macro Rewrite(name, file) %}
-{{ name }} = Rewrite("{{ file }}")
-{%- endmacro %}
-
-{% macro Data_modify(name, dict) %}
-{{ name }} = DataModify({{ dict }})
-{%- endmacro %}
-
-{% macro Exec_con(name_from, name_to, gate_from, gate_to) %}
-{{ name_from }}.connect({{ name_to }},{{ gate_from }},{{ gate_to }})
-{%- endmacro %}
-
-{% macro Data_con(name_from, name_to, event) %}
-{{ name_from }}.connect_data({{ name_to }}, {{ event }})
-{%- endmacro %}
-
-{% macro Loop(name, choise) %}
-{{ name }} = Loop({{ choise }})
-{%- endmacro %}
-
-{% macro Print(name, label) %}
-{{ name }} = Print("{{ label }}")
-{%- endmacro %}

+ 0 - 47
examples/schedule/templates/schedule_template_wrap.j2

@@ -1,47 +0,0 @@
-from examples.schedule.schedule_lib import *
-
-class Schedule:
-    def __init__(self, rule_executer):
-        self.start: Start
-        self.cur: ExecNode = None
-        self.rule_executer = rule_executer
-
-    def __call__(self, od):
-        self.cur = self.cur.nextState()
-        while not isinstance(self.cur, NullNode):
-            action_gen = self.cur.execute(od)
-            if action_gen is not None:
-            # if (action_gen := self.cur.execute(od)) is not None:
-                return action_gen
-            self.cur = self.cur.nextState()
-        return NullNode.terminate(od)
-
-    @staticmethod
-    def get_matchers():
-        return [
-            {% for file in match_files %}
-              "{{ file }}.od",
-            {% endfor %}
-        ]
-
-    def init_schedule(self, matchers):
-    {% for block in blocks%}
-        {{ block }}
-    {% endfor %}
-
-    {% for conn in exec_conn%}
-        {{ conn }}
-    {% endfor %}
-    {% for conn_d in data_conn%}
-        {{ conn_d }}
-    {% endfor %}
-        self.start = {{ start }}
-        self.cur = {{ start }}
-
-    {% for match in matchers %}
-        {{ match["name"] }}.init_rule(matchers["{{ match["file"] }}.od"], self.rule_executer)
-    {% endfor %}
-        return None
-
-    def generate_dot(self, *args, **kwargs):
-        return self.start.generate_dot(*args, **kwargs)

+ 0 - 142
examples/semantics/operational/port/assignment.py

@@ -1,142 +0,0 @@
-import functools
-from concrete_syntax.common import indent
-from examples.semantics.operational.port.helpers import design_to_state, state_to_design, get_time
-from examples.semantics.operational.simulator import make_actions_pure, filter_valid_actions
-
-
-def precondition_can_move_from(od, from_state):
-
-    # TO IMPLEMENT
-
-    # Function should return True if a ship can move out of 'from_state'
-
-    return False
-
-def precondition_can_move_to(od, to_state):
-
-    # TO IMPLEMENT
-
-    # Function should return True if a ship can move into 'to_state'
-
-    return False
-
-def precondition_all_successors_moved(od, conn):
-
-    # TO IMPLEMENT
-
-    # A move (or skip) can only be made along a connection after all subsequent connections have already made their move (or were skipped).
-
-    return True
-
-def precondition_workers_available(od, workerset):
-
-    # TO IMPLEMENT
-
-    # A worker in a WorkerSet can only be allocated to a berth, if the number of 'isOperating'-links is smaller than the number of workers in the WorkerSet.
-
-    return True
-
-def precondition_berth_unserved(od, berth):
-
-    # TO IMPLEMENT
-
-    # A worker can only be allocated to a berth, if the berth contains an 'unserved' ship.
-
-    return True
-
-def action_skip(od, conn_name):
-    # SERVES AS AN EXAMPLE - NO NEED TO EDIT THIS FUNCTION
-    conn = od.get(conn_name)
-    conn_state = design_to_state(od, conn)
-    od.set_slot_value(conn_state, "moved", True)
-    return [f"skip {conn_name}"]
-
-def action_move(od, conn_name):
-    action_skip(od, conn_name) # flag the connection as 'moved'
-
-    conn = od.get(conn_name)
-    from_place = od.get_source(conn)
-    to_place = od.get_target(conn)
-
-    from_state = design_to_state(od, from_place) # beware: Generator does not have State
-    to_state = design_to_state(od, to_place)
-
-    # TO IMPLEMENT:
-    #  - move a ship along the connection
-
-    return [f"unimplemented! nothing changed!"]
-
-def action_serve_berth(od, workerset_name, berth_name):
-
-    # TO IMPLEMENT:
-    #  - A worker starts operating a berth
-
-    return [f"unimplemented! nothing changed!"]
-
-def action_advance_time(od):
-    _, clock = od.get_all_instances("Clock")[0]
-    time = od.get_slot_value(clock, "time")
-    new_time = time + 1
-    od.set_slot_value(clock, "time", new_time)
-
-    # TO IMPLEMENT:
-    #  - all 'moved'-attributes need to be reset (to False)
-    #  - if there is a worker operating a Berth, then:
-    #      (1) the Berth's status becomes 'served'
-    #      (2) the worker is no longer operating the Berth
-
-    return [f"time is now {new_time}"]
-
-# This function is called to discover the possible steps that can be made.
-# It should not be necessary to edit this function
-def get_actions(od):
-    actions = {}
-
-    # Add move-actions (or skip-actions)
-    for conn_name, conn in od.get_all_instances("connection"):
-        already_moved = od.get_slot_value(design_to_state(od, conn), "moved")
-        if already_moved or not precondition_all_successors_moved(od, conn):
-            # a move was already made along this connection in the current time-step
-            continue
-
-        from_place = od.get_source(conn)
-        to_place = od.get_target(conn)
-        from_name = od.get_name(from_place)
-        to_name = od.get_name(to_place)
-        from_state = design_to_state(od, from_place)
-        to_state = design_to_state(od, to_place)
-
-        if (precondition_can_move_from(od, from_state)
-          and precondition_can_move_to(od, to_state)):
-            actions[f"move {conn_name} ({from_name} -> {to_name})"] = functools.partial(action_move, conn_name=conn_name)
-        else:
-            actions[f"skip {from_name} -> {to_name}"] = functools.partial(action_skip, conn_name=conn_name)
-
-    # Add actions to assign workers
-    for _, workerset in od.get_all_instances("WorkerSet"):
-        if not precondition_workers_available(od, workerset):
-            continue
-        for lnk in od.get_outgoing(workerset, "canOperate"):
-            berth = od.get_target(lnk)
-            if precondition_berth_unserved(od, berth):
-                berth_name = od.get_name(berth)
-                workerset_name = od.get_name(workerset)
-                actions[f"{workerset_name} operates {berth_name}"] = functools.partial(action_serve_berth, workerset_name=workerset_name, berth_name=berth_name)
-
-    # Only when no other action can be performed, can time advance
-    if len(actions) == 0:
-        actions["advance time"] = action_advance_time
-
-    # This wrapper turns our actions into pure functions: they will clone the model before modifying it. This is useful if we ever want to rollback an action.
-    return make_actions_pure(actions.items(), od)
-
-
-# Called every time the runtime state changes.
-# When this function returns a string, the simulation ends.
-# The string should represent the reason for ending the simulation.
-# When this function returns None, the simulation continues.
-def termination_condition(od):
-
-    # TO IMPLEMENT: terminate simulation when the place 'served' contains 2 ships.
-
-    pass

+ 0 - 18
examples/semantics/operational/port/helpers.py

@@ -1,18 +0,0 @@
-# Some helper functions
-
-def get_num_ships(od, place):
-    place_state = design_to_state(od, place)
-    return od.get_slot_value(place_state, "numShips")
-
-def design_to_state(od, design):
-    incoming = od.get_incoming(design, "of")
-    if len(incoming) == 1:
-        # not all design-objects have a state
-        return od.get_source(incoming[0])
-
-def state_to_design(od, state):
-    return od.get_target(od.get_outgoing(state, "of")[0])
-    
-def get_time(od):
-    _, clock = od.get_all_instances("Clock")[0]
-    return clock, od.get_slot_value(clock, "time")

+ 0 - 407
examples/semantics/operational/port/models.py

@@ -1,407 +0,0 @@
-# Design meta-model
-port_mm_cs = """
-    Source:Class {
-        abstract = True;
-    }
-    Sink:Class {
-        abstract = True;
-    }
-
-    Place:Class
-    :Inheritance (Place -> Source)
-    :Inheritance (Place -> Sink)
-
-    connection:Association (Source -> Sink)
-
-    CapacityConstraint:Class
-
-    CapacityConstraint_shipCapacity:AttributeLink (CapacityConstraint -> Integer) {
-        name = "shipCapacity";
-        optional = False;
-
-        # cannot have negative capacity:
-        constraint = `get_value(get_target(this)) >= 0`; # non-negative
-    }
-
-    # Capacity 
-    capacityOf:Association (CapacityConstraint -> Place) {
-        # must say something about at least one Place, otherwise what is the point of the constraint?
-        target_lower_cardinality = 1;
-    }
-
-    Berth:Class
-    :Inheritance (Berth -> Place)
-
-    # Set of workers
-    WorkerSet:Class
-
-    WorkerSet_numWorkers:AttributeLink (WorkerSet -> Integer) {
-        name = "numWorkers";
-        optional = False;
-        constraint = `get_value(get_target(this)) >= 0`; # non-negative
-    }
-    canOperate:Association (WorkerSet -> Berth) {
-        target_lower_cardinality = 1;
-    }
-
-    Generator:Class
-    :Inheritance (Generator -> Source)
-
-
-    # Those classes to which we want to attach a runtime state object
-    Stateful:Class {
-        abstract = True;
-    }
-    :Inheritance (Place      -> Stateful)
-    :Inheritance (WorkerSet  -> Stateful)
-    :Inheritance (Berth      -> Stateful)
-    :Inheritance (connection -> Stateful)
-""";
-
-# Runtime meta-model
-port_rt_mm_cs = port_mm_cs + """
-    State:Class
-    of:Association (State -> Stateful) {
-        source_lower_cardinality = 1;
-        source_upper_cardinality = 1;
-        target_lower_cardinality = 1;
-        target_upper_cardinality = 1;
-    }
-
-    PlaceState:Class
-    :Inheritance (PlaceState -> State)
-
-    PlaceState_numShips:AttributeLink (PlaceState -> Integer) {
-        # number of ships currently in the place
-        name = "numShips";
-        optional = False;
-        constraint = `get_value(get_target(this)) >= 0`; # non-negative
-    }
-
-    shipCapacities:GlobalConstraint {
-        constraint = ```
-            errors = []
-            for _, constr in get_all_instances("CapacityConstraint"):
-                cap = get_slot_value(constr, "shipCapacity")
-                total = 0
-                place_names = [] # for debugging
-                for lnk in get_outgoing(constr, "capacityOf"):
-                    place = get_target(lnk)
-                    place_names.append(get_name(place))
-                    place_state = get_source(get_incoming(place, "of")[0])
-                    total += get_slot_value(place_state, "numShips")
-                if total > cap:
-                    errors.append(f"The number of ships in places {','.join(place_names)} ({total}) exceeds the capacity ({cap}) of CapacityConstraint {get_name(constr)}.")
-            errors
-        ```;
-    }
-
-    BerthState:Class {
-        # status == empty <=> numShips == 0
-        constraint = ```
-            errors = []
-            numShips = get_slot_value(this, "numShips")
-            status = get_slot_value(this, "status")
-            if (numShips == 0) != (status == "empty"):
-                errors.append(f"Inconsistent: numShips = {numShips}, but status = {status}")
-            errors
-        ```;
-    }
-    :Inheritance (BerthState -> PlaceState)
-
-    BerthState_status:AttributeLink (BerthState -> String) {
-        name = "status";
-        optional = False;
-        constraint = `(
-            get_value(get_target(this)) in { "empty", "unserved", "served" }
-        )`;
-    }
-
-    WorkerSetState:Class
-    :Inheritance (WorkerSetState -> State)
-
-    isOperating:Association (WorkerSetState -> Berth) {
-        constraint = ```
-            errors = []
-
-            # get status of Berth
-            berth = get_target(this)
-            berth_state = get_source(get_incoming(berth, "of")[0])
-            status = get_slot_value(berth_state, "status")
-            if status != "unserved":
-                errors.append(f"Cannot operate {get_name(berth)} because there is no unserved ship there.")
-
-            # only operate Berts that we can operate
-            workerset = get_target(get_outgoing(get_source(this), "of")[0])
-            can_operate = [get_target(lnk) for lnk in get_outgoing(workerset, "canOperate")]
-            if berth not in can_operate:
-                errors.append(f"Cannot operate {get_name(berth)}.")
-
-            errors
-        ```;
-    }
-
-    operatingCapacities:GlobalConstraint {
-        constraint = ```
-            errors = []
-            for _, workersetstate in get_all_instances("WorkerSetState"):
-                workerset = get_target(get_outgoing(workersetstate, "of")[0])
-                num_operating = len(get_outgoing(workersetstate, "isOperating"))
-                num_workers = get_slot_value(workerset, "numWorkers")
-                if num_operating > num_workers:
-                    errors.append(f"WorkerSet {get_name(workerset)} is operating more berths ({num_operating}) than there are workers ({num_workers})")
-            errors
-        ```;
-    }
-
-    ConnectionState:Class
-    :Inheritance (ConnectionState -> State)
-    ConnectionState_moved:AttributeLink (ConnectionState -> Boolean) {
-        name = "moved";
-        optional = False;
-        constraint = ```
-            result = True
-            all_successors_moved = True
-            moved = get_value(get_target(this))
-            conn_state = get_source(this)
-            conn = get_target(get_outgoing(conn_state, "of")[0])
-            tgt_place = get_target(conn)
-            next_conns = get_outgoing(tgt_place, "connection")
-            for next_conn in next_conns:
-                next_conn_state = get_source(get_incoming(next_conn, "of")[0])
-                if not get_slot_value(next_conn_state, "moved"):
-                    all_successors_moved = False
-            if moved and not all_successors_moved:
-                result = f"Connection {get_name(conn)} played before its turn."
-            result
-        ```;
-    }
-
-    Clock:Class {
-        lower_cardinality = 1;
-        upper_cardinality = 1;
-    }
-    Clock_time:AttributeLink (Clock -> Integer) {
-        name = "time";
-        optional = False;
-        constraint = `get_value(get_target(this)) >= 0`;
-    }
-"""
-
-# Design model: the part that doesn't change
-port_m_cs = """
-    gen:Generator
-
-    # newly arrived ships collect here
-    waiting:Place
-    c1:connection (gen -> waiting)
-
-    inboundPassage:Place
-    c2:connection (waiting -> inboundPassage)
-
-    outboundPassage:Place
-
-    # inboundPassage and outboundPassage cannot have more than 3 ships total
-    passageCap:CapacityConstraint {
-        shipCapacity = 3;
-    }
-    :capacityOf (passageCap -> inboundPassage)
-    :capacityOf (passageCap -> outboundPassage)
-
-
-    # Berth 1
-
-    inboundBerth1:Place
-    berth1:Berth
-    outboundBerth1:Place
-
-    inboundBerth1Cap:CapacityConstraint { shipCapacity = 1; }
-    :capacityOf (inboundBerth1Cap -> inboundBerth1)
-    outboundBerth1Cap:CapacityConstraint { shipCapacity = 1; }
-    :capacityOf (outboundBerth1Cap -> outboundBerth1)
-
-    berth1Cap:CapacityConstraint { shipCapacity = 1; }
-    :capacityOf (berth1Cap -> berth1)
-
-    c3:connection (inboundBerth1 -> berth1)
-    c4:connection (berth1 -> outboundBerth1)
-
-    # Berth 2
-
-    inboundBerth2:Place
-    berth2:Berth
-    outboundBerth2:Place
-
-    inboundBerth2Cap:CapacityConstraint { shipCapacity = 1; }
-    :capacityOf (inboundBerth2Cap -> inboundBerth2)
-    outboundBerth2Cap:CapacityConstraint { shipCapacity = 1; }
-    :capacityOf (outboundBerth2Cap -> outboundBerth2)
-
-    berth2Cap:CapacityConstraint { shipCapacity = 1; }
-    :capacityOf (berth2Cap -> berth2)
-
-    c5:connection (inboundBerth2 -> berth2)
-    c6:connection (berth2 -> outboundBerth2)
-
-
-    # can either go to Berth 1 or Berth 2
-    c7:connection (inboundPassage -> inboundBerth1)
-    c8:connection (inboundPassage -> inboundBerth2)
-
-    c9:connection (outboundBerth1 -> outboundPassage)
-    c10:connection (outboundBerth2 -> outboundPassage)
-
-
-    # ships that have been served are counted here
-    served:Place
-    c11:connection (outboundPassage -> served)
-
-
-    workers:WorkerSet {
-        numWorkers = 1;
-    }
-    :canOperate (workers -> berth1)
-    :canOperate (workers -> berth2)
-"""
-
-# Initial runtime model: the part that changes (every execution step)
-port_rt_m_cs = port_m_cs + """
-    clock:Clock {
-        time = 0;
-    }
-
-    waitingState:PlaceState         { numShips = 2; }  :of (waitingState -> waiting)
-    inboundPassageState:PlaceState  { numShips = 0; }  :of (inboundPassageState -> inboundPassage)
-    outboundPassageState:PlaceState { numShips = 0; }  :of (outboundPassageState -> outboundPassage)
-
-    inboundBerth1State:PlaceState   { numShips = 0; }  :of (inboundBerth1State -> inboundBerth1)
-    outboundBerth1State:PlaceState  { numShips = 0; }  :of (outboundBerth1State -> outboundBerth1)
-    inboundBerth2State:PlaceState   { numShips = 0; }  :of (inboundBerth2State -> inboundBerth2)
-    outboundBerth2State:PlaceState  { numShips = 0; }  :of (outboundBerth2State -> outboundBerth2)
-
-    berth1State:BerthState { status = "empty"; numShips = 0; }  :of (berth1State -> berth1)
-    berth2State:BerthState { status = "empty"; numShips = 0; }  :of (berth2State -> berth2)
-
-    servedState:PlaceState { numShips = 1; }  :of (servedState -> served)
-
-    workersState:WorkerSetState  :of (workersState -> workers)
-
-    c1S:ConnectionState  { moved = False; }   :of (c1S -> c1)
-    c2S:ConnectionState  { moved = False; }   :of (c2S -> c2)
-    c3S:ConnectionState  { moved = False; }   :of (c3S -> c3)
-    c4S:ConnectionState  { moved = False; }   :of (c4S -> c4)
-    c5S:ConnectionState  { moved = False; }   :of (c5S -> c5)
-    c6S:ConnectionState  { moved = False; }   :of (c6S -> c6)
-    c7S:ConnectionState  { moved = False; }   :of (c7S -> c7)
-    c8S:ConnectionState  { moved = False; }   :of (c8S -> c8)
-    c9S:ConnectionState  { moved = False; }   :of (c9S -> c9)
-    c10S:ConnectionState { moved = False; }   :of (c10S -> c10)
-    c11S:ConnectionState { moved = False; }   :of (c11S -> c11)
-"""
-
-###################################################
-
-#                        ┌─────────────────┐            
-#                        │ shipCapacity=3  │            
-# ┌───┐     ┌───────┐    │┌──────────────┐ │  ┌───────┐ 
-# │gen├────►│waiting├────►│inboundPassage├───►│turning│ 
-# └───┘     └───────┘    │└──────────────┘ │  └───┬───┘ 
-#                        │                 │      │     
-#            ┌──────┐    │┌───────────────┐│      │     
-#            │served│◄────┼outboundPassage│◄──────┘     
-#            └──────┘    │└───────────────┘│            
-#                        └─────────────────┘            
-smaller_model_cs = """
-    gen:Generator
-    waiting:Place
-    inboundPassage:Place
-    turning:Place
-    outboundPassage:Place
-    served:Place
-
-    gen2wait:connection (gen -> waiting)
-    wait2inbound:connection (waiting -> inboundPassage)
-    inbound2turning:connection (inboundPassage -> turning)
-    turning2outbound:connection (turning -> outboundPassage)
-    outbound2served:connection (outboundPassage -> served)
-
-    # inboundPassage and outboundPassage cannot have more than 3 ships total
-    passageCap:CapacityConstraint {
-        shipCapacity = 3;
-    }
-    :capacityOf (passageCap -> inboundPassage)
-    :capacityOf (passageCap -> outboundPassage)
-"""
-
-smaller_model_rt_cs = smaller_model_cs + """
-    clock:Clock {
-        time = 0;
-    }
-
-    waitingState:PlaceState { numShips = 1; }  :of (waitingState -> waiting)
-    inboundPassageState:PlaceState { numShips = 1; }  :of (inboundPassageState -> inboundPassage)
-    turningState:PlaceState { numShips = 1; }  :of (turningState -> turning)
-    outboundPassageState:PlaceState { numShips = 1; }  :of (outboundPassageState -> outboundPassage)
-    servedState:PlaceState { numShips = 0; }  :of (servedState -> served)
-
-    gen2waitState:ConnectionState { moved = False; }  :of (gen2waitState -> gen2wait)
-    wait2inboundState:ConnectionState { moved = False; }  :of (wait2inboundState -> wait2inbound)
-    inbound2turningState:ConnectionState { moved = False; }  :of (inbound2turningState -> inbound2turning)
-    turning2outboundState:ConnectionState { moved = False; }  :of (turning2outboundState -> turning2outbound)
-    outbound2servedState:ConnectionState { moved = False; }  :of (outbound2servedState -> outbound2served)
-"""
-
-###################################################
-
-#                     ┌────────────┐           
-#                     │ workerset  │           
-#                     │            │           
-#                     │numWorkers=1│           
-#                     └──────┬─────┘           
-#                            │canOperate       
-#                            │                 
-#                        ┌───▼────┐            
-# ┌───┐     ┌───────┐    │┌─────┐ │    ┌──────┐
-# │gen├────►│waiting├────││berth├─┼───►│served│
-# └───┘     └───────┘    │└─────┘ │    └──────┘
-#                        │ship-   │            
-#                        │Capacity│            
-#                        │ =1     │            
-#                        └────────┘            
-smaller_model2_cs = """
-    gen:Generator
-    waiting:Place
-    berth:Berth
-    served:Place
-
-    gen2wait:connection (gen -> waiting)
-    wait2berth:connection (waiting -> berth)
-    berth2served:connection (berth -> served)
-
-    # berth can only hold 1 ship
-    passageCap:CapacityConstraint {
-        shipCapacity = 1;
-    }
-    :capacityOf (passageCap -> berth)
-
-    workers:WorkerSet {
-        numWorkers = 1;
-    }
-    :canOperate (workers -> berth)
-"""
-
-smaller_model2_rt_cs = smaller_model2_cs + """
-    clock:Clock {
-        time = 0;
-    }
-
-    waitingState:PlaceState { numShips = 1; }  :of (waitingState -> waiting)
-    berthState:BerthState { numShips = 1; status = "served"; }  :of (berthState -> berth)
-    servedState:PlaceState { numShips = 1; }  :of (servedState -> served)
-
-    gen2waitState:ConnectionState { moved = False; }  :of (gen2waitState -> gen2wait)
-    wait2berthState:ConnectionState { moved = False; }  :of (wait2berthState -> wait2berth)
-    berth2servedState:ConnectionState { moved = True; }  :of (berth2servedState -> berth2served)
-
-    workersState:WorkerSetState  :of (workersState -> workers)
-"""

+ 0 - 78
examples/semantics/operational/port/renderer.py

@@ -1,78 +0,0 @@
-from concrete_syntax.common import indent
-from concrete_syntax.graphviz.make_url import make_url
-from examples.semantics.operational.port.helpers import design_to_state, state_to_design, get_time, get_num_ships
-
-def render_port_to_dot(od,
-    make_id=lambda name,obj: name # by default, we just use the object name for the graphviz node name
-):
-    txt = ""
-
-    def render_place(place):
-        name = od.get_name(place)
-        return f'"{make_id(name,place)}" [ label = "{name}\\n ships = {get_num_ships(od, place)}", style = filled, fillcolor = lightblue ]\n'
-
-    for _, cap in od.get_all_instances("CapacityConstraint", include_subtypes=False):
-        name = od.get_name(cap)
-        capacity = od.get_slot_value(cap, "shipCapacity")
-        txt += f'subgraph cluster_{name} {{\n  label = "{name}\\n capacity = {capacity}";\n'
-        for lnk in od.get_outgoing(cap, "capacityOf"):
-            place = od.get_target(lnk)
-            txt += f'  {render_place(place)}'
-        txt += f'}}\n'
-
-    for _, place_state in od.get_all_instances("PlaceState", include_subtypes=False):
-        place = state_to_design(od, place_state)
-        if len(od.get_incoming(place, "capacityOf")) == 0:
-            txt += render_place(place)
-
-    for _, berth_state in od.get_all_instances("BerthState", include_subtypes=False):
-        berth = state_to_design(od, berth_state)
-        name = od.get_name(berth)
-        txt += f'"{make_id(name,berth)}" [ label = "{name}\\n numShips = {get_num_ships(od, berth)}\\n status = {od.get_slot_value(berth_state, "status")}", fillcolor = yellow, style = filled]\n'
-
-    for _, gen in od.get_all_instances("Generator", include_subtypes=False):
-        txt += f'"{make_id(od.get_name(gen),gen)}" [ label = "+", shape = diamond, fillcolor = green, fontsize = 30, style = filled ]\n'
-
-    for _, conn in od.get_all_instances("connection"):
-        src = od.get_source(conn)
-        tgt = od.get_target(conn)
-        moved = od.get_slot_value(design_to_state(od, conn), "moved")
-        src_name = od.get_name(src)
-        tgt_name = od.get_name(tgt)
-        txt += f"{make_id(src_name,src)} -> {make_id(tgt_name,tgt)} [color=deepskyblue3, penwidth={1 if moved else 2}];\n"
-
-    for _, workers in od.get_all_instances("WorkerSet"):
-        already_have = []
-        name = od.get_name(workers)
-        num_workers = od.get_slot_value(workers, "numWorkers")
-        txt += f'{make_id(name,workers)} [label="{num_workers} worker(s)", shape=parallelogram, fillcolor=chocolate, style=filled];\n'
-        for lnk in od.get_outgoing(design_to_state(od, workers), "isOperating"):
-            berth = od.get_target(lnk)
-            already_have.append(berth)
-            txt += f"{make_id(name,workers)} -> {make_id(od.get_name(berth),berth)} [arrowhead=none, color=chocolate];\n"
-        for lnk in od.get_outgoing(workers, "canOperate"):
-            berth = od.get_target(lnk)
-            if berth not in already_have:
-                txt += f"{make_id(name,workers)} -> {make_id(od.get_name(berth),berth)} [style=dotted, arrowhead=none, color=chocolate];\n"
-
-    return txt
-
-def render_port_graphviz(od):
-    return make_url(render_port_to_dot(od))
-
-def render_port_textual(od):
-    txt = ""
-    for _, place_state in od.get_all_instances("PlaceState", include_subtypes=False):
-        place = state_to_design(od, place_state)
-        name = od.get_name(place)
-        txt += f'place "{name}" {"🚢"*get_num_ships(od, place)}\n'
-
-    for _, berth_state in od.get_all_instances("BerthState", include_subtypes=False):
-        berth = state_to_design(od, berth_state)
-        name = od.get_name(berth)
-        operated_descr = ""
-        if len(od.get_incoming(berth, "isOperating")):
-            operated_descr = " and being operated"
-        txt += f'berth "{name}" {"🚢"*get_num_ships(od, berth)} {od.get_slot_value(berth_state, "status")}{operated_descr}\n'
-
-    return txt

+ 0 - 62
examples/semantics/operational/port/rulebased_runner.py

@@ -1,62 +0,0 @@
-import urllib.parse
-
-from state.devstate import DevState
-from bootstrap.scd import bootstrap_scd
-from framework.conformance import Conformance, render_conformance_check_result
-from concrete_syntax.textual_od import parser
-from concrete_syntax.plantuml.renderer import render_object_diagram, render_class_diagram
-from api.od import ODAPI
-
-from transformation.ramify import ramify
-
-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.semantics.operational.port import rulebased_sem
-
-state = DevState()
-scd_mmm = bootstrap_scd(state) # Load meta-meta-model
-
-### Load (meta-)models ###
-
-def parse_and_check(m_cs: str, mm, descr: str):
-    m = parser.parse_od(
-        state,
-        m_text=m_cs,
-        mm=mm)
-    conf = Conformance(state, m, mm)
-    print(descr, "...", render_conformance_check_result(conf.check_nominal()))
-    return m
-
-port_mm    = parse_and_check(models.port_mm_cs,    scd_mmm,    "MM")
-port_m     = parse_and_check(models.port_m_cs,     port_mm,    "M")
-port_rt_mm = parse_and_check(models.port_rt_mm_cs, scd_mmm,    "RT-MM")
-port_rt_m  = parse_and_check(models.port_rt_m_cs,  port_rt_mm, "RT-M")
-
-print()
-
-# print(render_class_diagram(state, port_rt_mm))
-
-### Simulate ###
-
-port_rt_mm_ramified = ramify(state, port_rt_mm)
-
-rulebased_action_generator = rulebased_sem.get_action_generator(state, port_rt_mm, port_rt_mm_ramified)
-termination_condition      = rulebased_sem.TerminationCondition(state, port_rt_mm_ramified)
-
-sim = Simulator(
-    action_generator=rulebased_action_generator,
-    # decision_maker=RandomDecisionMaker(seed=2),
-    decision_maker=InteractiveDecisionMaker(),
-    termination_condition=termination_condition,
-    check_conformance=True,
-    verbose=True,
-    # renderer=render_port_textual,
-    # renderer=render_port_graphviz,
-)
-
-od = ODAPI(state, port_rt_m, port_rt_mm)
-
-sim.run(od)

+ 0 - 67
examples/semantics/operational/port/rulebased_sem.py

@@ -1,67 +0,0 @@
-### Operational Semantics - defined by rule-based model transformation ###
-
-from concrete_syntax.textual_od.parser import parse_od
-from transformation.rule import Rule, RuleMatcherRewriter, PriorityActionGenerator
-from transformation.matcher import match_od
-from util import loader
-
-import os
-THIS_DIR = os.path.dirname(__file__)
-
-# kind: lhs, rhs, nac
-get_filename = lambda rule_name, kind: f"{THIS_DIR}/rules/r_{rule_name}_{kind}.od"
-
-
-def get_action_generator(state, rt_mm, rt_mm_ramified):
-    matcher_rewriter = RuleMatcherRewriter(state, rt_mm, rt_mm_ramified)
-
-    #############################################################################
-    # TO IMPLEMENT: Full semantics as a set of rule-based model transformations #
-
-    rules0_dict = loader.load_rules(state, get_filename, rt_mm_ramified,
-        ["ship_sinks"] # <- list of rule_name of equal priority
-    )
-    rules1_dict = loader.load_rules(state, get_filename, rt_mm_ramified,
-        ["ship_appears_in_berth"]
-    )
-    # rules2_dict = ...
-
-    generator = PriorityActionGenerator(matcher_rewriter, [
-        rules0_dict, # highest priority
-        rules1_dict, # lower priority
-        # rules2_dict, # lowest priority
-    ])
-
-    # TO IMPLEMENT: Full semantics as a set of rule-based model transformations #
-    #############################################################################
-
-    return generator
-
-
-
-
-# The termination condition can also be specified as a pattern:
-class TerminationCondition:
-    def __init__(self, state, rt_mm_ramified):
-        self.state = state
-        self.rt_mm_ramified = rt_mm_ramified
-
-        # TO IMPLEMENT: terminate simulation when the place 'served' contains 2 ships.
-
-        ########################################
-        # You should only edit the pattern below
-        pattern_cs = """
-            # Placeholder to make the termination condition never hold:
-            :GlobalCondition {
-                condition = `False`;
-            }
-        """
-        # You should only edit the pattern above
-        ########################################
-
-        self.pattern = parse_od(state, pattern_cs, rt_mm_ramified)
-
-    def __call__(self, od):
-        for match in match_od(self.state, od.m, od.mm, self.pattern, self.rt_mm_ramified):
-            # stop after the first match (no need to look for more matches):
-            return "There are 2 ships served." # Termination condition statisfied

+ 0 - 13
examples/semantics/operational/port/rules/README.txt

@@ -1,13 +0,0 @@
-The names of the files in this directory are important.
-
-A rule must always be named:
-  r_<rule_name>_<lhs|rhs|nac>.od
-
-It is allowed to have more than one NAC. In this case, the NACs must be named:
-  r_<rule_name>_nac.od
-  r_<rule_name>_nac2.od
-  r_<rule_name>_nac3.od
-  ...
-
-
-For the assignment, you can delete the existing rules (they are nonsense) and start fresh.

+ 0 - 4
examples/semantics/operational/port/rules/r_ship_appears_in_berth_lhs.od

@@ -1,4 +0,0 @@
-berthState:RAM_BerthState {
-  RAM_numShips = `get_value(this) == 0`;
-  RAM_status   = `get_value(this) == "empty"`;
-}

+ 0 - 4
examples/semantics/operational/port/rules/r_ship_appears_in_berth_rhs.od

@@ -1,4 +0,0 @@
-berthState:RAM_BerthState {
-  RAM_numShips = `1`;
-  RAM_status   = `"served"`;
-}

+ 0 - 5
examples/semantics/operational/port/rules/r_ship_sinks_lhs.od

@@ -1,5 +0,0 @@
-# Find any place that has at least one ship:
-
-placeState:RAM_PlaceState {
-  RAM_numShips = `get_value(this) > 0`;
-}

+ 0 - 4
examples/semantics/operational/port/rules/r_ship_sinks_rhs.od

@@ -1,4 +0,0 @@
-placeState:RAM_PlaceState {
-  # Decrement number of ships:
-  RAM_numShips = `get_value(this) - 1`;
-}

+ 0 - 56
examples/semantics/operational/port/runner.py

@@ -1,56 +0,0 @@
-import urllib.parse
-
-from state.devstate import DevState
-from bootstrap.scd import bootstrap_scd
-from framework.conformance import Conformance, render_conformance_check_result
-from concrete_syntax.textual_od import parser
-from concrete_syntax.plantuml.renderer import render_object_diagram, render_class_diagram
-from api.od import ODAPI
-
-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.semantics.operational.port.joeris_solution import termination_condition, get_actions
-from examples.semantics.operational.port.assignment import termination_condition, get_actions
-
-state = DevState()
-scd_mmm = bootstrap_scd(state) # Load meta-meta-model
-
-### Load (meta-)models ###
-
-def parse_and_check(m_cs: str, mm, descr: str):
-    m = parser.parse_od(
-        state,
-        m_text=m_cs,
-        mm=mm)
-    conf = Conformance(state, m, mm)
-    print(descr, "...", render_conformance_check_result(conf.check_nominal()))
-    return m
-
-port_mm    = parse_and_check(models.port_mm_cs,    scd_mmm,    "MM")
-port_m     = parse_and_check(models.port_m_cs,     port_mm,    "M")
-port_rt_mm = parse_and_check(models.port_rt_mm_cs, scd_mmm,    "RT-MM")
-port_rt_m  = parse_and_check(models.port_rt_m_cs,  port_rt_mm, "RT-M")
-
-print()
-
-# print(render_class_diagram(state, port_rt_mm))
-
-### Simulate ###
-
-sim = Simulator(
-    action_generator=get_actions,
-    # decision_maker=RandomDecisionMaker(seed=2),
-    decision_maker=InteractiveDecisionMaker(),
-    termination_condition=termination_condition,
-    check_conformance=True,
-    verbose=True,
-    renderer=render_port_textual,
-    # renderer=render_port_graphviz,
-)
-
-od = ODAPI(state, port_rt_m, port_rt_mm)
-
-sim.run(od)

+ 0 - 70
examples/semantics/operational/simulator.py

@@ -1,70 +0,0 @@
-import abc
-import random
-import math
-import functools
-import sys
-
-from framework.conformance import Conformance, render_conformance_check_result
-from concrete_syntax.common import indent
-from concrete_syntax.textual_od.renderer import render_od
-from transformation.cloner import clone_od
-from api.od import ODAPI
-
-from util.simulator import MinimalSimulator, DecisionMaker, RandomDecisionMaker, InteractiveDecisionMaker
-
-
-class Simulator(MinimalSimulator):
-    def __init__(self,
-        action_generator,
-        decision_maker: DecisionMaker,
-        termination_condition=lambda od: None,
-        check_conformance=True,
-        verbose=True,
-        renderer=lambda od: render_od(od.state, od.m, od.mm),
-    ):
-        super().__init__(
-            action_generator=action_generator,
-            decision_maker=decision_maker,
-            termination_condition=lambda od: self.check_render_termination_condition(od),
-            verbose=verbose,
-        )
-        self.check_conformance = check_conformance
-        self.actual_termination_condition = termination_condition
-        self.renderer = renderer
-
-    def check_render_termination_condition(self, od):
-        # A termination condition checker that also renders the model, and performs conformance check
-        self._print("--------------")
-        self._print(indent(self.renderer(od), 2))
-        self._print("--------------")
-        if self.check_conformance:
-            conf = Conformance(od.state, od.m, od.mm)
-            self._print(render_conformance_check_result(conf.check_nominal()))
-            self._print()
-        return self.actual_termination_condition(od)
-
-def make_actions_pure(actions, od):
-    # Copy model before modifying it
-    def exec_pure(action, od):
-        cloned_rt_m = clone_od(od.state, od.m, od.mm)
-        new_od = ODAPI(od.state, cloned_rt_m, od.mm)
-        msgs = action(new_od)
-        return (new_od, msgs)
-
-    for descr, action in actions:
-        yield (descr, functools.partial(exec_pure, action, od))
-
-def filter_valid_actions(pure_actions):
-    result = {}
-    def make_tuple(new_od, msgs):
-        return (new_od, msgs)
-    for name, callback in pure_actions:
-        # print(f"attempt '{name}' ...", end='\r')
-        (new_od, msgs) = callback()
-        conf = Conformance(new_od.state, new_od.m, new_od.mm)
-        errors = conf.check_nominal()
-        # erase current line:
-        # print("                                                                                ", end='\r')
-        if len(errors) == 0:
-            # updated RT-M is conform, we have a valid action:
-            yield (name, functools.partial(make_tuple, new_od, msgs))

+ 0 - 4
examples/semantics/translational/.gitignore

@@ -1,4 +0,0 @@
-# Let's not accidently add the solution to assignment 5...
-r_*.od
-
-snapshot_after_*.od

文件差异内容过多而无法显示
+ 0 - 197
examples/semantics/translational/merged_mm.od


+ 0 - 65
examples/semantics/translational/regenerate_mm.py

@@ -1,65 +0,0 @@
-from state.devstate import DevState
-from bootstrap.scd import bootstrap_scd
-from concrete_syntax.textual_od import renderer
-from concrete_syntax.plantuml.renderer import render_class_diagram
-from concrete_syntax.plantuml.make_url import make_url
-from api.od import ODAPI
-
-from transformation.topify.topify import Topifier
-from transformation.merger import merge_models
-
-from util import loader
-
-from examples.semantics.operational.port import models
-
-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 Petri Net meta-models
-    pn_mm_cs    =            read_file('../../petrinet/metamodels/mm_design.od')
-    pn_mm_rt_cs = pn_mm_cs + read_file('../../petrinet/metamodels/mm_runtime.od')
-    pn_mm    = loader.parse_and_check(state, pn_mm_cs,    scd_mmm, "Petri-Net Design meta-model")
-    pn_mm_rt = loader.parse_and_check(state, pn_mm_rt_cs, scd_mmm, "Petri-Net Runtime meta-model")
-
-    # Load Port meta-models
-    port_mm    = loader.parse_and_check(state, models.port_mm_cs,    scd_mmm,    "Port-MM")
-    port_mm_rt = loader.parse_and_check(state, models.port_rt_mm_cs, scd_mmm,    "Port-MM-RT")
-
-    # Merge Petri Net and Port meta-models
-    print("merging...")
-    merged_mm_rt = merge_models(state, mm=scd_mmm, models=[pn_mm_rt, port_mm_rt])
-    print("done merging")
-
-    print()
-    print("topifying... (may take a while)")
-    topifier = Topifier(state)
-    top_merged_mm_rt = topifier.topify_cd(merged_mm_rt)
-    print("done topifying")
-
-    plantuml_url = make_url(render_class_diagram(state, top_merged_mm_rt))
-
-    print()
-    print(plantuml_url)
-    print()
-
-    txt = renderer.render_od(state, top_merged_mm_rt, scd_mmm)
-
-    filename = THIS_DIR+"/merged_mm.od"
-
-    with open(filename, "w") as file:
-        file.write(f"# Auto-generated by {__file__}.\n\n")
-        file.write(f"# Merged run-time meta-models of 'Petri Net' and 'Port' formalisms.\n")
-        file.write(f"# An abstract 'Top'-class (superclass of everything else), and a 'generic_link'-association (which can connect everything with everything) have also been added.\n\n")
-        file.write(f"# PlantUML visualization: {plantuml_url}\n\n")
-        file.write(txt)
-
-    print("Wrote file", filename)

+ 0 - 90
examples/semantics/translational/renderer.py

@@ -1,90 +0,0 @@
-from api.od import ODAPI
-from concrete_syntax.graphviz.renderer import render_object_diagram, make_graphviz_id
-from concrete_syntax.graphviz.make_url import show_graphviz
-from examples.petrinet.renderer import render_petri_net_to_dot
-from examples.semantics.operational.port.renderer import render_port_to_dot
-from examples.semantics.operational.port import helpers
-
-# COLORS
-PLACE_BG = "#DAE8FC" # fill color
-PLACE_FG = "#6C8EBF" # font, line, arrow
-BERTH_BG = "#FFF2CC"
-BERTH_FG = "#D6B656"
-CAPACITY_BG = "#F5F5F5"
-CAPACITY_FG = "#666666"
-WORKER_BG = "#D5E8D4"
-WORKER_FG = "#82B366"
-GENERATOR_BG = "#FFE6CC"
-GENERATOR_FG = "#D79B00"
-CLOCK_BG = "black"
-CLOCK_FG = "white"
-
-def graphviz_style_fg_bg(fg, bg):
-    return f"style=filled,fillcolor=\"{bg}\",color=\"{fg}\",fontcolor=\"{fg}\""
-
-def render_port(state, m, mm):
-    dot = render_object_diagram(state, m, mm,
-        reify=True,
-        only_render=[
-            # Only render these types
-            "Place", "Berth", "CapacityConstraint", "WorkerSet", "Generator", "Clock",
-            "connection", "capacityOf", "canOperate", "generic_link",
-            # Petri Net types not included (they are already rendered by other function)
-            # Port-State-types not included to avoid cluttering the diagram, but if you need them, feel free to add them.
-        ],
-        # We can style nodes/edges according to their type:
-        type_to_style={
-            "Place": graphviz_style_fg_bg(PLACE_FG, PLACE_BG),
-            "Berth": graphviz_style_fg_bg(BERTH_FG, BERTH_BG),
-            "CapacityConstraint": graphviz_style_fg_bg(CAPACITY_FG, CAPACITY_BG),
-            "WorkerSet": "shape=oval,"+graphviz_style_fg_bg(WORKER_FG, WORKER_BG),
-            "Generator": "shape=parallelogram,"+graphviz_style_fg_bg(GENERATOR_FG, GENERATOR_BG),
-            "Clock": graphviz_style_fg_bg(CLOCK_FG, CLOCK_BG),
-
-            # same blue as Place, thick line:
-            "connection": f"color=\"{PLACE_FG}\",fontcolor=\"{PLACE_FG}\",penwidth=2.0",
-
-            # same grey as CapacityConstraint
-            "capacityOf": f"color=\"{CAPACITY_FG}\",fontcolor=\"{CAPACITY_FG}\"",
-
-            # same green as WorkerSet
-            "canOperate": f"color=\"{WORKER_FG}\",fontcolor=\"{WORKER_FG}\"",
-
-            # purple line
-            "generic_link": "color=purple,fontcolor=purple,arrowhead=onormal",
-        },
-        # We have control over the node/edge labels that are rendered:
-        type_to_label={
-            "CapacityConstraint": lambda capconstr_name, capconstr, odapi: f"{capconstr_name}\\nshipCapacity={odapi.get_slot_value(capconstr, "shipCapacity")}",
-
-            "Place": lambda place_name, place, odapi: f"{place_name}\\nnumShips={helpers.get_num_ships(odapi, place)}",
-
-            "Berth": lambda berth_name, berth, odapi: f"{berth_name}\\nnumShips={helpers.get_num_ships(odapi, berth)}\\nstatus={odapi.get_slot_value(helpers.design_to_state(odapi, berth), "status")}",
-
-            "Clock": lambda _, clock, odapi: f"Clock\\ntime={odapi.get_slot_value(clock, "time")}",
-
-            "connection": lambda conn_name, conn, odapi: f"{conn_name}\\nmoved={odapi.get_slot_value(helpers.design_to_state(odapi, conn), "moved")}",
-
-            # hide generic link labels
-            "generic_link": lambda lnk_name, lnk, odapi: "",
-
-            "WorkerSet": lambda ws_name, ws, odapi: f"{ws_name}\\nnumWorkers={odapi.get_slot_value(ws, "numWorkers")}",
-
-            # hide the type (it's already clear enough)
-            "Generator": lambda gen_name, gen, odapi: gen_name,
-        },
-    )
-    return dot
-
-def render_port_and_petri_net(state, m, mm):
-    od = ODAPI(state, m, mm)
-    dot = ""
-    dot += "// petri net:\n"
-    dot += render_petri_net_to_dot(od)
-    dot += "\n// the rest:\n"
-    dot += render_port(state, m, mm)
-    return dot
-
-
-def show_port_and_petri_net(state, m, mm, engine="dot"):
-    show_graphviz(render_port_and_petri_net(state, m, mm), engine=engine)

+ 0 - 5
examples/semantics/translational/rules/gen_pn/r_00_place2place_lhs.od

@@ -1,5 +0,0 @@
-# Look for a Place and its PlaceState:
-
-port_place:RAM_Place
-port_place_state:RAM_PlaceState
-port_of:RAM_of (port_place_state -> port_place)

+ 0 - 14
examples/semantics/translational/rules/gen_pn/r_00_place2place_nac.od

@@ -1,14 +0,0 @@
-# Our LHS:
-
-  port_place:RAM_Place
-  port_place_state:RAM_PlaceState
-  port_of:RAM_of (port_place_state -> port_place)
-
-
-# The elements from our RHS (this prevents the rule from firing forever):
-
-  pn_place:RAM_PNPlace
-  place2place:RAM_generic_link (pn_place -> port_place)
-
-  pn_place_state:RAM_PNPlaceState
-  :RAM_pn_of(pn_place_state -> pn_place)

+ 0 - 22
examples/semantics/translational/rules/gen_pn/r_00_place2place_rhs.od

@@ -1,22 +0,0 @@
-# Our entire LHS:
-
-  port_place:RAM_Place
-  port_place_state:RAM_PlaceState
-  port_of:RAM_of (port_place_state -> port_place)
-
-
-# To create: a Petri Net-place, and link it to our Port-place
-
-  pn_place:RAM_PNPlace {
-    # new feature: you can control the name of the object to be created:
-    name = `f"ships_{get_name(matched("port_place"))}"`;
-  }
-  place2place:RAM_generic_link (pn_place -> port_place)
-
-
-# And also create: a Petri Net-PlaceState (indicating the amount of tokens in our newly created place)
-
-  pn_place_state:RAM_PNPlaceState {
-    RAM_numTokens = `get_slot_value(matched('port_place_state'), "numShips")`;
-  }
-  :RAM_pn_of(pn_place_state -> pn_place)

+ 0 - 7
examples/semantics/translational/rules/gen_pn/r_10_conn2trans_lhs.od

@@ -1,7 +0,0 @@
-# Just look for a connection and its state:
-
-port_src:RAM_Source
-port_snk:RAM_Sink
-port_conn:RAM_connection (port_src -> port_snk)
-port_conn_state:RAM_ConnectionState
-port_of:RAM_of (port_conn_state -> port_conn)

+ 0 - 10
examples/semantics/translational/rules/gen_pn/r_10_conn2trans_nac.od

@@ -1,10 +0,0 @@
-# Our LHS:
-
-port_src:RAM_Source
-port_snk:RAM_Sink
-port_conn:RAM_connection (port_src -> port_snk)
-
-# There should not yet be a Petri Net transition linked to the connection:
-
-pn_transition:RAM_PNTransition
-:RAM_generic_link (pn_transition -> port_conn)

+ 0 - 28
examples/semantics/translational/rules/gen_pn/r_10_conn2trans_rhs.od

@@ -1,28 +0,0 @@
-# Our LHS:
-
-port_src:RAM_Source
-port_snk:RAM_Sink
-port_conn:RAM_connection (port_src -> port_snk)
-port_conn_state:RAM_ConnectionState
-port_of:RAM_of (port_conn_state -> port_conn)
-
-# Create a Petri Net transition, and link it to our port-connection:
-
-move_transition:RAM_PNTransition {
-  name = `f"move_{get_name(matched("port_conn"))}"`;
-}
-
-moved_place:RAM_PNPlace {
-  name = `f"  moved_{get_name(matched("port_conn"))}"`;
-}
-moved_place_state:RAM_PNPlaceState {
-  RAM_numTokens = `1 if get_slot_value(matched('port_conn_state'), "moved") else 0`;
-}
-:RAM_pn_of (moved_place_state -> moved_place)
-# when firing a 'move', put a token in the 'moved'-place
-:RAM_arc (move_transition -> moved_place)
-
-trans2conn:RAM_generic_link (move_transition -> port_conn)
-moved2conn:RAM_generic_link (moved_place -> port_conn)
-
-# Note that we are not yet creating any incoming/outgoing petri net arcs! This will be done in another rule.

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

@@ -1,82 +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 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 show_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)
-
-    def render(od):
-        show_petri_net(od) # graphviz in web browser
-        return renderer.render_od(state, od.m, od.mm) # text in terminal
-
-    sim = simulator.Simulator(
-        action_generator=action_generator,
-        decision_maker=simulator.InteractiveDecisionMaker(auto_proceed=False),
-        # decision_maker=simulator.RandomDecisionMaker(seed=0),
-        renderer=render,
-    )
-
-    sim.run(ODAPI(state, model, merged_mm))

+ 0 - 140
examples/semantics/translational/runner_translate.py

@@ -1,140 +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.rule import RuleMatcherRewriter
-
-from util import loader
-from util.module_to_dict import module_to_dict
-
-from examples.semantics.operational.port import models, helpers
-from examples.semantics.operational.port.renderer import render_port_textual, render_port_graphviz
-from examples.semantics.translational.renderer import show_port_and_petri_net
-from examples.petrinet.renderer import render_petri_net
-
-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)
-
-    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)
-
-    ###################################
-    # This is the main part you want to edit (by adding/changing the transformation rules)
-    #  |   |   |
-    #  V   V   V
-    rule_names = [
-        # high to low priority (the list-order here matters, the alphabetic-order of the names does not):
-        "00_place2place",
-        "10_conn2trans",
-
-        # The above two rules create a bunch of PN places and PN transitions.
-        # (with generic_links to the Port-elements)
-        # One way to continue, is to create PN arcs between the places and transitions.
-        # Or you can also just start from scratch, if you have a better idea :)
-    ]
-    # The script below will keep executing the first rule until it no longer matches, then the second rule, etc.
-    ###################################
-
-
-    print('loading rules...')
-    rules = loader.load_rules(state,
-        lambda rule_name, kind: f"{THIS_DIR}/rules/gen_pn/r_{rule_name}_{kind}.od",
-        ramified_merged_mm,
-        rule_names)
-
-    print('loading model...')
-    port_m_rt_initial = loader.parse_and_check(state,
-        # m_cs=models.port_rt_m_cs, # <-- your final solution should work with the full model
-        # m_cs=models.smaller_model_rt_cs, # <-- simpler model to try first
-        m_cs=models.smaller_model2_rt_cs, # <-- simpler model to try first
-        mm=merged_mm,
-        descr="initial model",
-        check_conformance=False, # no need to check conformance every time
-    )
-
-    print('ready!')
-
-    port_m_rt = port_m_rt_initial
-    eval_context = {
-        # make all the functions defined in 'helpers' module available to 'condition'-code in LHS/NAC/RHS:
-        **module_to_dict(helpers),
-        # another example: in all 'condition'-code, there will be a global variable 'meaning_of_life', equal to 42:
-        'meaning_of_life': 42, # just to demonstrate - feel free to remove this
-    }
-    print('The following additional globals are available:', ', '.join(list(eval_context.keys())))
-    matcher_rewriter = RuleMatcherRewriter(state, merged_mm, ramified_merged_mm, eval_context=eval_context)
-
-    ###################################
-    # Because the matching of many different rules can be slow,
-    # this script will store intermediate snapshots each time
-    # after having 'exhausted' a rule.
-    # When re-running the script, the stored snapshots will be loaded
-    # from disk instead of re-running the rules.
-    # You can force re-running the rules (e.g., because you changed the rules)
-    # by deleting the `snapshot_after_*` files.
-    ###################################
-
-    ###################################
-    # You are allowed to edit the script below, but you don't have to.
-    # Changes you may want to make:
-    #  - outcomment the 'render_petri_net'-call (preventing popups)
-    #  - if you really want to do something crazy,
-    #     you can even write a script that uses the lower-level `match_od`/`rewrite` primitives...
-    #  - ??
-    ###################################
-
-    for i, rule_name in enumerate(rule_names):
-        filename = f"{THIS_DIR}/snapshot_after_{rule_name}.od"
-        print("rule =", rule_name)
-        rule = rules[rule_name]
-        try:
-            with open(filename, "r") as file:
-                port_m_rt = parser.parse_od(state, file.read(), merged_mm)
-            print(f'skip rule (found {filename})')
-        except FileNotFoundError:
-            # Fire every rule until it cannot match any longer:
-            while True:
-                result = matcher_rewriter.exec_on_first_match(port_m_rt, rule, rule_name,
-                    in_place=True, # faster
-                )
-                if result == None:
-                    print("  no matches")
-                    break
-                else:
-                    port_m_rt, lhs_match, _ = result
-                    print("  rewrote", lhs_match)
-            txt = renderer.render_od(state, port_m_rt, merged_mm)
-            with open(filename, "w") as file:
-                file.write(txt)
-                print('wrote', filename)
-                render_petri_net(ODAPI(state, port_m_rt, merged_mm))
-
-                # Uncomment to show also the port model:
-                # show_port_and_petri_net(state, port_m_rt, merged_mm)
-
-                # Uncomment to pause after each rendering:
-                # input()
-
-    ###################################
-    # Once you have generated a Petri Net, you can execute the petri net:
-    #
-    #   python runner_exec_pn.py snapshot_after_XX_name_of_my_last_rule.od
-    ###################################

+ 0 - 58
examples/woods/common.py

@@ -1,58 +0,0 @@
-# Helpers
-def state_of(od, animal):
-    return od.get_source(od.get_incoming(animal, "of")[0])
-def animal_of(od, state):
-    return od.get_target(od.get_outgoing(state, "of")[0])
-def get_time(od):
-    _, clock = od.get_all_instances("Clock")[0]
-    return clock, od.get_slot_value(clock, "time")
-
-
-# Render our run-time state to a string
-def render_woods(od):
-    txt = ""
-    _, time = get_time(od)
-    txt += f"T = {time}.\n"
-    txt += "Bears:\n"
-    def render_attacking(animal_state):
-        attacking = od.get_outgoing(animal_state, "attacking")
-        if len(attacking) == 1:
-            whom_state = od.get_target(attacking[0])
-            whom_name = od.get_name(animal_of(od, whom_state))
-            return f" attacking {whom_name}"
-        else:
-            return ""
-    def render_dead(animal_state):
-        return 'dead' if od.get_slot_value(animal_state, 'dead') else 'alive'
-    for _, bear_state in od.get_all_instances("BearState"):
-        bear = animal_of(od, bear_state)
-        hunger = od.get_slot_value(bear_state, "hunger")
-        txt += f"  🐻 {od.get_name(bear)} (hunger: {hunger}, {render_dead(bear_state)}) {render_attacking(bear_state)}\n"
-    txt += "Men:\n"
-    for _, man_state in od.get_all_instances("ManState"):
-        man = animal_of(od, man_state)
-        attacked_by = od.get_incoming(man_state, "attacking")
-        if len(attacked_by) == 1:
-            whom_state = od.get_source(attacked_by[0])
-            whom_name = od.get_name(animal_of(od, whom_state))
-            being_attacked = f" being attacked by {whom_name}"
-        else:
-            being_attacked = ""
-        txt += f"  👨 {od.get_name(man)} ({render_dead(man_state)}) {render_attacking(man_state)}{being_attacked}\n"
-    return txt
-
-
-# When should simulation stop?
-def termination_condition(od):
-    _, time = get_time(od)
-    if time >= 10:
-        return "Took too long"
-
-    # End simulation when 2 animals are dead
-    who_is_dead = []
-    for _, animal_state in od.get_all_instances("AnimalState"):
-        if od.get_slot_value(animal_state, "dead"):
-            animal_name = od.get_name(animal_of(od, animal_state))
-            who_is_dead.append(animal_name)
-    if len(who_is_dead) >= 2:
-        return f"{' and '.join(who_is_dead)} are dead"

+ 0 - 158
examples/woods/models.py

@@ -1,158 +0,0 @@
-# Design meta-model
-woods_mm_cs = """
-    Animal:Class {
-        abstract = True;
-    }
-
-    Bear:Class
-    :Inheritance (Bear -> Animal)
-
-    Man:Class {
-        lower_cardinality = 1;
-        upper_cardinality = 2;
-        constraint = `get_value(get_slot(this, "weight")) > 20`;
-    }
-    :Inheritance (Man -> Animal)
-
-
-    Man_weight:AttributeLink (Man -> Integer) {
-        name = "weight";
-        optional = False;
-    }
-
-    afraidOf:Association (Man -> Animal) {
-        source_upper_cardinality = 6;
-        target_lower_cardinality = 1;
-    }
-"""
-# Runtime meta-model
-woods_rt_mm_cs = woods_mm_cs + """
-    AnimalState:Class {
-        abstract = True;
-    }
-    AnimalState_dead:AttributeLink (AnimalState -> Boolean) {
-        name = "dead";
-        optional = False;
-    }    
-    of:Association (AnimalState -> Animal) {
-        source_lower_cardinality = 1;
-        source_upper_cardinality = 1;
-        target_lower_cardinality = 1;
-        target_upper_cardinality = 1;
-    }
-
-    BearState:Class {
-        constraint = `get_type_name(get_target(get_outgoing(this, "of")[0])) == "Bear"`;
-    }
-    :Inheritance (BearState -> AnimalState)
-    BearState_hunger:AttributeLink (BearState -> Integer) {
-        name = "hunger";
-        optional = False;
-        constraint = ```
-            val = get_value(get_target(this))
-            val >= 0 and val <= 100
-        ```;
-    }
-
-    ManState:Class {
-        constraint = `get_type_name(get_target(get_outgoing(this, "of")[0])) == "Man"`;
-    }
-    :Inheritance (ManState -> AnimalState)
-
-    attacking:Association (AnimalState -> ManState) {
-        # Animal can only attack one Man at a time
-        target_upper_cardinality = 1;
-
-        # Man can only be attacked by one Animal at a time
-        source_upper_cardinality = 1;
-
-        constraint = ```
-            attacker = get_source(this)
-            if get_type_name(attacker) == "BearState":
-                # only BearState has 'hunger' attribute
-                hunger = get_value(get_slot(attacker, "hunger"))
-            else:
-                hunger = 100 # Man can always attack
-            attacker_dead = get_value(get_slot(attacker, "dead"))
-            attacked_state = get_target(this)
-            attacked_dead = get_value(get_slot(attacked_state, "dead"))
-            (
-                hunger >= 50 
-                and not attacker_dead # cannot attack while dead
-                and not attacked_dead # cannot attack whoever is dead
-            )
-        ```;
-    }
-
-    attacking_starttime:AttributeLink (attacking -> Integer) {
-        name = "starttime";
-        optional = False;
-        constraint = ```
-            val = get_value(get_target(this))
-            _, clock = get_all_instances("Clock")[0]
-            current_time = get_slot_value(clock, "time")
-            val >= 0 and val <= current_time
-        ```;
-    }
-
-    # Just a clock singleton for keeping the time
-    Clock:Class {
-        lower_cardinality = 1;
-        upper_cardinality = 1;
-    }
-    Clock_time:AttributeLink (Clock -> Integer) {
-        name = "time";
-        optional = False;
-        constraint = `get_value(get_target(this)) >= 0`;
-    }
-"""
-
-# Our design model - the part that doesn't change
-woods_m_cs = """
-    george:Man {
-        weight = 80;
-    }
-    bill:Man {
-        weight = 70;
-    }
-
-    teddy:Bear
-    mrBrown:Bear
-
-    # george is afraid of both bears
-    :afraidOf (george -> teddy)
-    :afraidOf (george -> mrBrown)
-
-    # the men are afraid of each other
-    :afraidOf (bill -> george)
-    :afraidOf (george -> bill)
-"""
-
-# Our runtime model - the part that changes with every execution step
-woods_rt_initial_m_cs = woods_m_cs + """
-    georgeState:ManState {
-        dead = False;
-    }
-    :of (georgeState -> george)
-
-    billState:ManState {
-        dead = False;
-    }
-    :of (billState -> bill)
-
-    teddyState:BearState {
-        dead = False;
-        hunger = 40;
-    }
-    :of (teddyState -> teddy)
-
-    mrBrownState:BearState {
-        dead = False;
-        hunger = 80;
-    }
-    :of (mrBrownState -> mrBrown)
-
-    clock:Clock {
-        time = 0;
-    }
-"""

+ 0 - 75
examples/woods/opsem_python.py

@@ -1,75 +0,0 @@
-### Operational Semantics - coded in Python ###
-
-import functools
-from examples.semantics.operational.simulator import make_actions_pure, filter_valid_actions
-from examples.woods.common import *
-
-# Action: Time advances, whoever is being attacked dies, bears become hungrier
-def action_advance_time(od):
-    msgs = []
-    clock, old_time = get_time(od)
-    new_time = old_time + 1
-    od.set_slot_value(clock, "time", new_time)
-
-    for _, attacking_link in od.get_all_instances("attacking"):
-        man_state = od.get_target(attacking_link)
-        animal_state = od.get_source(attacking_link)
-        if od.get_type_name(animal_state) == "BearState":
-            od.set_slot_value(animal_state, "hunger", max(od.get_slot_value(animal_state, "hunger") - 50, 0))
-        od.set_slot_value(man_state, "dead", True)
-        od.delete(attacking_link)
-        msgs.append(f"{od.get_name(animal_of(od, animal_state))} kills {od.get_name(animal_of(od, man_state))}.")
-
-    for _, bear_state in od.get_all_instances("BearState"):
-        if od.get_slot_value(bear_state, "dead"):
-            continue # bear already dead
-        old_hunger = od.get_slot_value(bear_state, "hunger")
-        new_hunger = min(old_hunger + 10, 100)
-        od.set_slot_value(bear_state, "hunger", new_hunger)
-        bear = od.get_target(od.get_outgoing(bear_state, "of")[0])
-        bear_name = od.get_name(bear)
-        if new_hunger == 100:
-            od.set_slot_value(bear_state, "dead", True)
-            msgs.append(f"Bear {bear_name} dies of hunger.")
-        else:
-            msgs.append(f"Bear {bear_name}'s hunger level is now {new_hunger}.")
-    return msgs
-
-# Action: Animal attacks Man
-# Note: We must use the names of the objects as parameters, because when cloning, the IDs of objects change!
-def action_attack(od, animal_name: str, man_name: str):
-    msgs = []
-    animal = od.get(animal_name)
-    man = od.get(man_name)
-    animal_state = state_of(od, animal)
-    man_state = state_of(od, man)
-    attack_link = od.create_link(None, # auto-generate link name
-        "attacking", animal_state, man_state)
-    _, clock = od.get_all_instances("Clock")[0]
-    current_time = od.get_slot_value(clock, "time")
-    od.set_slot_value(attack_link, "starttime", current_time)
-    msgs.append(f"{animal_name} is now attacking {man_name}")
-    return msgs
-
-# Get all actions that can be performed (including those that bring us to a non-conforming state)
-def get_all_actions(od):
-    def _generate_actions(od):
-        # can always advance time:
-        yield ("advance time", action_advance_time)
-
-        # if A is afraid of B, then B can attack A:
-        for _, afraid_link in od.get_all_instances("afraidOf"):
-            man = od.get_source(afraid_link)
-            animal = od.get_target(afraid_link)
-            animal_name = od.get_name(animal)
-            man_name = od.get_name(man)
-            man_state = state_of(od, man)
-            animal_state = state_of(od, animal)
-            descr = f"{animal_name} ({od.get_type_name(animal)}) attacks {man_name} ({od.get_type_name(man)})"
-            yield (descr, functools.partial(action_attack, animal_name=animal_name, man_name=man_name))
-
-    return make_actions_pure(_generate_actions(od), od)
-
-# Only get those actions that bring us to a conforming state
-def get_valid_actions(od):
-    return filter_valid_actions(get_all_actions(od))

+ 0 - 25
examples/woods/opsem_rulebased.py

@@ -1,25 +0,0 @@
-### Operational Semantics - defined by rule-based model transformation ###
-
-from transformation.rule import Rule, RuleMatcherRewriter, PriorityActionGenerator
-from transformation.ramify import ramify
-from util import loader
-
-import os
-THIS_DIR = os.path.dirname(__file__)
-
-get_filename = lambda rule_name, kind: f"{THIS_DIR}/rules/r_{rule_name}_{kind}.od"
-
-def get_action_generator(state, rt_mm):
-    rt_mm_ramified = ramify(state, rt_mm)
-
-    matcher_rewriter = RuleMatcherRewriter(state, rt_mm, rt_mm_ramified)
-
-    rules0_dict = loader.load_rules(state, get_filename, rt_mm_ramified, ["hungry_bear_dies"])
-    rules1_dict = loader.load_rules(state, get_filename, rt_mm_ramified, ["advance_time", "attack"]) 
-
-    generator = PriorityActionGenerator(matcher_rewriter, [
-        rules0_dict, # highest priority
-        rules1_dict, # lowest priority
-    ])
-
-    return generator

+ 0 - 0
examples/woods/rules/r_advance_time_lhs.od


部分文件因为文件数量过多而无法显示