6 Commits 3cd3b2177c ... ebc8df5a95

Autore SHA1 Messaggio Data
  Yentl Van Tendeloo ebc8df5a95 Remove unnecessary sleep to improve performance marginally 7 anni fa
  Yentl Van Tendeloo 47a45b8c57 Partially pre-compile instantiate_link 7 anni fa
  Yentl Van Tendeloo cb9beb4604 Add script to analyse profiling results 7 anni fa
  Yentl Van Tendeloo 3834f6e351 Add profiling functionality 7 anni fa
  Yentl Van Tendeloo e898f1b5b4 Fixes for Windows 7 anni fa
  Yentl Van Tendeloo 9840b07033 Added note about local functions not working on Windows due to Python implementation issues. 7 anni fa

BIN
bootstrap/bootstrap.m.gz


+ 0 - 1
bootstrap/compiler.alc

@@ -43,7 +43,6 @@ Element function compile_model(code : String, metamodel : Element):
 	port = ""
 	while (port == ""):
 		port = comm_connect("compiler")
-		sleep(0.5)
 
 	comm_set(port, "model")
 

+ 5 - 4
bootstrap/modelling.alc

@@ -308,8 +308,6 @@ Void function instantiate_existing_attribute(model : Element, element : String,
 
 String function instantiate_link(model : Element, type : String, name : String, source : String, destination : String):
 	// Create a typed link between two nodes
-	String actual_name
-
 	if (type == ""):
 		// Have to find the type ourselves, as it isn't defined
 		Element out
@@ -332,20 +330,23 @@ String function instantiate_link(model : Element, type : String, name : String,
 
 	if (bool_not(dict_in(model["model"], source))):
 		log("ERROR: source of link undefined: " + source)
-		set_pop(create_node())
 		return ""!
 
 	if (bool_not(dict_in(model["model"], destination))):
 		log("ERROR: destination of link undefined: " + destination)
-		set_pop(create_node())
 		return ""!
 
 	if (bool_not(dict_in(model["metamodel"]["model"], type))):
 		log("ERROR: (instantiate_link) no such type in metamodel: " + type)
 		log("    for " + name)
 		return ""!
+
+	return instantiate_typed_link(model, type, name, source, destination)!
 	
+String function instantiate_typed_link(model : Element, type : String, name : String, source : String, destination : String):
 	Element v
+	String actual_name
+
 	v = create_edge(model["model"][source], model["model"][destination])
 	actual_name = instantiated_name(v, name)
 	dict_add_fast(model["model"], actual_name, v)

+ 12 - 2
doc/problems.rst

@@ -6,12 +6,22 @@ Most functions are however rather safe and should return an exception in the wra
 Note that even if the MvK crashes with such an error as mentioned below, this only breaks the violating task and all other tasks are left unharmed.
 As such, it is possible for a user to log in again on a different task, although there is no continuation.
 
-TODO: body_id is None
+body_id is None
 ---------------------
 
 This error likely means that a function is called that was never defined: the declaration was found, but the definition is empty.
 
-TODO: None has no length
+None has no length
 ------------------------
 
 Operations done on an error value, such as a dictionary read on a non-existing element
+
+pickle.PicklingError: Can't pickle <function X>
+-----------------------------------------------
+
+The wrapper for manual activities relies on the multiprocessing library to spawn the various user-side interactions.
+As such, the different functions are spawned in different Python processes, to allow for multiple such functions to execute simultaneously, as needed for process enactment.
+While this allows for multiple such functions to execute simultaneously, as needed for process enactment, `this is not 100% supported in Python for Windows<https://docs.python.org/2/library/multiprocessing.html#windows>`_.
+Your error is therefore likely caused by the multiprocessing library wanting to pass a function (or something else...), which it could not.
+For example, it is not possible on Windows to give a local (nested) function as parameter to *transformation_execute_MANUAL*, as local functions cannot be pickled.
+On Linux, that would work perfectly fine.

+ 8 - 0
hybrid_server/classes/task.xml

@@ -112,14 +112,22 @@
                             <state id="processing">
                                 <onentry>
                                     <script>
+                                        if self.mvk.profiling:
+                                            try:
+                                                self.mvk.prev_timers[self.taskname] += (time.time() - self.mvk.end_timers[self.taskname])
+                                            except KeyError:
+                                                self.mvk.prev_timers[self.taskname] = time.time()
                                         start_time = time.time()
                                         # Grant each task some milliseconds of execution
+                                        timeout = (0.0, False)
                                         while (time.time() - start_time &lt; 0.05):
                                             timeout = self.execute_modelverse(self.taskname, "execute_rule", [])
                                             if timeout[0] > 0.0:
                                                 # We should not continue immediately
                                                 break
                                         self.timeout = timeout
+                                        if self.mvk.profiling:
+                                            self.mvk.end_timers[self.taskname] = time.time()
                                     </script>
                                 </onentry>
 

+ 45 - 0
kernel/modelverse_kernel/compiled.py

@@ -373,6 +373,51 @@ def instantiate_node(a, b, c, **remainder):
 
     yield [("RETURN", [name_node])]
 
+def instantiate_typed_link(a, b, c, d, e, **remainder):
+    if "value" not in b:
+        b['value'], = yield [("RV", [b['id']])]
+
+    if "value" not in c:
+        c['value'], = yield [("RV", [c['id']])]
+        
+    if "value" not in d:
+        d['value'], = yield [("RV", [d['id']])]
+        
+    if "value" not in e:
+        e['value'], = yield [("RV", [e['id']])]
+        
+    dict_entry, tm = yield [\
+               ("RD", [a['id'], "model"]),
+               ("RD", [a['id'], "type_mapping"]),
+              ]
+    src, dst = yield [\
+                ("RD", [dict_entry, d['value']]),
+                ("RD", [dict_entry, e['value']]),
+              ]
+    node, = yield [("CE", [src, dst])]
+    if c['value'] == "":
+        name = "__" + str(node)
+        name_node = {'value': name}
+    else:
+        name = c['value']
+        name_node = c
+
+    _, root = yield [("CD", [dict_entry, name, node]),
+                     ("RD", [tm, "root"])]
+
+    # Create new type links
+    type_elem, instance_elem = yield [("CNV", [b['value']]), ("CNV", [name])]
+    type_link, = yield [("CE", [root, type_elem])]
+    instance_link, = yield [("CE", [type_link, instance_elem])]
+
+    # Add them to the model
+    yield  [("CD", [tm, str(type_elem), type_elem]),
+            ("CD", [tm, str(instance_elem), instance_elem]),
+            ("CD", [tm, str(type_link), type_link]),
+            ("CD", [tm, str(instance_link), instance_link])]
+
+    yield [("RETURN", [name_node])]
+
 def list_insert(a, b, c, **remainder):
     if "id" not in b:
         b["id"], = yield [("CNV", [b['value']])]

+ 18 - 10
kernel/modelverse_kernel/main.py

@@ -5,12 +5,15 @@ import modelverse_kernel.jit as jit
 from collections import defaultdict
 import sys
 import time
+import json
 
 if sys.version > '3': # pragma: no cover
     string_types = (str,)
 else:
     string_types = (str, unicode)
 
+PROFILE = False
+
 class ModelverseKernel(object):
     
     counter = 0
@@ -37,6 +40,14 @@ class ModelverseKernel(object):
 
         self.debug_info = defaultdict(list)
 
+        if PROFILE:
+            self.prev_timers = {}
+            self.end_timers = {}
+            self.profiling = True
+            self.profile_file = open("../profiling_results", 'w')
+        else:
+            self.profiling = False
+
     def try_to_protect(self, var):
         if isinstance(var, dict) and "id" in var and var['id'] is not None:
             return set([var['id']])
@@ -324,7 +335,7 @@ class ModelverseKernel(object):
 
             param_list = "{" + ", ".join(["'%s': %s" % (k, v) for k, v in param_list.items()]) + "}"
             actual_computation = "$$INDENT$$%s, = yield [('CALL_ARGS', [_mvk.execute_jit, (_root, %s['id'], _taskname, %s)])]\n" % (value, func_name, param_list)
-                
+
             if indent == 0:
                 # No indent, meaning that we use it inline
                 # Therefore, we output the prev and value individually
@@ -334,7 +345,6 @@ class ModelverseKernel(object):
                 # Therefore, we only do the yield
                 prev, instruction = prev_func_name + computation, actual_computation.replace("$$INDENT$$", "  " * indent)
 
-
         elif inst_type["value"] == "access":
             value, = yield [("RD", [inst, "var"])]
             (prev, instruction), = yield [("CALL_ARGS", [self.print_instruction, (value, 0, nested_indent)])]
@@ -375,7 +385,6 @@ class ModelverseKernel(object):
             print("Ignoring mutable or unreadable: %s" % suggested_name)
             raise jit.JitCompilationFailedException("FAIL")
 
-        #print("Reading function: %s" % suggested_name)
         (prev, printed), = yield [("CALL_ARGS", [self.print_instruction, (inst, 1)])]
         preamble = "  _mvk = kwargs['mvk']\n" + \
                    "  _root = kwargs['task_root']\n" + \
@@ -385,13 +394,10 @@ class ModelverseKernel(object):
                    "    _globs, = yield [('RD', [kwargs['task_root'], 'globals'])]\n" + \
                    "    _mvk.jit.cache[_taskname]['_globs'] = _globs\n"
         printed = preamble + prev + printed
-        #print("Total printed function: ")
         if params:
             func = "def " + suggested_name + "(" + ", ".join([chr(ord('a') + i) for i in range(len(params))]) + ", **kwargs):\n" + "".join(["  var_%s = %s\n" % (param, chr(ord('a') + i)) for i, param in enumerate(params)]) + printed
         else:
             func = "def " + suggested_name + "(**kwargs):\n" + printed
-        
-        #print(func)
 
         try:
             # Try to write out the generated code
@@ -456,13 +462,15 @@ class ModelverseKernel(object):
                 self.jit.register_compiled(inst, compiled_func, suggested_name)
 
         # Run the compiled function.
+        if self.profiling:
+            self.profile_file.write(json.dumps([gen.__name__ for gen in self.request_handlers[taskname]['execute_rule'].generator_stack if gen is not None and gen.__name__ not in ['execute_rule', 'execute_jit']] + [time.time() - self.prev_timers[taskname]]) + "\n")
+            self.prev_timers[taskname] = time.time()
         if compiled_func == primitive_functions.dict_read:
             if "value" not in params['b']:
                 params['b']['value'], = yield [("RV", [params['b']['id']])]
             result, = yield [("RD", [params['a']['id'], params['b']['value']])]
             result = {'id': result}
         else:
-            #print("CALL " + str(self.jit.get_global_name(inst)) + " --> " + params)
             results = yield [("CALL_KWARGS", [compiled_func, params])]
             if results is None:
                 raise Exception("%s: primitive finished without returning a value!" % (self.debug_info[taskname]))
@@ -470,6 +478,9 @@ class ModelverseKernel(object):
                 result, = results
             if result is None:
                 result = {'id': None, 'value': None}
+        if self.profiling:
+            self.profile_file.write(json.dumps([gen.__name__ for gen in self.request_handlers[taskname]['execute_rule'].generator_stack if gen is not None and gen.__name__ not in ['execute_rule', 'execute_jit']] + [compiled_func.__name__, time.time() - self.prev_timers[taskname]]) + "\n")
+            self.prev_timers[taskname] = time.time()
 
         if store:
             # Clean up the current stack, as if a return happened
@@ -477,9 +488,6 @@ class ModelverseKernel(object):
                 ("RD", [task_frame, "prev"]),
                 ("RD", [task_frame, primitive_functions.EXCEPTION_RETURN_KEY])]
 
-            #if self.debug_info[self.taskname]:
-            #    self.debug_info[self.taskname].pop()
-
             if "id" not in result:
                 result['id'], = yield [("CNV", [result['value']])]
 

+ 34 - 0
scripts/analyse_profiler.py

@@ -0,0 +1,34 @@
+import json
+
+tottime = {}
+cumtime = {}
+
+with open("profiling_results", "r") as f:
+    for l in f:
+        stack = json.loads(l)
+        t = stack.pop()
+
+        if stack:
+            prev = None
+            for func in set(stack):
+                cumtime[func] = cumtime.get(func, 0.0) + t
+            tottime[stack[-1]] = tottime.get(stack[-1], 0.0) + t
+
+max_tot = sorted(tottime.keys(), key=lambda i: -tottime[i])
+max_cum = sorted(cumtime.keys(), key=lambda i: -cumtime[i])
+
+print("TOTTIME")
+for f in max_tot:
+    print("%s -- %s -- %s" % (f, tottime[f], cumtime[f]))
+
+print("")
+print("")
+print("CUMTIME")
+for f in max_cum:
+    print("%s -- %s -- %s" % (f, tottime[f], cumtime[f]))
+
+print("")
+print("")
+print("NAME")
+for f in sorted(tottime.keys()):
+    print("%s -- %s -- %s" % (f, tottime[f], cumtime[f]))

+ 166 - 171
unit/test_all.py

@@ -19,11 +19,161 @@ def null_operation(model):
 
 def model_is_empty_operation(model):
     assert model is None
+    
+def ops_manual_callback(model):
+    p1 = instantiate(model, "PetriNet_Runtime/Place")
+    p2 = instantiate(model, "PetriNet_Runtime/Place")
+    p3 = instantiate(model, "PetriNet_Runtime/Place")
+    t1 = instantiate(model, "PetriNet_Runtime/Transition")
+    p2t1 = instantiate(model, "PetriNet_Runtime/P2T", (p1, t1))
+    p2t2 = instantiate(model, "PetriNet_Runtime/P2T", (p2, t1))
+    t2p1 = instantiate(model, "PetriNet_Runtime/T2P", (t1, p3))
+    attr_assign(model, p1, "tokens", 1)
+    attr_assign(model, p1, "name", "p1")
+    attr_assign(model, p2, "tokens", 2)
+    attr_assign(model, p2, "name", "p2")
+    attr_assign(model, p3, "tokens", 3)
+    attr_assign(model, p3, "name", "p3")
+    attr_assign(model, t1, "name", "t1")
+    attr_assign(model, t1, "executing", False)
+    attr_assign(model, p2t1, "weight", 1)
+    attr_assign(model, p2t2, "weight", 1)
+    attr_assign(model, t2p1, "weight", 2)
+
+def pn_subfunc_callback_refine_PN(model):
+    p1 = instantiate(model, "PetriNet/Place")
+    attr_assign(model, p1, "name", "p1")
+    attr_assign(model, p1, "tokens", 1)
+
+    t1 = instantiate(model, "PetriNet/Transition")
+    attr_assign(model, t1, "name", "t1")
+
+    p2t = instantiate(model, "PetriNet/P2T", (p1, t1))
+    attr_assign(model, p2t, "weight", 1)
+
+def render_add_tracability(model):
+    instantiate(model, "Association", ("abstract/Block", "rendered/Group"), ID="TracabilityLink")
+            
+def ops_add_tracability_D2R(model):
+    instantiate(model, "Association", ("PetriNet/Place", "PetriNet_Runtime/Place"), ID="D2R_PlaceLink")
+    instantiate(model, "Association", ("PetriNet/Transition", "PetriNet_Runtime/Transition"), ID="D2R_TransitionLink")
 
+def ops_add_tracability_R2D(model):
+    instantiate(model, "Association", ("PetriNet_Runtime/Place", "PetriNet/Place"), ID="R2D_PlaceLink")
+    instantiate(model, "Association", ("PetriNet_Runtime/Transition", "PetriNet/Transition"), ID="R2D_TransitionLink")
+            
 def operation_exec_1(model):
     assert model is not None
     assert [{"__id": "MODEL_A/__0", "__type": "MODEL_A/A", "name": None}] == element_list_nice(model)
     instantiate(model, "MODEL_B/B")
+    
+def operation_MAN_0(model):
+    # Check if both are present
+    lst = element_list_nice(model)
+    assert len(lst) == 6
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+
+    # Do minor merge operation
+    instantiate(model, "Association", edge=("MODEL_A/A", "MODEL_B/B"), ID="trace")
+
+    # Check again
+    lst = element_list_nice(model)
+    assert len(lst) == 7
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "trace", "__type": "Association", "__source": "MODEL_A/A", "__target": "MODEL_B/B", "name": None, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}, "lower_cardinality": None, "upper_cardinality": None} in lst
+
+def operation_MAN_1(model):
+    # Check if both are present
+    lst = element_list_nice(model)
+    assert len(lst) == 6
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+            
+def operation_MT_0(model):
+    # Check if both are present
+    lst = element_list_nice(model)
+    assert len(lst) == 6
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+
+    # Do minor merge operation
+    instantiate(model, "Association", edge=("MODEL_A/A", "MODEL_B/B"), ID="trace")
+
+    # Check again
+    lst = element_list_nice(model)
+    assert len(lst) == 7
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "trace", "__type": "Association", "__source": "MODEL_A/A", "__target": "MODEL_B/B", "name": None, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}, "lower_cardinality": None, "upper_cardinality": None} in lst
+
+def operation_MT_1(model):
+    # Check if both are present
+    lst = element_list_nice(model)
+    assert len(lst) == 6
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+
+def operation_AL_0(model):
+    # Check if both are present
+    lst = element_list_nice(model)
+    assert len(lst) == 6
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+
+    # Do minor merge operation
+    instantiate(model, "Association", edge=("MODEL_A/A", "MODEL_B/B"), ID="trace")
+
+    # Check again
+    lst = element_list_nice(model)
+    assert len(lst) == 7
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "trace", "__type": "Association", "__source": "MODEL_A/A", "__target": "MODEL_B/B", "name": None, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}, "lower_cardinality": None, "upper_cardinality": None} in lst
+
+def operation_AL_1(model):
+    # Check if both are present
+    lst = element_list_nice(model)
+    assert len(lst) == 6
+    assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
+    assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
 
 model_hierarchy = \
             {"formalisms/": {"SimpleClassDiagrams": {},
@@ -4065,45 +4215,8 @@ class TestModelverse(unittest.TestCase):
         transformation_add_MANUAL({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/c")
 
         # Add a transformation with normal signature and merged metamodel changes
-        def operation(model):
-            # Check if both are present
-            lst = element_list_nice(model)
-            assert len(lst) == 6
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-
-            # Do minor merge operation
-            instantiate(model, "Association", edge=("MODEL_A/A", "MODEL_B/B"), ID="trace")
-
-            # Check again
-            lst = element_list_nice(model)
-            assert len(lst) == 7
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "trace", "__type": "Association", "__source": "MODEL_A/A", "__target": "MODEL_B/B", "name": None, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}, "lower_cardinality": None, "upper_cardinality": None} in lst
-
-        transformation_add_MANUAL({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/d", operation)
-        
-        def operation(model):
-            # Check if both are present
-            lst = element_list_nice(model)
-            assert len(lst) == 6
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-
-        transformation_add_MANUAL({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/e", operation)
+        transformation_add_MANUAL({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/d", operation_MAN_0)
+        transformation_add_MANUAL({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/e", operation_MAN_1)
 
         try:
             transformation_add_MANUAL({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/A"}, "users/user/test/f")
@@ -4116,9 +4229,7 @@ class TestModelverse(unittest.TestCase):
 
         # Add a transformation with empty signature and a callback
         try:
-            def operation(model):
-                pass
-            transformation_add_MANUAL({}, {}, "users/user/test/h", operation)
+            transformation_add_MANUAL({}, {}, "users/user/test/h", null_operation)
             self.fail()
         except CallbackOnEmptySignature:
             assert "h" not in model_list("users/user/test")
@@ -4204,45 +4315,10 @@ class TestModelverse(unittest.TestCase):
         transformation_add_AL({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/c", default_function)
 
         # Add a transformation with normal signature and merged metamodel changes
-        def operation(model):
-            # Check if both are present
-            lst = element_list_nice(model)
-            assert len(lst) == 6
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-
-            # Do minor merge operation
-            instantiate(model, "Association", edge=("MODEL_A/A", "MODEL_B/B"), ID="trace")
-
-            # Check again
-            lst = element_list_nice(model)
-            assert len(lst) == 7
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "trace", "__type": "Association", "__source": "MODEL_A/A", "__target": "MODEL_B/B", "name": None, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}, "lower_cardinality": None, "upper_cardinality": None} in lst
-
-        transformation_add_AL({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/d", default_function, operation)
-        
-        def operation(model):
-            # Check if both are present
-            lst = element_list_nice(model)
-            assert len(lst) == 6
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
 
-        transformation_add_AL({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/e", default_function, operation)
+
+        transformation_add_AL({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/d", default_function, operation_AL_0)
+        transformation_add_AL({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/e", default_function, operation_AL_1)
 
         try:
             transformation_add_AL({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/A"}, "users/user/test/f", default_function)
@@ -4255,9 +4331,7 @@ class TestModelverse(unittest.TestCase):
 
         # Add a transformation with empty signature and a callback
         try:
-            def operation(model):
-                pass
-            transformation_add_AL({}, {}, "users/user/test/h", default_function, operation)
+            transformation_add_AL({}, {}, "users/user/test/h", default_function, null_operation)
             self.fail()
         except CallbackOnEmptySignature:
             assert "h" not in model_list("users/user/test")
@@ -4350,45 +4424,10 @@ class TestModelverse(unittest.TestCase):
         transformation_add_MT({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/c", default_function)
 
         # Add a transformation with normal signature and merged metamodel changes
-        def operation(model):
-            # Check if both are present
-            lst = element_list_nice(model)
-            assert len(lst) == 6
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-
-            # Do minor merge operation
-            instantiate(model, "Association", edge=("MODEL_A/A", "MODEL_B/B"), ID="trace")
-
-            # Check again
-            lst = element_list_nice(model)
-            assert len(lst) == 7
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "trace", "__type": "Association", "__source": "MODEL_A/A", "__target": "MODEL_B/B", "name": None, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}, "lower_cardinality": None, "upper_cardinality": None} in lst
-
-        transformation_add_MT({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/d", default_function, operation)
-        
-        def operation(model):
-            # Check if both are present
-            lst = element_list_nice(model)
-            assert len(lst) == 6
-            assert {"__id": "MODEL_A/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A", "__type": "Class", "name": "A", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_A/A_name", "__type": "AttributeLink", "__source": "MODEL_A/A", "__target": "MODEL_A/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/String", "__type": "SimpleAttribute", "name": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B", "__type": "Class", "name": "B", "lower_cardinality": None, "upper_cardinality": None, "abstract": None, "constraint": {"AL": ""}} in lst
-            assert {"__id": "MODEL_B/B_name", "__type": "AttributeLink", "__source": "MODEL_B/B", "__target": "MODEL_B/String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
+        transformation_add_MT({"MODEL_A": "users/user/test/A"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/d", default_function, operation_MT_0)
+
 
-        transformation_add_MT({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/e", default_function, operation)
+        transformation_add_MT({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/B"}, "users/user/test/e", default_function, operation_MT_1)
 
         try:
             transformation_add_MT({"MODEL_A": "users/user/test/A", "MODEL_B": "users/user/test/B"}, {"MODEL_B": "users/user/test/A"}, "users/user/test/f", default_function)
@@ -4405,9 +4444,7 @@ class TestModelverse(unittest.TestCase):
 
         # Add a transformation with empty signature and a callback
         try:
-            def operation(model):
-                pass
-            transformation_add_MT({}, {}, "users/user/test/h", default_function, operation)
+            transformation_add_MT({}, {}, "users/user/test/h", default_function, null_operation)
             self.fail()
         except CallbackOnEmptySignature:
             assert "h" not in model_list("users/user/test")
@@ -5407,43 +5444,14 @@ class TestModelverse(unittest.TestCase):
     def test_operations(self):
         log = []
 
-        def manual_callback(model):
-            p1 = instantiate(model, "PetriNet_Runtime/Place")
-            p2 = instantiate(model, "PetriNet_Runtime/Place")
-            p3 = instantiate(model, "PetriNet_Runtime/Place")
-            t1 = instantiate(model, "PetriNet_Runtime/Transition")
-            p2t1 = instantiate(model, "PetriNet_Runtime/P2T", (p1, t1))
-            p2t2 = instantiate(model, "PetriNet_Runtime/P2T", (p2, t1))
-            t2p1 = instantiate(model, "PetriNet_Runtime/T2P", (t1, p3))
-            attr_assign(model, p1, "tokens", 1)
-            attr_assign(model, p1, "name", "p1")
-            attr_assign(model, p2, "tokens", 2)
-            attr_assign(model, p2, "name", "p2")
-            attr_assign(model, p3, "tokens", 3)
-            attr_assign(model, p3, "name", "p3")
-            attr_assign(model, t1, "name", "t1")
-            attr_assign(model, t1, "executing", False)
-            attr_assign(model, p2t1, "weight", 1)
-            attr_assign(model, p2t2, "weight", 1)
-            attr_assign(model, t2p1, "weight", 2)
-
         model_add("users/user/test/PetriNet", "formalisms/SimpleClassDiagrams", open("integration/code/pn_design.mvc", "r").read())
         model_add("users/user/test/PetriNet_Runtime", "formalisms/SimpleClassDiagrams", open("integration/code/pn_runtime.mvc", "r").read())
-
         model_add("users/user/test/my_pn", "users/user/test/PetriNet", open("integration/code/pn_design_model.mvc", "r").read())
 
-        def add_tracability_D2R(model):
-            instantiate(model, "Association", ("PetriNet/Place", "PetriNet_Runtime/Place"), ID="D2R_PlaceLink")
-            instantiate(model, "Association", ("PetriNet/Transition", "PetriNet_Runtime/Transition"), ID="D2R_TransitionLink")
-
-        def add_tracability_R2D(model):
-            instantiate(model, "Association", ("PetriNet_Runtime/Place", "PetriNet/Place"), ID="R2D_PlaceLink")
-            instantiate(model, "Association", ("PetriNet_Runtime/Transition", "PetriNet/Transition"), ID="R2D_TransitionLink")
-
         transformation_add_MT({"PetriNet": "users/user/test/PetriNet"}, {}, "users/user/test/print_pn", open("integration/code/pn_print.mvc").read())
-        transformation_add_MANUAL({"PetriNet": "users/user/test/PetriNet"}, {"PetriNet_Runtime": "users/user/test/PetriNet_Runtime"}, "users/user/test/pn_design_to_runtime", add_tracability_D2R)
+        transformation_add_MANUAL({"PetriNet": "users/user/test/PetriNet"}, {"PetriNet_Runtime": "users/user/test/PetriNet_Runtime"}, "users/user/test/pn_design_to_runtime", ops_add_tracability_D2R)
         transformation_add_AL({"PetriNet_Runtime": "users/user/test/PetriNet_Runtime"}, {"PetriNet_Runtime": "users/user/test/PetriNet_Runtime"}, "users/user/test/pn_simulate", open("integration/code/pn_simulate.alc").read())
-        transformation_add_MT({"PetriNet_Runtime": "users/user/test/PetriNet_Runtime"}, {"PetriNet": "users/user/test/PetriNet"}, "users/user/test/pn_runtime_to_design", open("integration/code/pn_runtime_to_design.mvc").read(), add_tracability_R2D)
+        transformation_add_MT({"PetriNet_Runtime": "users/user/test/PetriNet_Runtime"}, {"PetriNet": "users/user/test/PetriNet"}, "users/user/test/pn_runtime_to_design", open("integration/code/pn_runtime_to_design.mvc").read(), ops_add_tracability_R2D)
 
         log = []
         ctrl = log_output.Controller(log, keep_running=False)
@@ -5457,7 +5465,7 @@ class TestModelverse(unittest.TestCase):
                                 '"p2" --> 2',
                                 '"p3" --> 3'])
 
-        assert transformation_execute_MANUAL("users/user/test/pn_design_to_runtime", {"PetriNet": "users/user/test/my_pn"}, {"PetriNet_Runtime": "users/user/test/my_pn_RT"}, manual_callback) == True
+        assert transformation_execute_MANUAL("users/user/test/pn_design_to_runtime", {"PetriNet": "users/user/test/my_pn"}, {"PetriNet_Runtime": "users/user/test/my_pn_RT"}, ops_manual_callback) == True
         assert transformation_execute_AL("users/user/test/pn_simulate", {"PetriNet_Runtime": "users/user/test/my_pn_RT"}, {"PetriNet_Runtime": "users/user/test/my_pn_RT"}) == True
         assert transformation_execute_MT("users/user/test/pn_runtime_to_design", {"PetriNet_Runtime": "users/user/test/my_pn_RT"}, {"PetriNet": "users/user/test/my_pn"}) == True
 
@@ -5482,16 +5490,6 @@ class TestModelverse(unittest.TestCase):
         transformation_add_AL({"PetriNet": "users/user/test/PetriNet"}, {"ReachabilityGraph": "users/user/test/ReachabilityGraph"}, "users/user/test/reachability", open("integration/code/reachability_subfunction.alc", "r").read())
         transformation_add_MT({"ReachabilityGraph": "users/user/test/ReachabilityGraph"}, {}, "users/user/test/reachability_print", open("integration/code/reachabilitygraph_print.mvc", 'r').read())
 
-        def callback_refine_PN(model):
-            p1 = instantiate(model, "PetriNet/Place")
-            attr_assign(model, p1, "name", "p1")
-            attr_assign(model, p1, "tokens", 1)
-
-            t1 = instantiate(model, "PetriNet/Transition")
-            attr_assign(model, t1, "name", "t1")
-
-            p2t = instantiate(model, "PetriNet/P2T", (p1, t1))
-            attr_assign(model, p2t, "weight", 1)
 
         log = []
         ctrl = log_output.Controller(log, keep_running=False)
@@ -5499,7 +5497,7 @@ class TestModelverse(unittest.TestCase):
         thrd.daemon = True
         thrd.start()
 
-        process_execute("users/user/test/pn_reachability", {}, {"users/user/test/refine_PN": callback_refine_PN, "users/user/test/reachability_print": (ctrl, "inp", "outp")})
+        process_execute("users/user/test/pn_reachability", {}, {"users/user/test/refine_PN": pn_subfunc_callback_refine_PN, "users/user/test/reachability_print": (ctrl, "inp", "outp")})
         thrd.join()
 
         assert set(log) == set(['"0": {"p1": 1}',
@@ -5511,10 +5509,7 @@ class TestModelverse(unittest.TestCase):
         model_add("users/user/test/MM_rendered_graphical", "formalisms/SimpleClassDiagrams", open("integration/code/MM_rendered_graphical.mvc", 'r').read())
         model_add("users/user/test/my_CBD", "users/user/test/CausalBlockDiagrams", open("integration/code/my_cbd.mvc", 'r').read())
 
-        def add_tracability(model):
-            instantiate(model, "Association", ("abstract/Block", "rendered/Group"), ID="TracabilityLink")
-
-        transformation_add_MT({"abstract": "users/user/test/CausalBlockDiagrams", "rendered": "users/user/test/MM_rendered_graphical"}, {"abstract": "users/user/test/CausalBlockDiagrams", "rendered": "users/user/test/MM_rendered_graphical"}, "users/user/test/render_graphical_CBD", open("integration/code/CBD_mapper.mvc", 'r').read(), add_tracability)
+        transformation_add_MT({"abstract": "users/user/test/CausalBlockDiagrams", "rendered": "users/user/test/MM_rendered_graphical"}, {"abstract": "users/user/test/CausalBlockDiagrams", "rendered": "users/user/test/MM_rendered_graphical"}, "users/user/test/render_graphical_CBD", open("integration/code/CBD_mapper.mvc", 'r').read(), render_add_tracability)
         result = model_render("users/user/test/my_CBD", "users/user/test/render_graphical_CBD", "users/user/test/my_perceptualized_CBD")
 
         assert len(result) == 23