Bläddra i källkod

Lots of fixes to the new set representation

Yentl Van Tendeloo 8 år sedan
förälder
incheckning
544c08519b

+ 0 - 4
bootstrap/bootstrap.py

@@ -66,10 +66,6 @@ def bootstrap():
                     "dict_in": ["Boolean", "Element", "Element"],
                     "dict_in_node": ["Boolean", "Element", "Element"],
                     "dict_keys": ["Element", "Element"],
-                    "set_remove": ["Element", "Element", "Element"],
-                    "set_remove_node": ["Element", "Element", "Element"],
-                    "set_in": ["Boolean", "Element", "Element"],
-                    "set_in_node": ["Boolean", "Element", "Element"],
                     "is_physical_int": ["Boolean", "Element"],
                     "is_physical_boolean": ["Boolean", "Element"],
                     "is_physical_string": ["Boolean", "Element"],

+ 16 - 10
bootstrap/core_algorithm.alc

@@ -200,12 +200,9 @@ String function get_service_id(name : String):
 
 	services = allInstances(core, "Service")
 
-	log("Search " + name)
 	while (set_len(services) > 0):
 		service = set_pop(services)
-		log("Check " + cast_v2s(read_attribute(core, service, "name")))
 		if (value_eq(read_attribute(core, service, "name"), name)):
-			log("Match!")
 			return service!
 	
 	return ""!
@@ -375,7 +372,7 @@ Element function execute_operation(operation_id : String, input_models : Element
 		keys = dict_keys(input_models)
 		while (set_len(keys) > 0):
 			key = set_pop(keys)
-			set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(input_models[key]), get_model_id(input_metamodels[key]))))
+			set_add_node(model_tuples, create_tuple(key, get_full_model(get_model_id(input_models[key]), get_model_id(input_metamodels[key]))))
 
 		merged_model = model_join(model_tuples, get_full_model(merged_metamodel_id, get_model_id("SimpleClassDiagrams")), tracability_model)
 	else:
@@ -425,7 +422,7 @@ Element function execute_operation(operation_id : String, input_models : Element
 		keys = dict_keys(output_models)
 		while (set_len(keys) > 0):
 			key = set_pop(keys)
-			set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(output_models[key]), get_model_id(output_metamodels[key]))))
+			set_add_node(model_tuples, create_tuple(key, get_full_model(get_model_id(output_models[key]), get_model_id(output_metamodels[key]))))
 
 		result = model_split(merged_model, model_tuples, tracability)
 
