Browse Source

Cleaned up and got most tests to work with transformations

Yentl Van Tendeloo 8 years ago
parent
commit
45323f54ca

BIN
bootstrap/bootstrap.m.gz


+ 0 - 1
bootstrap/conformance_scd.alc

@@ -112,7 +112,6 @@ String function conformance_scd(model : Element):
 			model_name = set_pop(keys)
 			element = model["model"][model_name]
 			type_name = reverseKeyLookup(metamodel["model"], dict_read_node(typing, element))
-			//log((("Check " + model_name) + " : ") + type_name)
 
 			if (bool_not(dict_in_node(typing, element))):
 				return "Model has no type specified: " + model_info(model, model_name)!

+ 0 - 1
bootstrap/constructors.alc

@@ -148,7 +148,6 @@ Action function construct_unknown():
 		return construct_continue()!
 	elif (elem == "model"):
 		construct_model()
-		log("Constructed model")
 		return construct_unknown()!
 	else:
 		log("ERROR: did not understand command " + cast_e2s(elem))

+ 1 - 4
bootstrap/metamodels.alc

@@ -250,11 +250,8 @@ Element function initialize_PN(location_SCD : String, location_PN : String):
 	instantiate_attribute(pn, "T2P_weight", "target_upper_cardinality", 1)
 
 	// Add constraint on the Natural
-	//TODO temporarily done for RAMification to test
-	//add_constraint(pn, "Natural", constraint_natural)
+	add_constraint(pn, "Natural", constraint_natural)
 
-	// Add global constraints
-	//set_model_constraints(pn, petrinet_constraints)
 	export_node(location_PN, pn)
 
 	return pn!

+ 0 - 1
bootstrap/model_management.alc

