Browse Source

Patched model_join code and invocation for multiple models simultaneously; thus also improving performance considerably

Yentl Van Tendeloo 8 years ago
parent
commit
f17b28080b

+ 64 - 35
bootstrap/model_management.alc

@@ -140,56 +140,85 @@ 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 function model_join(models : Element, metamodel : Element, tracability_model : Element):
+	Element new_model
+	Element tagged_model
+	String retyping_key
+	Element elem_map
+	Element model
 	Element keys
+	String new_name
 	Element second_keys
-	Element mapping
-	String name
-	String type
 	String src
 	String dst
-	Element elem
+	String key
+	String type
 
-	mapping = create_node()
+	new_model = instantiate_model(metamodel)
+	elem_map = create_node()
 
-	second_keys = create_node()
+	// Do the iteration
+	while (read_nr_out(models) > 0):
+		tagged_model = set_pop(models)
+		retyping_key = string_join(list_read(tagged_model, 0), "/")
+		model = list_read(tagged_model, 1)
 
-	Element reverse
-	reverse = make_reverse_dictionary(src_model["model"])
+		// Add all elements from 'model'
+		keys = dict_keys(model["model"])
+		second_keys = create_node()
 
-	keys = dict_keys(src_model["model"])
-	while (read_nr_out(keys) > 0):
-		name = set_pop(keys)
-		elem = src_model["model"][name]
-		type = read_type(src_model, name)
+		while (read_nr_out(keys) > 0):
+			// Copy the new element
+			key = set_pop(keys)
+			type = read_type(model, key)
 
-		if (is_edge(elem)):
-			// Is an edge, so potentially queue it
-			String src
-			String dst
+			if (is_edge(model["model"][key])):
+				src = cast_id2s(read_edge_src(model["model"][key]))
+				dst = cast_id2s(read_edge_dst(model["model"][key]))
+				if (bool_and(dict_in(elem_map, src), dict_in(elem_map, dst))):
+					new_name = instantiate_link(new_model, retyping_key + type, "", elem_map[src], elem_map[dst])
+				else:
+					set_add(second_keys, key)
+					new_name = ""
+			elif (has_value(model["model"][key])):
+				new_name = instantiate_value(new_model, retyping_key + type, "", model["model"][key])
+			else:
+				new_name = instantiate_node(new_model, retyping_key + type, "")
 
-			src = reverse[cast_id2s(read_edge_src(elem))]
-			dst = reverse[cast_id2s(read_edge_dst(elem))]
+			if (new_name != ""):
+				// Add the new name to a map which registers the mapping to the new name
+				dict_add_fast(elem_map, cast_id2s(model["model"][key]), new_name)
 
-			if (bool_and(dict_in(mapping, src), dict_in(mapping, dst))):
-				// All present, so create the link between them
-				dict_add_fast(mapping, name, instantiate_link(dst_model, retyping_key + type, "", mapping[src], mapping[dst]))
-			else:
-				set_add(second_keys, name)
+			if (read_nr_out(keys) == 0):
+				keys = second_keys
+				second_keys = create_node()
 
-		elif (has_value(elem)):
-			// Has a value, so copy that as well
-			dict_add_fast(mapping, name, instantiate_value(dst_model, retyping_key + type, "", elem))
+	// Now link in the tracability model
+	// Go over all TracabilityLink elements and connect them in the merged model as well
 
-		else:
-			// Is a node
-			dict_add_fast(mapping, name, instantiate_node(dst_model, retyping_key + type, ""))
+	if (element_neq(tracability_model, read_root())):
+		Element tracability_links
+		String tracability_link
+		String new_name_src
+		String new_name_dst
 
-		if (read_nr_out(keys) == 0):
-			keys = second_keys
-			second_keys = create_node()
+		tracability_links = allInstances(tracability_model, "TracabilityLink")
+
+		while (read_nr_out(tracability_links) > 0):
+			tracability_link = set_pop(tracability_links)
+
+			// Get necessary information from the tracability link
+			new_name_src = elem_map[cast_id2s(read_edge_src(tracability_model["model"][tracability_link]))]
+			new_name_dst = elem_map[cast_id2s(read_edge_dst(tracability_model["model"][tracability_link]))]
+			type = read_attribute(tracability_model, tracability_link, "type")
 