@@ -1074,7 +1071,7 @@ String function transformation_add(user_id : String, source_models : Element, ta
 			if (allow_read(user_id, model_id)):
 				if (bool_not(dict_in(source, key))):
 					dict_add(source, key, model_id)
-					set_add(formalism_map, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
+					set_add_node(formalism_map, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
 					if (bool_not(set_in(all_formalisms, model_id))):
 						set_add(all_formalisms, model_id)
 				else:
@@ -1093,7 +1090,7 @@ String function transformation_add(user_id : String, source_models : Element, ta
 			if (allow_read(user_id, model_id)):
 				if (bool_not(dict_in(target, key))):
 					dict_add(target, key, model_id)
-					set_add(formalism_map, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
+					set_add_node(formalism_map, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
 					if (bool_not(set_in(all_formalisms, model_id))):
 						set_add(all_formalisms, model_id)
 				else:
@@ -1107,7 +1104,8 @@ String function transformation_add(user_id : String, source_models : Element, ta
 		// Write out a merged metamodel containing all these models: this is the MM for the manual operation
 		// New location is available, so write
 		if (bool_not(bool_and(dict_len(source_models) == 0, dict_len(target_models) == 0))):
-			merged_formalism = model_fuse(set_copy(formalism_map))
+			log("Formalism map: " + list_to_string(formalism_map))
+			merged_formalism = model_fuse(formalism_map)
 			modify(merged_formalism, True)
 
 		if (operation_type == "manual"):
@@ -1195,7 +1193,7 @@ String function cmd_transformation_add_MT(user_id : String, source_models : Elem
 				if (set_len(get_instanceOf_links(model_id, get_model_id("SimpleClassDiagrams"))) > 0):
 					if (bool_not(dict_in(source, key))):
 						dict_add(source, key, model_id)
-						set_add(to_ramify, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
+						set_add_node(to_ramify, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
 					else:
 						return "Name was already assigned a metamodel: " + key!
 				else:
@@ -1222,7 +1220,7 @@ String function cmd_transformation_add_MT(user_id : String, source_models : Elem
 								return "Name in output cannot have different type than input: " + key!
 						else:
 							dict_add(target, key, model_id)
-							set_add(to_ramify, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
+							set_add_node(to_ramify, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
 					else:
 						return "Name was already assigned a metamodel: " + key!
 				else:
@@ -1232,10 +1230,14 @@ String function cmd_transformation_add_MT(user_id : String, source_models : Elem
 		else:
 			return "Model not found: " + name!
 
+	log("FUSE")
 	merged_formalism = model_fuse(to_ramify)
+	log("MODIFY")
 	modify(merged_formalism, True)
+	log("RAMIFY")
 
 	ramified_metamodel = ramify(merged_formalism)
+	log("RAMify OK")
 	model_create(ramified_metamodel, "__RAM_" + operation_name, user_id, get_model_id("SimpleClassDiagrams"), "Model")
 	ramified_metamodel_id = get_model_id("__RAM_" + operation_name)
 	
@@ -1244,9 +1246,11 @@ String function cmd_transformation_add_MT(user_id : String, source_models : Elem
 		String new_model
 		// Finished with all information, now create the model itself!
 		output("Waiting for model constructors...")
+		log("Uploading model")
 		new_model = construct_model_raw(get_full_model(ramified_metamodel_id, get_model_id("SimpleClassDiagrams")))
 		model_create(new_model, operation_name, user_id, ramified_metamodel_id, "ModelTransformation")
 		model_id = get_model_id(operation_name)
+		log("Uploaded model")
 
 		// Write out a merged metamodel containing all these models: this is the MM for the manual operation
 		// New location is available, so write
@@ -1260,6 +1264,7 @@ String function cmd_transformation_add_MT(user_id : String, source_models : Elem
 		// Add tracability links at this level
 		tracability_link = instantiate_link(core, "tracability", "", merged_formalism_id, ramified_metamodel_id)
 		instantiate_attribute(core, tracability_link, "type", "RAMified")
+		log("Tracability OK")
 
 		// Extend metadata with info on source and target
 		String link
@@ -1278,6 +1283,7 @@ String function cmd_transformation_add_MT(user_id : String, source_models : Elem
 			dst = target[key]
 			link = instantiate_link(core, "transformOutput", "", model_id, dst)
 			instantiate_attribute(core, link, "name", key)
+		log("Transform links oK")
 
 		return "Success"!
 	else:

+ 6 - 10
bootstrap/modelling.alc

@@ -174,12 +174,11 @@ Element function get_subclasses(model : Element, name : String):
 
 	// Initialize empty set
 	result = set_create()
-	i = 0
 
-	while (list_len(nodes) > 0):
+	while (set_len(nodes) > 0):
 		elem = set_pop(nodes)
 		if (bool_not(set_in(result, elem))):
-			create_edge(result, elem)
+			set_add(result, elem)
 			// Read out all incoming edges
 			num_edges = read_nr_in(model["model"][elem])
 			j = 0
@@ -188,12 +187,10 @@ Element function get_subclasses(model : Element, name : String):
 				if (value_eq(model["type_mapping"][reverseKeyLookup(model["model"], edge)], "Inheritance")):
 					set_add(nodes, reverseKeyLookup(model["model"], read_edge_src(edge)))
 				j = j + 1
-
 	return result!
 
 Element function get_superclasses(model : Element, name : String):
 	Element result
-	Integer i
 	Integer j
 	Integer num_edges
 	Element edge
@@ -205,12 +202,11 @@ Element function get_superclasses(model : Element, name : String):
 
 	// Initialize empty set
 	result = set_create()
-	i = 0
 
-	while (list_len(nodes) > 0):
+	while (set_len(nodes) > 0):
 		elem = set_pop(nodes)
 		if (bool_not(set_in(result, elem))):
-			create_edge(result, elem)
+			set_add(result, elem)
 			// Read out all outgoing edges
 			num_edges = read_nr_out(model["model"][elem])
 			j = 0
@@ -230,7 +226,7 @@ String function find_attribute_definer(model : Element, elem_name : String, name
 	String name_attr
 
 	superclasses = get_superclasses(model, elem_name)
-	while (list_len(superclasses) > 0):
+	while (set_len(superclasses) > 0):
 		current = set_pop(superclasses)
 		
 		nr_out = read_nr_out(model["model"][current])
@@ -432,7 +428,7 @@ Void function unset_attribute(model : Element, element : String, attribute : Str
 	attr_type = find_attribute_type(model, element, attribute)
 	attr_links = allOutgoingAssociationInstances(model, element, attr_type)
 
-	while (list_len(attr_links) > 0):
+	while (set_len(attr_links) > 0):
 		attr_link = set_pop(attr_links)
 		dict_delete(model["type_mapping"], reverseKeyLookup(model["model"], read_edge_dst(model["model"][attr_link])))
 		dict_delete(model["type_mapping"], attr_link)

+ 2 - 2
bootstrap/object_operations.alc

@@ -211,11 +211,11 @@ Element function allowedAssociationsBetween(model : Element, src : String, dst :
 		i = 0
 		while (i < nr_edges):
 			edge = read_out(model["metamodel"]["model"][type], i)
+			edge_name = reverseKeyLookup(model["metamodel"]["model"], edge)
 
-			if (set_in(model["metamodel"]["model"], edge)):
+			if (dict_in(model["metamodel"]["model"], edge_name)):
 				// Find destination
 				dst_name = reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(edge))
-				edge_name = reverseKeyLookup(model["metamodel"]["model"], edge)
 
 				if (is_nominal_instance(model, dst, dst_name)):
 					// Find out whether our dst is an instance of the found destination type

+ 1 - 2
bootstrap/ramify.alc

@@ -131,10 +131,9 @@ Element function ramify(model : Element):
 			instantiate_link(new_model, "Inheritance", "", "Pre_" + key, "PreElement")
 			instantiate_link(new_model, "Inheritance", "", "Post_" + key, "PostElement")
 
-			i = 0
 			local_copied_attributes = set_copy(copied_attributes)
 			while (set_len(local_copied_attributes) > 0):
-				attr_name = set_pop(copied_attributes)
+				attr_name = set_pop(local_copied_attributes)
 				if (element_neq(read_attribute(model, key, attr_name), read_root())):
 					// Attribute was defined, so reassign in both LHS and RHS
 					instantiate_attribute(new_model, "Pre_" + key, attr_name, read_attribute(model, key, attr_name))

+ 33 - 4
bootstrap/semi_primitives.alc

@@ -22,6 +22,7 @@ Boolean function float_gt(a : Element, b : Element):
 	return bool_or(float_lt(a, b), value_eq(a, b))!
 
 Element function dict_add(a : Element, b : Element, c : Element):
+	log("Doing dict_add for " + cast_v2s(b))
 	create_edge(create_edge(a, c), b)
 	return a!
 
@@ -56,14 +57,22 @@ Element function set_add(a : Element, b : Element):
 		dict_add(a, b, a)
 	return a!
 
+Element function set_add_node(a : Element, b : Element):
+	if (bool_not(set_in_node(a, b))):
+		// Treat set as a dictionary with a mock-value
+		dict_add(a, b, a)
+	return a!
+
 Element function set_pop(a : Element):
+	log("Pop from set!")
 	if (integer_gt(set_len(a), 0)):
 		Element edge
 		Element result
 		edge = read_out(a, 0)
 		result = read_edge_dst(read_out(edge, 0))
 		delete_element(edge)
-		return edge!
+		log("Value: " + cast_v2s(result))
+		return result!
 	else:
 		return read_root()!
 
@@ -180,15 +189,14 @@ Element function list_pop(lst : Element, index : Integer):
 	return v!
 
 Element function set_copy(a : Element):
-	return read_dict_keys(a)!
+	return dict_keys(a)!
 
 String function set_to_string(s : Element):
 	String result
-	Integer i
 
 	result = "{"
 	s = set_copy(s)
-	while (i < set_len(s)):
+	while (set_len(s) > 0):
 		result = (result + cast_v2s(set_pop(s))) + ", "
 	
 	result = result + "}"
@@ -241,6 +249,7 @@ String function dict_to_string(d : Element):
 
 Element function set_overlap(sa : Element, sb : Element):
 	Element result
+	Element elem
 
 	if (set_len(sa) > set_len(sb)):
 		// Pick the smallest set to iterate over, so switch if sa is not the smallest
@@ -392,3 +401,23 @@ Element function reverseKeyLookupMulti(dict : Element, element : Element):
 		counter = counter + 1
 	
 	return result!
+
+Boolean function list_in(list : Element, elem : Element):
+	Integer i
+	i = 0
+	while (i < list_len(list)):
+		if (value_eq(list_read(list, i), elem)):
+			return True!
+		i = i + 1
+	return False!
+
+Element function dict_values(dict : Element):
+	Element result
+	result = set_create()
+
+	Element keys
+	keys = dict_keys(dict)
+	while (set_len(keys) > 0):
+		set_add(result, dict[set_pop(keys)])
+
+	return result!

+ 19 - 8
bootstrap/transform.alc

@@ -33,7 +33,7 @@ Element function make_matching_schedule(schedule_model : Element, LHS : String,
 		// workset is empty, but we still need to add to the list
 		// Therefore, we pick a random, unbound node, and add it to the workset
 		new_element = set_pop(all_elements)
-		while (bool_or(set_in(schedule, new_element), is_edge(schedule_model["model"][new_element]))):
+		while (bool_or(list_in(schedule, new_element), is_edge(schedule_model["model"][new_element]))):
 			// Element is not usable, so pick another one
 			new_element = set_pop(all_elements)
 		set_add(workset, new_element)
@@ -44,7 +44,7 @@ Element function make_matching_schedule(schedule_model : Element, LHS : String,
 			next = set_pop(workset)
 
 			// Check if element might not be already used somewhere
-			if (bool_not(set_in(schedule, next))):
+			if (bool_not(list_in(schedule, next))):
 				if (set_in(full_all_elements, next)):
 					if (bool_not(set_in(ignore, read_attribute(schedule_model, next, "label")))):
 						list_insert(schedule, next, 0)
@@ -152,16 +152,19 @@ Element function get_possible_bindings(host_model : Element, schedule_model : El
 			// Multiple "only" options, which will not work out: no options!
 			return set_create()!
 
+	log("INT1 options: " + set_to_string(options))
 	// Filter options further
 	Element filtered_options
 	String option
 
 	filtered_options = set_create()
+	Element bound
+	bound = dict_values(map)
 	while (set_len(options) > 0):
 		option = set_pop(options)
 
 		// Check for detecting same element twice
-		if (bool_not(set_in(map, option))):
+		if (bool_not(set_in(bound, option))):
 			// Option is already present with another label, so skip this!
 
 			// Check if it conforms to the desired type
@@ -195,6 +198,7 @@ Element function get_possible_bindings(host_model : Element, schedule_model : El
 	Element attributes_copy
 
 	options = filtered_options
+	log("INT2 options: " + set_to_string(options))
 	filtered_options = set_create()
 
 	// Check whether all attributes have a satisfied condition
@@ -226,6 +230,7 @@ Element function get_possible_bindings(host_model : Element, schedule_model : El
 			set_add(filtered_options, option)
 
 	options = filtered_options
+	log("Return options: " + set_to_string(options))
 	return options!
 
 Element function full_match(host_model : Element, schedule_model : Element, current : String, single_ok : Boolean):
@@ -250,6 +255,7 @@ Element function full_match(host_model : Element, schedule_model : Element, curr
 	// For each possible mapping, we check all NACs!
 	while (set_len(mappings) > 0):
 		mapping = set_pop(mappings)
+		log("Got mapping from match: " + dict_to_string(mapping))
 		allowed = True
 		while (set_len(NACs) > 0):
 			NAC = set_pop(NACs)
@@ -260,7 +266,7 @@ Element function full_match(host_model : Element, schedule_model : Element, curr
 				break!
 		
 		if (allowed):
-			set_add(final_mappings, mapping)
+			set_add_node(final_mappings, mapping)
 
 			if (single_ok):
 				break!
@@ -273,6 +279,7 @@ Element function match(host_model : Element, schedule_model : Element, LHS : Str
 	// Make the schedule first
 	Element schedule
 	schedule = make_matching_schedule(schedule_model, LHS, dict_keys(initial_mapping))
+	log("Got schedule: " + list_to_string(schedule))
 
 	// Now follow the schedule, incrementally building all mappings
 	Element mappings
@@ -284,7 +291,7 @@ Element function match(host_model : Element, schedule_model : Element, LHS : Str
 	Element options
 
 	mappings = set_create()
-	set_add(mappings, initial_mapping)
+	set_add_node(mappings, initial_mapping)
 	while (list_len(schedule) > 0):
 		current_element = list_pop(schedule, list_len(schedule) - 1)
 		//log("Binding element with label " + cast_v2s(read_attribute(schedule_model, current_element, "label")))
@@ -293,12 +300,17 @@ Element function match(host_model : Element, schedule_model : Element, LHS : Str
 		while (set_len(mappings) > 0):
 			map = set_pop(mappings)
 			options = get_possible_bindings(host_model, schedule_model, current_element, map)
+			log("Options to bind: " + set_to_string(options))
 
 			while (set_len(options) > 0):
 				option = set_pop(options)
+				log("Pop option: " + option)
 				new_map = dict_copy(map)
+				log("Copied: " + dict_to_string(new_map))
 				dict_add_fast(new_map, read_attribute(schedule_model, current_element, "label"), option)
-				set_add(new_mappings, new_map)
+				log("PRE Got new mapping: " + dict_to_string(new_map))
+				set_add_node(new_mappings, new_map)
+				log("Got new mapping: " + dict_to_string(new_map))
 
 		mappings = new_mappings
 		//log("Remaining options: " + cast_v2s(set_len(mappings)))
@@ -321,7 +333,7 @@ Element function match(host_model : Element, schedule_model : Element, LHS : Str
 			result = func(host_model, map)
 
 			if (result):
-				set_add(new_mappings, map)
+				set_add_node(new_mappings, map)
 		mappings = new_mappings
 
 	return mappings!
@@ -555,4 +567,3 @@ Boolean function transform_query(host_model : Element, schedule_model : Element,
 		return True!
 	else:
 		return False!
-

+ 1 - 0
integration/code/pn_print.mvc

@@ -14,6 +14,7 @@ Composite schedule {
                 label = "0"
                 action = $
                     Void function action(model : Element, name : String, mapping : Element):
+                        log("Got mapping: " + dict_to_string(mapping))
                         output((cast_v2s(read_attribute(model, name, "name")) + " --> ") + cast_v2s(read_attribute(model, name, "tokens")))
                         return!
                     $

+ 3 - 0
interface/HUTN/includes/primitives.alh

@@ -67,7 +67,9 @@ Element function list_append(a: Element, b: Element)
 Element function list_insert(a: Element, b: Element, c: Integer) 
 Element function list_delete(a: Element, b: Integer) 
 Integer function list_len(a: Element) 
+Boolean function list_in(a : Element, b : Element)
 Element function set_add(a: Element, b: Element) 
+Element function set_add_node(a: Element, b: Element) 
 Element function set_pop(a: Element) 
 Element function set_read(a : Element)
 Element function set_remove(a: Element, b: Element) 
@@ -118,3 +120,4 @@ Element function list_create()
 Element function dict_create()
 String function reverseKeyLookup(a: Element, b: Element)
 Element function reverseKeyLookupMulti(a: Element, b: Element)
+Element function dict_values(dict : Element)

+ 2 - 2
kernel/modelverse_jit/intrinsics.py

@@ -299,8 +299,8 @@ MISC_INTRINSICS = {
         tree_ir.ReadDictionaryEdgeInstruction(
             a, tree_ir.ReadValueInstruction(b)),
 
-    'dict_add' : __dict_add,
-    'dict_add_fast' : __dict_add_fast,
+    #'dict_add' : __dict_add,
+    #'dict_add_fast' : __dict_add_fast,
     'dict_len' : __read_nr_out,
 
     # Set operations

+ 21 - 18
kernel/modelverse_kernel/compiled.py

@@ -16,7 +16,8 @@ def reverseKeyLookupMulti(a, b, **remainder):
 
     outgoings = yield [("RO", [edges[i]]) for i in todo]
     values = yield [("RE", [outgoing[0]]) for outgoing in outgoings]
-    yield [("CE", [result, value[1]]) for value in values]
+    edges = yield [("CE", [result, result]) for value in values]
+    yield [("CE", [edge, value[1]]) for edge, value in zip(edges, values)]
 
     #PROFILE print("[COMPILED]reverseKeyLookupMulti : %s : %s" % (time.time() - start, time.time() - start))
     raise PrimitiveFinished(result)
@@ -38,15 +39,6 @@ def reverseKeyLookup(a, b, **remainder):
     #PROFILE print("[COMPILED]reverseKeyLookup : %s : %s" % (time.time() - start, time.time() - start))
     raise PrimitiveFinished(result)
 
-def set_copy(a, **remainder):
-    #PROFILE start = time.time()
-    b, =         yield [("CN", [])]
-    links, =     yield [("RO", [a])]
-    exp_links = yield [("RE", [i]) for i in links]
-    _ =         yield [("CE", [b, i[1]]) for i in exp_links]
-    #PROFILE print("[COMPILED]set_copy : %s : %s" % (time.time() - start, time.time() - start))
-    raise PrimitiveFinished(b)
-
 def instantiated_name(a, b, **remainder):
     #PROFILE start = time.time()
     name_value, = yield [("RV", [b])]
@@ -57,9 +49,9 @@ def instantiated_name(a, b, **remainder):
 
 def set_merge(a, b, **remainder):
     #PROFILE start = time.time()
-    outputs, = yield [("RO", [b])]
-    values = yield [("RE", [i]) for i in outputs]
-    yield [("CE", [a, i[1]]) for i in values]
+    keys, =         yield [("RDK", [b])]
+    edges =         yield [("CE", [a, a]) for key in keys]
+    _ =             yield [("CE", [edge, key]) for edge, key in zip(edges, keys)]
     #PROFILE print("[COMPILED]set_merge : %s : %s" % (time.time() - start, time.time() - start))
     raise PrimitiveFinished(a)
 
@@ -172,17 +164,28 @@ def dict_len(a, **remainder):
 
 def set_add(a, b, **remainder):
     v, =        yield [("RV", [b])]
-    is_in, =    yield [("RD", [a, b])]
+    is_in, =    yield [("RD", [a, v])]
     if not is_in:
         _, =    yield [("CD", [a, v, a])]
     raise PrimitiveFinished(a)
 
+def set_add_node(a, b, **remainder):
+    is_in, =    yield [("RDN", [a, b])]
+    if not is_in:
+        edge, = yield [("CE", [a, a])]
+        _, =    yield [("CE", [edge, b])]
+    raise PrimitiveFinished(a)
+
 def set_pop(a, **remainder):
     outgoing, = yield [("RO", [a])]
     if outgoing:
-        v, _ = yield [("RE", [outgoing[0]]), ("DE", [outgoing[0]])]
-        raise PrimitiveFinished(v[1])
+        outgoing = outgoing[0]
+        new_outgoing, = yield [("RO", [outgoing])]
+        new_outgoing = new_outgoing[0]
+        edge, _ = yield [("RE", [new_outgoing]), ("DE", [outgoing])]
+        raise PrimitiveFinished(edge[1])
     else:
+        raise Exception("POP from empty set")
         print("Pop from empty set!")
         raise PrimitiveFinished(remainder["root"])
 
@@ -200,7 +203,7 @@ def dict_create(**remainder):
 
 def create_tuple(a, b, **remainder):
     result, = yield [("CN", [])]
-    _, _ =    yield [("CD", [result, a]),
-                     ("CD", [result, b]),
+    _, _ =    yield [("CD", [result, 0, a]),
+                     ("CD", [result, 1, b]),
                     ]
     raise PrimitiveFinished(result)

+ 2 - 1
kernel/modelverse_kernel/primitives.py

@@ -314,7 +314,8 @@ def dict_in_node(a, b, **remainder):
 
 def dict_keys(a, **remainder):
     keys, result = yield [("RDK", [a]), ("CN", [])]
-    yield [("CE", [result, v]) for v in keys]
+    edges = yield [("CE", [result, result]) for _ in keys]
+    _ = yield [("CE", [edge, key]) for edge, key in zip(edges, keys)]
     raise PrimitiveFinished(result)
 
 def is_physical_int(a, **remainder):

+ 2 - 1
kernel/test/primitives/test_dict_special.py

@@ -248,7 +248,8 @@ class TestDictSpecials(unittest.TestCase):
         outgoing_links = self.mvs.execute("RO", [returnval])
         received = []
         for l in outgoing_links:
-            src, dst = self.mvs.execute("RE", [l])
+            outgoing_links_2 = self.mvs.execute("RO", [l])
+            src, dst = self.mvs.execute("RE", [outgoing_links_2[0]])
             received.append(self.mvs.execute("RV", [dst]))
 
         self.assertEquals(sorted(received), sorted(result))

+ 0 - 329
kernel/test/primitives/test_set.py

@@ -1,329 +0,0 @@
-import unittest
-from modelverse_kernel.main import ModelverseKernel
-from utils import execute_until_finished, MvSWrapper, get_inst, get_phase, get_returnvalue, get_phase_ref, read_primitive_interfaces, get_returnvalue_ref
-
-class TestSet(unittest.TestCase):
-    def setUp(self):
-        self.mvs = MvSWrapper()
-        self.root = self.mvs.execute("RR", [])
-        self.mvk = ModelverseKernel(self.root)
-
-        self.task_root = self.mvs.execute("CN", [])
-        self.task_frame = self.mvs.execute("CN", [])
-        self.symbols = self.mvs.execute("CN", [])
-        self.evalstack = self.mvs.execute("CN", [])
-        self.returnvalue = self.mvs.execute("CN", [])
-        self.phase = self.mvs.execute("CNV", ["init"])
-
-        self.mvs.execute("CD", [self.root, "task_1", self.task_root])
-        self.mvs.execute("CD", [self.task_root, "frame", self.task_frame])
-        self.mvs.execute("CD", [self.task_frame, "symbols", self.symbols])
-        self.mvs.execute("CD", [self.task_frame, "evalstack", self.evalstack])
-        self.mvs.execute("CD", [self.task_frame, "phase", self.phase])
-        self.mvs.execute("CD", [self.task_frame, "returnvalue", self.returnvalue])
-
-        execute_until_finished(self.mvk, self.mvs, "load_primitives", [])
-        self.primitives = read_primitive_interfaces(self.root, self.mvs)
-
-    def test_remove(self):
-        self.helper_primitives_2_params("set_remove", set([1, 2, 3, 4]), 3, set([1, 2, 4]))
-
-    def test_remove_last(self):
-        self.helper_primitives_2_params("set_remove", set([1]), 1, set([]))
-
-    def test_in_T(self):
-        self.helper_primitives_2_params("set_in", set([1]), 1, True)
-
-    def test_in_T_multi(self):
-        self.helper_primitives_2_params("set_in", set([1, 2, 3]), 1, True)
-
-    def test_in_F(self):
-        self.helper_primitives_2_params("set_in", set([1]), 2, False)
-
-    def test_in_empty(self):
-        self.helper_primitives_2_params("set_in", set([]), 2, False)
-
-    def construct(self, source, lst):
-        for v in lst:
-            t = self.mvs.execute("CNV", [v])
-            self.mvs.execute("CE", [source, t])
-
-    def parse(self, source, expected):
-        if isinstance(expected, set):
-            self.assertEquals(len(self.mvs.execute("RO", [source])), len(expected))
-            s = set()
-            for v in self.mvs.execute("RO", [source]):
-                s.add(self.mvs.execute("RV", [self.mvs.execute("RE", [v])[1]]))
-            self.assertEquals(s, expected)
-        else:
-            self.assertEquals(get_returnvalue(self.root, self.mvs), expected)
-
-    def helper_primitives_2_params(self, operation, a, b, result):
-        self.actual_arg_a = self.mvs.execute("CN", [])
-        self.actual_arg_b = self.mvs.execute("CN", [])
-
-        self.inst = self.mvs.execute("CNV", [{"value":"call"}])
-        self.const_a = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_b = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_c = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_first = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_second = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.value_a = self.mvs.execute("CNV", ["a"])
-        self.value_b = self.mvs.execute("CNV", ["b"])
-        self.value_c = self.mvs.execute("CNV", ["c"])
-        self.value_first = self.mvs.execute("CN", [])
-        self.value_second = self.mvs.execute("CNV", [b])
-
-        self.construct(self.value_first, a)
-
-        self.mvs.execute("CD", [self.task_frame, "IP", self.inst])
-        self.const_func = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.mvs.execute("CD", [self.inst, "func", self.const_func])
-        self.mvs.execute("CD", [self.const_func, "node", self.primitives[operation]])
-        self.mvs.execute("CD", [self.inst, "next", self.const_c])
-        self.mvs.execute("CD", [self.inst, "params", self.actual_arg_a])
-        self.mvs.execute("CD", [self.actual_arg_a, "next_param", self.actual_arg_b])
-        self.mvs.execute("CD", [self.inst, "last_param", self.actual_arg_b])
-        self.mvs.execute("CD", [self.actual_arg_a, "value", self.const_first])
-        self.mvs.execute("CD", [self.actual_arg_b, "value", self.const_second])
-        self.mvs.execute("CD", [self.actual_arg_a, "name", self.value_a])
-        self.mvs.execute("CD", [self.actual_arg_b, "name", self.value_b])
-        self.mvs.execute("CD", [self.const_a, "node", self.value_a])
-        self.mvs.execute("CD", [self.const_b, "node", self.value_b])
-        self.mvs.execute("CD", [self.const_c, "node", self.value_c])
-        self.mvs.execute("CD", [self.const_first, "node", self.value_first])
-        self.mvs.execute("CD", [self.const_second, "node", self.value_second])
-
-        ### Execute rules
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase_ref(self.root, self.mvs), self.actual_arg_a)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        self.assertEquals(get_returnvalue_ref(self.root, self.mvs), self.value_first)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase_ref(self.root, self.mvs), self.actual_arg_b)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        self.assertEquals(get_returnvalue(self.root, self.mvs), b)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "call")
-        execute_until_finished(self.mvk, self.mvs)
-
-        # Body points to empty instruction, as it is a primitive
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        # This will have triggered the primitive, so now we are back where we left off
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.parse(self.value_first, result)
-
-    def helper_primitives_1_params(self, operation, a, result):
-        self.actual_arg_a = self.mvs.execute("CN", [])
-
-        self.inst = self.mvs.execute("CNV", [{"value":"call"}])
-        self.const_a = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_b = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_c = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_first = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.value_a = self.mvs.execute("CNV", ["a"])
-        self.value_b = self.mvs.execute("CNV", ["b"])
-        self.value_c = self.mvs.execute("CNV", ["c"])
-        self.value_first = self.mvs.execute("CN", [])
-
-        self.mvs.execute("CD", [self.task_frame, "IP", self.inst])
-        self.const_func = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.mvs.execute("CD", [self.inst, "func", self.const_func])
-        self.mvs.execute("CD", [self.const_func, "node", self.primitives[operation]])
-        self.mvs.execute("CD", [self.inst, "next", self.const_c])
-        self.mvs.execute("CD", [self.inst, "params", self.actual_arg_a])
-        self.mvs.execute("CD", [self.inst, "last_param", self.actual_arg_a])
-        self.mvs.execute("CD", [self.actual_arg_a, "value", self.const_first])
-        self.mvs.execute("CD", [self.actual_arg_a, "name", self.value_a])
-        self.mvs.execute("CD", [self.const_a, "node", self.value_a])
-        self.mvs.execute("CD", [self.const_b, "node", self.value_b])
-        self.mvs.execute("CD", [self.const_c, "node", self.value_c])
-        self.mvs.execute("CD", [self.const_first, "node", self.value_first])
-
-        self.construct(self.value_first, a)
-
-        ### Execute rules
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase_ref(self.root, self.mvs), self.actual_arg_a)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        self.assertEquals(get_returnvalue_ref(self.root, self.mvs), self.value_first)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "call")
-        execute_until_finished(self.mvk, self.mvs)
-
-        # Body points to empty instruction, as it is a primitive
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        # This will have triggered the primitive, so now we are back where we left off
-        # Just check whether or not the correct value is in the returnvalue to be used
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-
-        self.parse(self.value_first, result)
-
-    def helper_primitives_3_params(self, operation, a, b, c, result):
-        self.actual_arg_a = self.mvs.execute("CN", [])
-        self.actual_arg_b = self.mvs.execute("CN", [])
-        self.actual_arg_c = self.mvs.execute("CN", [])
-
-        self.inst = self.mvs.execute("CNV", [{"value":"call"}])
-        self.const_a = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_b = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_c = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_first = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_second = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_third = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.value_a = self.mvs.execute("CNV", ["a"])
-        self.value_b = self.mvs.execute("CNV", ["b"])
-        self.value_c = self.mvs.execute("CNV", ["c"])
-        self.value_first = self.mvs.execute("CN", [])
-        self.value_second = self.mvs.execute("CNV", [b])
-        self.value_third = self.mvs.execute("CNV", [c])
-
-        self.mvs.execute("CD", [self.task_frame, "IP", self.inst])
-        self.const_func = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.mvs.execute("CD", [self.inst, "func", self.const_func])
-        self.mvs.execute("CD", [self.const_func, "node", self.primitives[operation]])
-        self.mvs.execute("CD", [self.inst, "next", self.const_c])
-        self.mvs.execute("CD", [self.inst, "params", self.actual_arg_a])
-        self.mvs.execute("CD", [self.actual_arg_a, "next_param", self.actual_arg_b])
-        self.mvs.execute("CD", [self.actual_arg_b, "next_param", self.actual_arg_c])
-        self.mvs.execute("CD", [self.inst, "last_param", self.actual_arg_c])
-        self.mvs.execute("CD", [self.actual_arg_a, "value", self.const_first])
-        self.mvs.execute("CD", [self.actual_arg_b, "value", self.const_second])
-        self.mvs.execute("CD", [self.actual_arg_c, "value", self.const_third])
-        self.mvs.execute("CD", [self.actual_arg_a, "name", self.value_a])
-        self.mvs.execute("CD", [self.actual_arg_b, "name", self.value_b])
-        self.mvs.execute("CD", [self.actual_arg_c, "name", self.value_c])
-        self.mvs.execute("CD", [self.const_a, "node", self.value_a])
-        self.mvs.execute("CD", [self.const_b, "node", self.value_b])
-        self.mvs.execute("CD", [self.const_c, "node", self.value_c])
-        self.mvs.execute("CD", [self.const_first, "node", self.value_first])
-        self.mvs.execute("CD", [self.const_second, "node", self.value_second])
-        self.mvs.execute("CD", [self.const_third, "node", self.value_third])
-
-        self.construct(self.value_first, a)
-
-        ### Execute rules
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase_ref(self.root, self.mvs), self.actual_arg_a)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        self.assertEquals(get_returnvalue_ref(self.root, self.mvs), self.value_first)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase_ref(self.root, self.mvs), self.actual_arg_b)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        self.assertEquals(get_returnvalue(self.root, self.mvs), b)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase_ref(self.root, self.mvs), self.actual_arg_c)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        self.assertEquals(get_returnvalue(self.root, self.mvs), c)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "call")
-        execute_until_finished(self.mvk, self.mvs)
-
-        # Body points to empty instruction, as it is a primitive
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        # This will have triggered the primitive, so now we are back where we left off
-        # Just check whether or not the correct value is in the returnvalue to be used
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-
-        self.parse(self.value_first, result)

+ 0 - 165
kernel/test/primitives/test_set_node.py

@@ -1,165 +0,0 @@
-import unittest
-from modelverse_kernel.main import ModelverseKernel
-from utils import execute_until_finished, MvSWrapper, get_inst, get_phase, get_returnvalue, get_phase_ref, read_primitive_interfaces, get_returnvalue_ref
-
-class TestSetNode(unittest.TestCase):
-    def setUp(self):
-        self.mvs = MvSWrapper()
-        self.root = self.mvs.execute("RR", [])
-        self.mvk = ModelverseKernel(self.root)
-
-        self.task_root = self.mvs.execute("CN", [])
-        self.task_frame = self.mvs.execute("CN", [])
-        self.symbols = self.mvs.execute("CN", [])
-        self.evalstack = self.mvs.execute("CN", [])
-        self.returnvalue = self.mvs.execute("CN", [])
-        self.phase = self.mvs.execute("CNV", ["init"])
-
-        self.mvs.execute("CD", [self.root, "task_1", self.task_root])
-        self.mvs.execute("CD", [self.task_root, "frame", self.task_frame])
-        self.mvs.execute("CD", [self.task_frame, "symbols", self.symbols])
-        self.mvs.execute("CD", [self.task_frame, "evalstack", self.evalstack])
-        self.mvs.execute("CD", [self.task_frame, "phase", self.phase])
-        self.mvs.execute("CD", [self.task_frame, "returnvalue", self.returnvalue])
-
-        execute_until_finished(self.mvk, self.mvs, "load_primitives", [])
-        self.primitives = read_primitive_interfaces(self.root, self.mvs)
-
-    def test_remove(self):
-        n = self.mvs.execute("CN", [])
-        a = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, a])
-        b = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, b])
-        c = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, c])
-        self.helper_primitives_2_params("set_remove_node", n, b, set([a, c]))
-
-    def test_remove_last(self):
-        n = self.mvs.execute("CN", [])
-        a = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, a])
-        self.helper_primitives_2_params("set_remove_node", n, a, set([]))
-
-    def test_in_T(self):
-        n = self.mvs.execute("CN", [])
-        a = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, a])
-        b = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, b])
-        c = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, c])
-        self.helper_primitives_2_params("set_in_node", n, c, True)
-
-    def test_in_F(self):
-        n = self.mvs.execute("CN", [])
-        a = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, a])
-        b = self.mvs.execute("CN", [])
-        self.mvs.execute("CE", [n, b])
-        c = self.mvs.execute("CN", [])
-        self.helper_primitives_2_params("set_in_node", n, c, False)
-
-    def test_in_empty(self):
-        n = self.mvs.execute("CN", [])
-        c = self.mvs.execute("CN", [])
-        self.helper_primitives_2_params("set_in_node", n, c, False)
-
-    def parse(self, source, expected):
-        if isinstance(expected, set):
-            self.assertEquals(len(self.mvs.execute("RO", [source])), len(expected))
-            s = set()
-            for v in self.mvs.execute("RO", [source]):
-                s.add(self.mvs.execute("RE", [v])[1])
-            self.assertEquals(s, expected)
-        else:
-            self.assertEquals(get_returnvalue(self.root, self.mvs), expected)
-
-    def helper_primitives_2_params(self, operation, a, b, result):
-        self.actual_arg_a = self.mvs.execute("CN", [])
-        self.actual_arg_b = self.mvs.execute("CN", [])
-
-        self.inst = self.mvs.execute("CNV", [{"value":"call"}])
-        self.const_a = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_b = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_c = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_first = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.const_second = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.value_a = self.mvs.execute("CNV", ["a"])
-        self.value_b = self.mvs.execute("CNV", ["b"])
-        self.value_c = self.mvs.execute("CNV", ["c"])
-        self.value_first = self.mvs.execute("CN", [])
-        self.value_second = b
-
-        self.value_first = a
-
-        self.mvs.execute("CD", [self.task_frame, "IP", self.inst])
-        self.const_func = self.mvs.execute("CNV", [{"value":"constant"}])
-        self.mvs.execute("CD", [self.inst, "func", self.const_func])
-        self.mvs.execute("CD", [self.const_func, "node", self.primitives[operation]])
-        self.mvs.execute("CD", [self.inst, "next", self.const_c])
-        self.mvs.execute("CD", [self.inst, "params", self.actual_arg_a])
-        self.mvs.execute("CD", [self.actual_arg_a, "next_param", self.actual_arg_b])
-        self.mvs.execute("CD", [self.inst, "last_param", self.actual_arg_b])
-        self.mvs.execute("CD", [self.actual_arg_a, "value", self.const_first])
-        self.mvs.execute("CD", [self.actual_arg_b, "value", self.const_second])
-        self.mvs.execute("CD", [self.actual_arg_a, "name", self.value_a])
-        self.mvs.execute("CD", [self.actual_arg_b, "name", self.value_b])
-        self.mvs.execute("CD", [self.const_a, "node", self.value_a])
-        self.mvs.execute("CD", [self.const_b, "node", self.value_b])
-        self.mvs.execute("CD", [self.const_c, "node", self.value_c])
-        self.mvs.execute("CD", [self.const_first, "node", self.value_first])
-        self.mvs.execute("CD", [self.const_second, "node", self.value_second])
-
-        ### Execute rules
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase_ref(self.root, self.mvs), self.actual_arg_a)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        self.assertEquals(get_returnvalue_ref(self.root, self.mvs), self.value_first)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase_ref(self.root, self.mvs), self.actual_arg_b)
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "constant")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "call")
-        execute_until_finished(self.mvk, self.mvs)
-
-        # Body points to empty instruction, as it is a primitive
-        self.assertEquals(get_phase(self.root, self.mvs), "init")
-        execute_until_finished(self.mvk, self.mvs)
-
-        # This will have triggered the primitive, so now we are back where we left off
-        self.assertEquals(get_inst(self.root, self.mvs), "call")
-        self.assertEquals(get_phase(self.root, self.mvs), "finish")
-        execute_until_finished(self.mvk, self.mvs)
-
-        self.parse(self.value_first, result)

+ 4 - 4
models/pn_print.alc

@@ -12,7 +12,7 @@ Boolean function pn_print(model : Element):
 
 	log("Places:")
 	all_places = allInstances(model, "PetriNet/Place")
-	while (read_nr_out(all_places) > 0):
+	while (set_len(all_places) > 0):
 		place = set_pop(all_places)
 		name = read_attribute(model, place, "name")
 		tokens = read_attribute(model, place, "tokens")
@@ -21,19 +21,19 @@ Boolean function pn_print(model : Element):
 
 	log("Transitions:")
 	all_places = allInstances(model, "PetriNet/Transition")
-	while (read_nr_out(all_places) > 0):
+	while (set_len(all_places) > 0):
 		place = set_pop(all_places)
 		name = read_attribute(model, place, "name")
 
 		log("  " + name)
 
 		all_t = allIncomingAssociationInstances(model, place, "PetriNet/P2T")
-		while (read_nr_out(all_t) > 0):
+		while (set_len(all_t) > 0):
 			t = set_pop(all_t)
 			log("    <-- " + cast_v2s(read_attribute(model, readAssociationSource(model, t), "name")))
 
 		all_t = allOutgoingAssociationInstances(model, place, "PetriNet/T2P")
-		while (read_nr_out(all_t) > 0):
+		while (set_len(all_t) > 0):
 			t = set_pop(all_t)
 			log("    --> " + cast_v2s(read_attribute(model, readAssociationDestination(model, t), "name")))
 

+ 1 - 0
scripts/run_local_modelverse.py

@@ -15,6 +15,7 @@ program_to_execute = [sys.executable, "run_mvk_server.py", port]
 
 # Alternative execution modes
 #program_to_execute = [sys.executable, "-m", "cProfile", "-s", "tottime", "run_mvk_server.py", port]
+#program_to_execute = [sys.executable, "run_mvk_server.py", port, "--kernel=interpreter"]
 
 if os.name == "nt":
     subprocess.call(program_to_execute)