@@ -133,6 +133,5 @@ Element function model_retype_on_name(model : Element, new_MM : Element, operati
 
 	dict_delete(model, "metamodel")
 	dict_add(model, "metamodel", new_MM)
-	log("Elements in model: " + set_to_string(dict_keys(model["model"])))
 
 	return model!

+ 0 - 2
bootstrap/modelling.alc

@@ -186,7 +186,6 @@ Void function instantiate_attribute(model : Element, element : String, attribute
 	String attr_type
 	String attr_name
 
-	log("Adding attribute " + attribute_name)
 	attr_type = find_attribute_type(model, element, attribute_name)
 
 	if (attr_type == ""):
@@ -459,7 +458,6 @@ Void function construct_model():
 	String command
 	while (True):
 		command = input()
-		log(command)
 		if (command == "instantiate_bottom"):
 			Element m
 			m = instantiate_bottom()

+ 0 - 2
integration/code/pn_interface.alc

@@ -312,8 +312,6 @@ Element function main():
 	while (True):
 		output("Please give your command.")
 		command = input()
-		log("Exec " + command)
-
 		if (command == "help"):
 			output("Currently no model is loaded, so your operations are limited to:")
 			output("  new    -- Create a new model and save it for future use")

+ 72 - 341
integration/test_pn_interface.py

@@ -7,6 +7,30 @@ set_inheritance = [
         "Set inheritance link!",
     ]
 
+join = ["Model name?",
+        "New metamodel?",
+       ]
+
+unify = ["Which language do you want to unify?",
+         "Name of this language in the unification",
+         "Second language to unify?",
+         "Name of this language in the unification",
+         ]
+
+ramify = ["Name of the RAMified metamodel to create",
+          "Source language?"]
+
+transform = ["Which model do you want to transform?",
+             "Which schedule do you want to execute?",
+            ]
+
+transform_result_true = ["Transformation result: True"]
+
+split = ["Name of the model to split up?",
+         "Name of new metamodel?",
+         "Typename to split?",
+        ]
+
 do_instantiate_simple = [
             "new", "PetriNets", "abc",
             "instantiate", "Transition", "t1",
@@ -528,9 +552,10 @@ Element function constraint(model : Element, name : String):
                 (instantiate_node + prompt) * 6 + \
                 (instantiate_edge + prompt) * 9 + \
                 (attr_add + prompt) * 20 + \
-                ["Element to constrain (empty for global)?",
-                 "Give input to function constructors for LOCAL constraint!",
-                 "Added constraint to model!"] + \
+                ["Which model do you want to assign a coded attribute to?",
+                 "Which attribute do you wish to assign?",
+                 "Constructors for code?",
+                 "Added code!"] + \
                 prompt + \
                 ["OK"] + \
                 prompt + prompt + new + loaded + \
@@ -539,335 +564,6 @@ Element function constraint(model : Element, name : String):
                 ["OK"],
             mode))
 
-    def test_po_pn_interface_transform_pn(self):
-        code_mark_constraint = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-include "object_operations.alh"
-Boolean function constraint(host_model : Element, name : String):
-	// Make sure that all places have enough tokens
-	Element links
-	String link
-	String place
-	links = allIncomingAssociationInstances(host_model, name, "P2T")
-	while (read_nr_out(links) > 0):
-		link = set_pop(links)
-		place = readAssociationSource(host_model, link)
-		log("Check link " + link)
-		log("Check place " + place)
-		if (integer_lt(read_attribute(host_model, place, "tokens"), read_attribute(host_model, link, "weight"))):
-			// Not enough tokens for this weight
-			return False!
-	return True!
-            """
-
-        code_mark_action = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Void function action(host_model : Element, name : String, mapping : Element):
-	unset_attribute(host_model, name, "executing")
-	instantiate_attribute(host_model, name, "executing", True)
-	return!
-            """
-
-        code_consume_transition_constraint = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Boolean function constraint(host_model : Element, name : String):
-	// Check if this node is executing currently
-	return value_eq(read_attribute(host_model, name, "executing"), True)!
-            """
-
-        code_consume_place_constraint = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Boolean function constraint(host_model : Element, name : String):
-	// Check if this node is executing currently
-	return value_eq(read_attribute(host_model, name, "executed"), False)!
-            """
-
-        code_consume_place_action = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Void function action(host_model : Element, name : String, mapping : Element):
-	Integer tokens
-	Integer weight
-	tokens = read_attribute(host_model, name, "tokens")
-	weight = read_attribute(host_model, mapping["2"], "weight")
-	unset_attribute(host_model, name, "tokens")
-	instantiate_attribute(host_model, name, "tokens", tokens - weight)
-	unset_attribute(host_model, name, "executed")
-	instantiate_attribute(host_model, name, "executed", True)
-	return!
-            """
-
-        code_produce_place_action = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Void function action(host_model : Element, name : String, mapping : Element):
-	Integer tokens
-	Integer weight
-	tokens = read_attribute(host_model, name, "tokens")
-	weight = read_attribute(host_model, mapping["2"], "weight")
-	unset_attribute(host_model, name, "tokens")
-	instantiate_attribute(host_model, name, "tokens", tokens + weight)
-	unset_attribute(host_model, name, "executed")
-	instantiate_attribute(host_model, name, "executed", True)
-	return!
-            """
-
-        code_unmark_transition_constraint = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Boolean function constraint(host_model : Element, name : String):
-	// Check if this node is executing currently
-	return value_eq(read_attribute(host_model, name, "executing"), True)!
-            """
-
-        code_unmark_place_constraint = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Boolean function constraint(host_model : Element, name : String):
-	// Check if this node is executing currently
-	return value_eq(read_attribute(host_model, name, "executed"), True)!
-            """
-
-        code_unmark_transition_action = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Void function action(host_model : Element, name : String, mapping : Element):
-	unset_attribute(host_model, name, "executing")
-	instantiate_attribute(host_model, name, "executing", False)
-	return!
-            """
-
-        code_unmark_place_action = \
-            """
-include "primitives.alh"
-include "modelling.alh"
-Void function action(host_model : Element, name : String, mapping : Element):
-	unset_attribute(host_model, name, "executed")
-	instantiate_attribute(host_model, name, "executed", False)
-	return!
-            """
-
-        constructor_mark_constraint = get_constructor(code_mark_constraint)
-        constructor_mark_action = get_constructor(code_mark_action)
-
-        constructor_consume_transition_constraint = get_constructor(code_consume_transition_constraint)
-        constructor_consume_place_constraint = get_constructor(code_consume_place_constraint)
-        constructor_consume_place_action = get_constructor(code_consume_place_action)
-
-        constructor_produce_transition_constraint = constructor_consume_transition_constraint
-        constructor_produce_place_constraint = constructor_consume_place_constraint
-        constructor_produce_place_action = get_constructor(code_produce_place_action)
-
-        constructor_unmark_transition_constraint = constructor_consume_transition_constraint
-        constructor_unmark_transition_action = get_constructor(code_unmark_transition_action)
-
-        constructor_unmark_place_constraint = get_constructor(code_unmark_place_constraint)
-        constructor_unmark_place_action = get_constructor(code_unmark_place_action)
-
-        self.assertTrue(run_file(all_files,
-            ["new", "SimpleClassDiagrams", "PetriNets_Runtime",
-                "set_inheritance", "Inheritance",
-                "instantiate", "Class", "Natural",
-                "instantiate", "Class", "Boolean",
-                "instantiate", "Class", "Place",
-                "attr_def", "Place", "tokens", "Natural",
-                "attr_def", "Place", "executed", "Boolean",
-                "instantiate", "Class", "Transition",
-                "attr_def", "Transition", "executing", "Boolean",
-                "instantiate", "Association", "P2T", "Place", "Transition",
-                "attr_def", "P2T", "weight", "Natural",
-                "instantiate", "Association", "T2P", "Transition", "Place",
-                "attr_def", "T2P", "weight", "Natural",
-                "exit",
-             "new", "PetriNets_Runtime", "pn",
-                "instantiate", "Place", "p1",
-                "attr_add", "p1", "tokens", 1,
-                "attr_add", "p1", "executed", False,
-                "instantiate", "Place", "p2",
-                "attr_add", "p2", "tokens", 2,
-                "attr_add", "p2", "executed", False,
-                "instantiate", "Transition", "t1",
-                "attr_add", "t1", "executing", False,
-                "instantiate", "P2T", "p2t", "p1", "t1",
-                "attr_add", "p2t", "weight", 1,
-                "instantiate", "P2T", "p2t2", "p2", "t1",
-                "attr_add", "p2t2", "weight", 1,
-                "exit",
-             "ramify", "PetriNets_Runtime_SCHEDULE", "in", "PetriNets_Runtime",
-             "new", "PetriNets_Runtime_SCHEDULE", "pn_simulate",
-                # Rule 1: mark transition to execute
-                # LHS
-                "instantiate", "LHS", "lhs_mark",
-                "instantiate", "Pre_Transition", "pre_mark_t",
-                "attr_add", "pre_mark_t", "label", "0",
-                "attr_add_code", "pre_mark_t", "constraint", 
-            ] + constructor_mark_constraint + [
-                "instantiate", "LHS_contains", "", "lhs_mark", "pre_mark_t",
-                # RHS
-                "instantiate", "RHS", "rhs_mark",
-                "instantiate", "Post_Transition", "post_mark_t",
-                "attr_add", "post_mark_t", "label", "0",
-                "attr_add_code", "post_mark_t", "action",
-            ] + constructor_mark_action + [
-                "instantiate", "RHS_contains", "", "rhs_mark", "post_mark_t",
-                # Atomic of rule 1 "mark"
-                "instantiate", "Atomic", "mark",
-                "instantiate", "AtomicLHS", "", "mark", "lhs_mark",
-                "instantiate", "AtomicRHS", "", "mark", "rhs_mark",
-                # Rule 2: consume tokens going into marked transition
-                # LHS
-                "instantiate", "LHS", "lhs_consume",
-                "instantiate", "Pre_Transition", "pre_consume_t",
-                "attr_add", "pre_consume_t", "label", "0",
-                "attr_add_code", "pre_consume_t", "constraint",
-            ] + constructor_consume_transition_constraint + [
-                "instantiate", "Pre_Place", "pre_consume_p",
-                "attr_add", "pre_consume_p", "label", "1",
-                "attr_add_code", "pre_consume_p", "constraint",
-            ] + constructor_consume_place_constraint + [
-                "instantiate", "Pre_P2T", "pre_consume_p2t", "pre_consume_p", "pre_consume_t",
-                "attr_add", "pre_consume_p2t", "label", "2",
-                "instantiate", "LHS_contains", "", "lhs_consume", "pre_consume_t",
-                "instantiate", "LHS_contains", "", "lhs_consume", "pre_consume_p",
-                "instantiate", "LHS_contains", "", "lhs_consume", "pre_consume_p2t",
-                # RHS
-                "instantiate", "RHS", "rhs_consume",
-                "instantiate", "Post_Transition", "post_consume_t",
-                "attr_add", "post_consume_t", "label", "0",
-                "instantiate", "Post_Place", "post_consume_p",
-                "attr_add", "post_consume_p", "label", "1",
-                "attr_add_code", "post_consume_p", "action", 
-            ] + constructor_consume_place_action + [
-                "instantiate", "Post_P2T", "post_consume_p2t", "post_consume_p", "post_consume_t",
-                "attr_add", "post_consume_p2t", "label", "2",
-                "instantiate", "RHS_contains", "", "rhs_consume", "post_consume_t",
-                "instantiate", "RHS_contains", "", "rhs_consume", "post_consume_p",
-                "instantiate", "RHS_contains", "", "rhs_consume", "post_consume_p2t",
-                # Atomic of rule 2 "consume"
-                "instantiate", "Atomic", "consume",
-                "instantiate", "AtomicLHS", "", "consume", "lhs_consume",
-                "instantiate", "AtomicRHS", "", "consume", "rhs_consume",
-                # Rule 3: produce tokens going out of marked transition
-                # LHS
-                "instantiate", "LHS", "lhs_produce",
-                "instantiate", "Pre_Transition", "pre_produce_t",
-                "attr_add", "pre_produce_t", "label", "0",
-                "attr_add_code", "pre_produce_t", "constraint",
-            ] + constructor_produce_transition_constraint + [
-                "instantiate", "Pre_Place", "pre_produce_p",
-                "attr_add", "pre_produce_p", "label", "1",
-                "attr_add_code", "pre_produce_p", "constraint",
-            ] + constructor_produce_place_constraint + [
-                "instantiate", "Pre_T2P", "pre_produce_t2p", "pre_produce_t", "pre_produce_p",
-                "attr_add", "pre_produce_t2p", "label", "2",
-                "instantiate", "LHS_contains", "", "lhs_produce", "pre_produce_t",
-                "instantiate", "LHS_contains", "", "lhs_produce", "pre_produce_p",
-                "instantiate", "LHS_contains", "", "lhs_produce", "pre_produce_t2p",
-                # RHS
-                "instantiate", "RHS", "rhs_produce",
-                "instantiate", "Post_Transition", "post_produce_t",
-                "attr_add", "post_produce_t", "label", "0",
-                "instantiate", "Post_Place", "post_produce_p",
-                "attr_add", "post_produce_p", "label", "1",
-                "attr_add_code", "post_produce_p", "action", 
-            ] + constructor_produce_place_action + [
-                "instantiate", "Post_T2P", "post_produce_t2p", "post_produce_t", "post_produce_p",
-                "attr_add", "post_produce_t2p", "label", "2",
-                "instantiate", "RHS_contains", "", "rhs_produce", "post_produce_t",
-                "instantiate", "RHS_contains", "", "rhs_produce", "post_produce_p",
-                "instantiate", "RHS_contains", "", "rhs_produce", "post_produce_t2p",
-                # Atomic of rule 3 "produce"
-                "instantiate", "Atomic", "produce",
-                "instantiate", "AtomicLHS", "", "produce", "lhs_produce",
-                "instantiate", "AtomicRHS", "", "produce", "rhs_produce",
-                # Rule 4: unmark marked transition
-                # LHS
-                "instantiate", "LHS", "lhs_unmark_transition",
-                "instantiate", "Pre_Transition", "pre_unmark_t",
-                "attr_add", "pre_unmark_t", "label", "0",
-                "attr_add_code", "pre_unmark_t", "constraint",
-            ] + constructor_unmark_transition_constraint + [
-                "instantiate", "LHS_contains", "", "lhs_unmark_transition", "pre_unmark_t",
-                # RHS
-                "instantiate", "RHS", "rhs_unmark_transition",
-                "instantiate", "Post_Transition", "post_unmark_t",
-                "attr_add", "post_unmark_t", "label", "0",
-                "attr_add_code", "post_unmark_t", "action", 
-            ] + constructor_unmark_transition_action + [
-                "instantiate", "RHS_contains", "", "rhs_unmark_transition", "post_unmark_t",
-                # Atomic of rule 4 "unmark transition"
-                "instantiate", "Atomic", "unmark_transition",
-                "instantiate", "AtomicLHS", "", "unmark_transition", "lhs_unmark_transition",
-                "instantiate", "AtomicRHS", "", "unmark_transition", "rhs_unmark_transition",
-                # Rule 5: unmark marked places
-                # LHS
-                "instantiate", "LHS", "lhs_unmark_place",
-                "instantiate", "Pre_Place", "pre_unmark_p",
-                "attr_add", "pre_unmark_p", "label", "0",
-                "attr_add_code", "pre_unmark_p", "constraint",
-            ] + constructor_unmark_place_constraint + [
-                "instantiate", "LHS_contains", "", "lhs_unmark_place", "pre_unmark_p",
-                # RHS
-                "instantiate", "RHS", "rhs_unmark_place",
-                "instantiate", "Post_Place", "post_unmark_p",
-                "attr_add", "post_unmark_p", "label", "0",
-                "attr_add_code", "post_unmark_p", "action", 
-            ] + constructor_unmark_place_action + [
-                "instantiate", "RHS_contains", "", "rhs_unmark_place", "post_unmark_p",
-                # Atomic of rule 5 "unmark place"
-                "instantiate", "Atomic", "unmark_place",
-                "instantiate", "AtomicLHS", "", "unmark_place", "lhs_unmark_place",
-                "instantiate", "AtomicRHS", "", "unmark_place", "rhs_unmark_place",
-                # Compose schedule
-                "instantiate", "Composite", "main",
-                "instantiate", "Success", "success",
-                "instantiate", "Failure", "failure",
-                # Add all rules
-                "instantiate", "Contains", "", "main", "success",
-                "instantiate", "Contains", "", "main", "failure",
-                "instantiate", "Contains", "", "main", "mark",
-                "instantiate", "Contains", "", "main", "consume",
-                "instantiate", "Contains", "", "main", "produce",
-                "instantiate", "Contains", "", "main", "unmark_transition",
-                "instantiate", "Contains", "", "main", "unmark_place",
-                # Scheduling order
-                "instantiate", "OnSuccess", "", "mark", "consume",
-                "instantiate", "OnFailure", "", "mark", "success",
-                "instantiate", "OnSuccess", "", "consume", "consume",
-                "instantiate", "OnFailure", "", "consume", "produce",
-                "instantiate", "OnSuccess", "", "produce", "produce",
-                "instantiate", "OnFailure", "", "produce", "unmark_transition",
-                "instantiate", "OnSuccess", "", "unmark_transition", "unmark_place",
-                "instantiate", "OnFailure", "", "unmark_transition", "failure",
-                "instantiate", "OnSuccess", "", "unmark_place", "unmark_place",
-                "instantiate", "OnFailure", "", "unmark_place", "success",
-                # Composite initial
-                "instantiate", "Initial", "", "main", "mark",
-                "exit",
-             "transform", "pn", "pn_simulate",
-             "load", "pn",
-                "list",
-                "verify",
-                "read", "t1",
-                "read", "p1",
-                "read", "p2",
-                "exit",
-                ],
-            None, "PO"))
-
     def test_po_pn_interface_model_transform_pn(self):
         PN_runtime = \
             """
@@ -878,7 +574,6 @@ Void function action(host_model : Element, name : String, mapping : Element):
                 Class Boolean {}
                 Class Place {
                     tokens : Natural
-                    executed : Boolean
                 }
                 Class Transition {
                     executing : Boolean
@@ -901,15 +596,12 @@ Void function action(host_model : Element, name : String, mapping : Element):
             PetriNets_Runtime pn {
                 Place p1 {
                     tokens = 1
-                    executed = False
                 }
                 Place p2 {
                     tokens = 2
-                    executed = False
                 }
                 Place p3 {
                     tokens = 3
-                    executed = False
                 }
                 Transition t1 {
                     executing = False
@@ -1101,13 +793,18 @@ Void function action(host_model : Element, name : String, mapping : Element):
             """
 
         self.assertTrue(run_file(all_files,
-            get_model_constructor(PN_runtime) + \
-                get_model_constructor(PN_model) + [
+            get_model_constructor(PN_runtime) + [
+                ] + get_model_constructor(PN_model) + [
+                "load", "pn", 
+                    "read", "t1",
+                    "read", "p1",
+                    "read", "p2",
+                    "read", "p3",
+                    "exit",
                 "ramify", "PetriNets_Runtime_SCHEDULE", "PetriNets_Runtime",
                 ] + get_model_constructor(schedule_model) + [
                 "transform", "pn", "pn_simulate",
                 "load", "pn",
-                    "list",
                     "verify",
                     "read", "t1",
                     "read", "p1",
@@ -1115,7 +812,23 @@ Void function action(host_model : Element, name : String, mapping : Element):
                     "read", "p3",
                     "exit",
             ],
-          None, "PO"))
+          greeting + prompt * 3 +
+            load + loaded +
+            read_node("t1", "Transition", [], [("executing", "Boolean", False)]) + prompt +
+            read_node("p1", "Place", [], [("tokens", "Natural", 1)]) + prompt +
+            read_node("p2", "Place", [], [("tokens", "Natural", 2)]) + prompt +
+            read_node("p3", "Place", [], [("tokens", "Natural", 3)]) + prompt +
+            prompt +
+            ramify + prompt + 
+            prompt +
+            transform + transform_result_true + prompt +
+            load + loaded +
+            ["OK"] + prompt +
+            read_node("t1", "Transition", [], [("executing", "Boolean", False)]) + prompt +
+            read_node("p1", "Place", [], [("tokens", "Natural", 0)]) + prompt +
+            read_node("p2", "Place", [], [("tokens", "Natural", 1)]) + prompt +
+            read_node("p3", "Place", [], [("tokens", "Natural", 5)]) + prompt, 
+          "PO"))
 
     def test_po_pn_interface_transform_pn_to_runtime(self):
         PN_runtime = \
@@ -1604,4 +1317,22 @@ Void function action(host_model : Element, name : String, mapping : Element):
                 "transform", "pn", "pn_simulate",
                 "transform", "pn", "pn_print",
             ],
-          None, "PO"))
+          greeting + prompt * 3 +
+            unify + prompt +
+            join + prompt +
+            load + loaded +
+            instantiate_edge + prompt +
+            instantiate_edge + prompt +
+            prompt +
+            ramify + prompt +
+            ramify + prompt + 
+            prompt +
+            prompt +
+            prompt +
+            transform + transform_result_true + prompt +
+            split + prompt +
+            transform + [set(['"p1" --> 1', '"p2" --> 2', '"p3" --> 3'])] + transform_result_true + prompt +
+            transform + transform_result_true + prompt +
+            transform + [set(['"p1" --> 0', '"p2" --> 1', '"p3" --> 5'])] + transform_result_true + prompt
+            , 
+          "PO"))

+ 16 - 17
kernel/modelverse_kernel/compiled.py

@@ -304,24 +304,23 @@ def get_superclasses(a, b, **remainder):
 
     while worklist:
         subclass = worklist.pop()
-        if subclass in touched:
-            raise Exception("Loop in Inheritance links")
-        else:
-            touched.add(subclass)
         res = elem_to_name[subclass]
-        yield [("CE", [result, res])]
-
-        outgoing, =      yield [("RO", [subclass])]
-        types =         yield [("RDN", [type_mapping, i]) for i in outgoing]
-
-        for i, t in enumerate(types):
-            if t == inheritance:
-                # Found an inheritance link!
-                elem = outgoing[i]
-                srcdst, = yield [("RE", [elem])]
-                src, dst = srcdst
-                # Find elem in elems
-                worklist.append(dst)
+
+        if subclass not in touched:
+            touched.add(subclass)
+            yield [("CE", [result, res])]
+
+            outgoing, =      yield [("RO", [subclass])]
+            types =         yield [("RDN", [type_mapping, i]) for i in outgoing]
+
+            for i, t in enumerate(types):
+                if t == inheritance:
+                    # Found an inheritance link!
+                    elem = outgoing[i]
+                    srcdst, = yield [("RE", [elem])]
+                    src, dst = srcdst
+                    # Find elem in elems
+                    worklist.append(dst)
 
     raise PrimitiveFinished(result)
 

+ 1 - 1
state/modelverse_state/main.py

@@ -407,4 +407,4 @@ class ModelverseState(object):
                 if v in self.nodes:
                     self.delete_node(v)
 
-        print("Remaining nodes: " + str(len(self.nodes)))
+        #print("Remaining nodes: " + str(len(self.nodes)))