-	return!
+			// Connect the two with the info we have
+			new_name = instantiate_link(new_model, type, "", new_name_src, new_name_dst)
+
+			if (new_name == ""):
+				log("ERROR: could not create a tracability link; ignoring")
+
+	return new_model!
 	
 Element function model_split(src_model : Element, target_metamodel : Element, retyping_key : String):
 	Element dst_model

+ 20 - 7
core/core_algorithm.alc

@@ -552,18 +552,19 @@ Boolean function enact_action(pm : Element, element : String, prefix : String, u
 				merged_metamodel_id = readAssociationDestination(core, trace_link_id)
 
 		if (merged_metamodel_id != ""):
-			merged_model = instantiate_model(get_full_model(merged_metamodel_id))
-
 			// 2) Merge source models
 			String key
-			Element keys
 			Element input_keys
 			Element output_keys
+			Element model_tuples
 
+			model_tuples = create_node()
 			input_keys = dict_keys(inputs)
 			while (read_nr_out(input_keys) > 0):
 				key = set_pop(input_keys)
-				model_join(merged_model, get_full_model(get_model_id(inputs[key])), string_join(types[key], "/"))
+				set_add(model_tuples, create_tuple(types[key], get_full_model(get_model_id(inputs[key]))))
+
+			merged_model = model_join(model_tuples, get_full_model(merged_metamodel_id), read_root())
 
 			// 3) Transform
 			result = transform(merged_model, schedule_model)
@@ -650,11 +651,15 @@ Boolean function enact_action(pm : Element, element : String, prefix : String, u
 			Element keys
 			Element input_keys
 			Element output_keys
+			Element model_tuples
 
+			model_tuples = create_node()
 			input_keys = dict_keys(inputs)
 			while (read_nr_out(input_keys) > 0):
 				key = set_pop(input_keys)
-				model_join(merged_model, get_full_model(get_model_id(inputs[key])), string_join(types[key], "/"))
+				set_add(model_tuples, create_tuple(types[key], get_full_model(get_model_id(inputs[key]))))
+
+			merged_model = model_join(model_tuples, get_full_model(merged_metamodel_id), read_root())
 
 			// 3) Transform
 
@@ -984,11 +989,15 @@ Void function user_function_skip_init(user_id : String):
 								Element keys
 								Element input_keys
 								Element output_keys
+								Element model_tuples
 
+								model_tuples = create_node()
 								input_keys = dict_keys(inputs)
 								while (read_nr_out(input_keys) > 0):
 									key = set_pop(input_keys)
-									model_join(merged_model, get_full_model(get_model_id(inputs[key])), key + "/")
+									set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(inputs[key]))))
+
+								merged_model = model_join(model_tuples, get_full_model(merged_metamodel_id), read_root())
 
 								// 3) Transform
 
@@ -1075,11 +1084,15 @@ Void function user_function_skip_init(user_id : String):
 								Element keys
 								Element input_keys
 								Element output_keys
+								Element model_tuples
 
+								model_tuples = create_node()
 								input_keys = dict_keys(inputs)
 								while (read_nr_out(input_keys) > 0):
 									key = set_pop(input_keys)
-									model_join(merged_model, get_full_model(get_model_id(inputs[key])), key + "/")
+									set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(inputs[key]))))
+
+								merged_model = model_join(model_tuples, get_full_model(merged_metamodel_id), read_root())
 
 								// 3) Transform
 

+ 1 - 1
interface/HUTN/includes/model_management.alh

@@ -1,5 +1,5 @@
 Element function model_fuse(models : Element)
 Element function model_copy(model : Element)
 Element function model_retype_on_name(model : Element, new_MM : Element, operation : String, name : String)
-Void function model_join(target_model : Element, source_model : Element, retyping_key : String)
+Element function model_join(models : Element, metamodel : Element, tracability : Element)
 Element function model_split(source_model : Element, target_metamodel : Element, retyping_key : String)