Browse Source

Different iteration over models in many model_management operations

Yentl Van Tendeloo 8 years ago
parent
commit
0304ea6733
1 changed files with 50 additions and 20 deletions
  1. 50 20
      bootstrap/model_management.alc

+ 50 - 20
bootstrap/model_management.alc

@@ -12,6 +12,7 @@ Element function model_fuse(models : Element):
 	String model_name
 	Element model
 	Element keys
+	Element second_keys
 	String key
 	Element selected_MM
 	String type
@@ -22,15 +23,17 @@ Element function model_fuse(models : Element):
 	new_model = instantiate_model(tagged_model[1]["metamodel"])
 
 	// Do the iteration
-	while (read_nr_out(models)):
+	while (read_nr_out(models) > 0):
 		tagged_model = set_pop(models)
 		model_name = string_join(list_read(tagged_model, 0), "/")
 		model = list_read(tagged_model, 1)
 
 		// Add all elements from 'model', but prepend it with the 'model_name'
-		keys = set_to_list(dict_keys(model["model"]))
+		keys = dict_keys(model["model"])
+		second_keys = create_node()
+
 		while (read_nr_out(keys) > 0):
-			key = list_pop(keys, 0)
+			key = set_pop(keys)
 			type = read_type(model, key)
 
 			if (is_edge(model["model"][key])):
@@ -41,25 +44,31 @@ Element function model_fuse(models : Element):
 				if (bool_and(dict_in(new_model["model"], src), dict_in(new_model["model"], dst))):
 					instantiate_link(new_model, type, model_name + key, src, dst)
 				else:
-					list_append(keys, key)
+					set_add(second_keys, key)
 			elif (has_value(model["model"][key])):
 				instantiate_value(new_model, type, model_name + key, model["model"][key])
 			else:
 				instantiate_node(new_model, type, model_name + key)
 
+			if (read_nr_out(keys) == 0):
+				keys = second_keys
+				second_keys = create_node()
+
 	return new_model!
 
 Element function model_copy(src_model : Element):
 	Element dst_model
-	Element queue
 	Element name
+	Element keys
+	Element second_keys
 	String type
 
 	dst_model = instantiate_model(src_model["metamodel"])
-	queue = set_to_list(dict_keys(src_model["model"]))
+	keys = dict_keys(src_model["model"])
+	second_keys = create_node()
 
-	while (read_nr_out(queue) > 0):
-		name = list_pop(queue, 0)
+	while (read_nr_out(keys) > 0):
+		name = set_pop(keys)
 
 		if (is_edge(src_model["model"][name])):
 			// Is an edge, so potentially queue it
@@ -74,7 +83,7 @@ Element function model_copy(src_model : Element):
 				// All present, so create the link between them
 				instantiate_link(dst_model, type, name, src, dst)
 			else:
-				list_append(queue, name)
+				set_add(second_keys, name)
 
 		elif (has_value(src_model["model"][name])):
 			// Has a value, so copy that as well
@@ -86,6 +95,10 @@ Element function model_copy(src_model : Element):
 			type = read_type(src_model, name)
 			instantiate_node(dst_model, type, name)
 
+		if (read_nr_out(keys) == 0):
+			keys = second_keys
+			second_keys = create_node()
+
 	return dst_model!
 
 Element function model_retype_on_name(model : Element, new_MM : Element, operation : String, name : String):
@@ -121,18 +134,22 @@ Element function model_retype_on_name(model : Element, new_MM : Element, operati
 	return model!
 
 Void function model_join(dst_model : Element, src_model : Element, retyping_key : String):
-	Element queue
+	Element keys
+	Element second_keys
 	Element mapping
 	String name
 	String type
 	String src
 	String dst
 
-	queue = set_to_list(dict_keys(src_model["model"]))
 	mapping = create_node()
 
-	while (read_nr_out(queue) > 0):
-		name = list_pop(queue, 0)
+	second_keys = create_node()
+
+	keys = dict_keys(src_model["model"])
+	while (read_nr_out(keys) > 0):
+		name = set_pop(keys)
+		log("Remaining elements: " + cast_i2s(read_nr_out(keys)))
 
 		type = read_type(src_model, name)
 
@@ -148,7 +165,7 @@ Void function model_join(dst_model : Element, src_model : Element, retyping_key
 				// All present, so create the link between them
 				dict_add(mapping, name, instantiate_link(dst_model, retyping_key + type, "", mapping[src], mapping[dst]))
 			else:
-				list_append(queue, name)
+				set_add(second_keys, name)
 
 		elif (has_value(src_model["model"][name])):
 			// Has a value, so copy that as well
@@ -158,6 +175,10 @@ Void function model_join(dst_model : Element, src_model : Element, retyping_key
 			// Is a node
 			dict_add(mapping, name, instantiate_node(dst_model, retyping_key + type, ""))
 
+		if (read_nr_out(keys) == 0):
+			keys = second_keys
+			second_keys = create_node()
+
 	return!
 	
 Element function model_split(src_model : Element, target_metamodel : Element, retyping_key : String):
@@ -165,7 +186,8 @@ Element function model_split(src_model : Element, target_metamodel : Element, re
 
 	dst_model = instantiate_model(target_metamodel)
 
-	Element queue
+	Element keys
+	Element second_keys
 	Element mapping
 	String name
 	String type
@@ -174,12 +196,16 @@ Element function model_split(src_model : Element, target_metamodel : Element, re
 	Integer length
 	String new_type
 
-	queue = set_to_list(dict_keys(src_model["model"]))
 	mapping = create_node()
 	length = string_len(retyping_key)
 
-	while (read_nr_out(queue) > 0):
-		name = list_pop(queue, 0)
+	keys = dict_keys(src_model["model"])
+	second_keys = create_node()
+
+	while (read_nr_out(keys) > 0):
+		name = set_pop(keys)
+
+		log("Remaining elements: " + cast_i2s(read_nr_out(keys)))
 
 		type = read_type(src_model, name)
 		if (string_startswith(type, retyping_key)):
@@ -195,7 +221,7 @@ Element function model_split(src_model : Element, target_metamodel : Element, re
 				if (bool_and(dict_in(mapping, src), dict_in(mapping, dst))):
 					// All present, so create the link between them
 					dict_add(mapping, name, instantiate_link(dst_model, new_type, "", mapping[src], mapping[dst]))
-				elif (bool_not(bool_or(set_in(queue, src), set_in(queue, dst)))):
+				elif (bool_not(bool_or(set_in(keys, src), set_in(keys, dst)))):
 					// Source/target not in the queue, but we need it to split!
 					// This is an error as it indicates problems with links crossing different formalisms
 					log("ERROR: source/target of link to be included is not included!")
@@ -208,7 +234,7 @@ Element function model_split(src_model : Element, target_metamodel : Element, re
 					return create_node()!
 				else:
 					// Still source or destination in the queue, so we wait for that
-					list_append(queue, name)
+					set_add(second_keys, name)
 
 			elif (has_value(src_model["model"][name])):
 				// Has a value, so copy that as well
@@ -218,4 +244,8 @@ Element function model_split(src_model : Element, target_metamodel : Element, re
 				// Is a node
 				dict_add(mapping, name, instantiate_node(dst_model, new_type, ""))
 
+		if (read_nr_out(keys) == 0):
+			keys = second_keys
+			second_keys = create_node()
+
 	return dst_model!