浏览代码

Fixed model_split to run in a single iteration

Yentl Van Tendeloo 8 年之前
父节点
当前提交
015b7d6666
共有 3 个文件被更改,包括 123 次插入85 次删除
  1. 64 48
      bootstrap/model_management.alc
  2. 58 36
      core/core_algorithm.alc
  3. 1 1
      interface/HUTN/includes/model_management.alh

+ 64 - 48
bootstrap/model_management.alc

@@ -220,68 +220,84 @@ Element function model_join(models : Element, metamodel : Element, tracability_m
 
 	return new_model!
 	
-Element function model_split(src_model : Element, target_metamodel : Element, retyping_key : String):
-	Element dst_model
-
-	dst_model = instantiate_model(target_metamodel)
-
+Element function model_split(merged_model : Element, models : Element):
+	Element result
+	Element metamodel
+	Element model_tuple
+	Element tracability_model
 	Element keys
-	Element second_keys
-	Element mapping
-	String name
-	String type
+	String key
 	String src
 	String dst
-	Integer length
-	String new_type
+	Element reverse
+	Element mapping
+	String retyping_key
+	String original_type
 	Element elem
+	Element second_keys
+	String type
+	Element splitted
 
+	result = create_node()
+	tracability_model = instantiate_model(import_node("models/Tracability"))
+	reverse = make_reverse_dictionary(merged_model["model"])
 	mapping = create_node()
-	length = string_len(retyping_key)
-
 	second_keys = create_node()
 
-	Element reverse
-	reverse = make_reverse_dictionary(src_model["model"])
+	while (read_nr_out(models) > 0):
+		model_tuple = set_pop(models)
+		retyping_key = model_tuple[0]
+		metamodel = model_tuple[1]
+		dict_add_fast(result, retyping_key, instantiate_model(metamodel))
 
-	keys = dict_keys(src_model["model"])
+	keys = dict_keys(merged_model["model"])
 	while (read_nr_out(keys) > 0):
-		name = set_pop(keys)
-		elem = src_model["model"][name]
-
-		type = read_type(src_model, name)
-		if (string_startswith(type, retyping_key)):
-			new_type = string_substr(type, length, string_len(type))
-			if (is_edge(elem)):
-				// Is an edge, so potentially queue it
-				String src
-				String dst
+		key = set_pop(keys)
+		type = read_type(merged_model, key)
+		splitted = string_split(type, "/")
+
+		if (list_len(splitted) == 1):
+			// Only one, so no split possible
+			// Indicates a tracability element!
+			key = ""
+			log("TRACABILITY: ignoring for now")
+		else:
+			retyping_key = splitted[0]
+
+			if (dict_in(result, retyping_key)):
+				original_type = splitted[1]
+				elem = merged_model["model"][key]
+
+				if (is_edge(elem)):
+					// Is an edge, so potentially queue it
+					src = reverse[cast_id2s(read_edge_src(elem))]
+					dst = reverse[cast_id2s(read_edge_dst(elem))]
+
+					if (bool_and(dict_in(mapping, src), dict_in(mapping, dst))):
+						// All present, so create the link between them
+						// Though we first check the model to which it was mapped, as this should be the same as we have now
+						if (bool_and(dict_in(result[retyping_key]["model"], mapping[src]), dict_in(result[retyping_key]["model"], mapping[dst]))):
+							// The matching worked fine
+							dict_add_fast(mapping, key, instantiate_link(result[retyping_key], original_type, "", mapping[src], mapping[dst]))
+						else:
+							log("ERROR mapping: source/target mapped to model, but not found in expected model; ignoring")
+					else:
+						// Still source or destination in the queue, so we wait for that
+						set_add(second_keys, key)
+
+				elif (has_value(elem)):
+					// Has a value, so copy that as well
+					dict_add_fast(mapping, key, instantiate_value(result[retyping_key], original_type, "", elem))
 
-				src = reverse[cast_id2s(read_edge_src(elem))]
-				dst = reverse[cast_id2s(read_edge_dst(elem))]
-
-				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, new_type, "", mapping[src], mapping[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!")
-					return create_node()!
 				else:
-					// Still source or destination in the queue, so we wait for that
-					set_add(second_keys, name)
-
-			elif (has_value(elem)):
-				// Has a value, so copy that as well
-				dict_add_fast(mapping, name, instantiate_value(dst_model, new_type, "", elem))
-
-			else:
-				// Is a node
-				dict_add_fast(mapping, name, instantiate_node(dst_model, new_type, ""))
+					// Is a node
+					dict_add_fast(mapping, key, instantiate_node(result[retyping_key], original_type, ""))
 
 		if (read_nr_out(keys) == 0):
 			keys = second_keys
 			second_keys = create_node()
 
-	return dst_model!
+	// Finally, we also add tracability information as a separate model
+	//dict_add_fast(result, "__tracability", tracability_model)
+
+	return result!

+ 58 - 36
core/core_algorithm.alc

@@ -571,22 +571,35 @@ Boolean function enact_action(pm : Element, element : String, prefix : String, u
 			log("Transformation result: " + cast_b2s(result))
 
 			// 4) Split in different files depending on type
-			String desired_metamodel_id
-			Element split_off_model
-
+			model_tuples = create_node()
 			output_keys = dict_keys(outputs)
+
 			while (read_nr_out(output_keys) > 0):
 				key = set_pop(output_keys)
-				desired_metamodel_id = get_model_id(key)
-				split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/")
+				set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(key))))
 
-				// Check if the destination model already exists
+			Element splitted_models
+			splitted_models = model_split(merged_model, model_tuples)
+
+			Element keys
+			keys = dict_keys(splitted_models)
+			log("SPLITTED OK")
+			while (read_nr_out(keys) > 0):
+				key = set_pop(keys)
+				log("Write out model: " + key)
+				log("Data: " + cast_e2s(splitted_models[key]))
+				
 				if (get_model_id(outputs[key]) == ""):
 					// New model
-					model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model")
+					log("New model")
+					log("Outputs: " + cast_e2s(outputs[key]))
+					log("Model ID: " + cast_e2s(get_model_id(key)))
+					model_create(splitted_models[key], outputs[key], user_id, get_model_id(key), "Model")
 				else:
-					// Model exists, so we overwrite
-					model_overwrite(split_off_model, get_model_id(outputs[key]))
+					log("Existing model")
+					log("Value: " + cast_e2s(get_model_id(outputs[key])))
+					model_overwrite(splitted_models[key], get_model_id(outputs[key]))
+
 		else:
 			log("Intermediate not found")
 
@@ -668,22 +681,25 @@ Boolean function enact_action(pm : Element, element : String, prefix : String, u
 
 			// 4) Split in different files depending on type
 
-			String desired_metamodel_id
-			Element split_off_model
-
+			model_tuples = create_node()
 			output_keys = dict_keys(outputs)
+
 			while (read_nr_out(output_keys) > 0):
 				key = set_pop(output_keys)
-				desired_metamodel_id = get_model_id(key)
-				split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/")
+				set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(key))))
 
-				// Check if the destination model already exists
+			Element splitted_models
+			splitted_models = model_split(merged_model, model_tuples)
+
+			keys = dict_keys(splitted_models)
+			while (read_nr_out(keys) > 0):
+				key = set_pop(keys)
+				
 				if (get_model_id(outputs[key]) == ""):
 					// New model
-					model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model")
+					model_create(splitted_models[key], outputs[key], user_id, get_model_id(key), "Model")
 				else:
-					// Model exists, so we overwrite
-					model_overwrite(split_off_model, get_model_id(outputs[key]))
+					model_overwrite(splitted_models[key], get_model_id(outputs[key]))
 		else:
 			output("Could not find merged metamodel")
 
@@ -1006,22 +1022,25 @@ Void function user_function_skip_init(user_id : String):
 
 								// 4) Split in different files depending on type
 
-								String desired_metamodel_id
-								Element split_off_model
-
+								model_tuples = create_node()
 								output_keys = dict_keys(outputs)
+
 								while (read_nr_out(output_keys) > 0):
 									key = set_pop(output_keys)
-									desired_metamodel_id = get_model_id(key)
-									split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/")
+									set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(key))))
 
-									// Check if the destination model already exists
+								Element splitted_models
+								splitted_models = model_split(merged_model, model_tuples)
+
+								keys = dict_keys(splitted_models)
+								while (read_nr_out(keys) > 0):
+									key = set_pop(keys)
+									
 									if (get_model_id(outputs[key]) == ""):
 										// New model
-										model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model")
+										model_create(splitted_models[key], outputs[key], user_id, get_model_id(key), "Model")
 									else:
-										// Model exists, so we overwrite
-										model_overwrite(split_off_model, get_model_id(outputs[key]))
+										model_overwrite(splitted_models[key], get_model_id(outputs[key]))
 							else:
 								output("Could not resolve intermediate merged metamodel")
 
@@ -1100,22 +1119,25 @@ Void function user_function_skip_init(user_id : String):
 
 								// 4) Split in different files depending on type
 
-								String desired_metamodel_id
-								Element split_off_model
-
+								model_tuples = create_node()
 								output_keys = dict_keys(outputs)
+
 								while (read_nr_out(output_keys) > 0):
 									key = set_pop(output_keys)
-									desired_metamodel_id = get_model_id(key)
-									split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/")
+									set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(key))))
+
+								Element splitted_models
+								splitted_models = model_split(merged_model, model_tuples)
 
-									// Check if the destination model already exists
+								keys = dict_keys(splitted_models)
+								while (read_nr_out(keys) > 0):
+									key = set_pop(keys)
+									
 									if (get_model_id(outputs[key]) == ""):
 										// New model
-										model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model")
+										model_create(splitted_models[key], outputs[key], user_id, get_model_id(key), "Model")
 									else:
-										// Model exists, so we overwrite
-										model_overwrite(split_off_model, get_model_id(outputs[key]))
+										model_overwrite(splitted_models[key], get_model_id(outputs[key]))
 							else:
 								output("Could not find merged metamodel")
 						else:

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

@@ -2,4 +2,4 @@ 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)
 Element function model_join(models : Element, metamodel : Element, tracability : Element)
-Element function model_split(source_model : Element, target_metamodel : Element, retyping_key : String)
+Element function model_split(merged_model : Element, models : Element)