Browse Source

Perform various tests when opening models in a specific context

Yentl Van Tendeloo 8 years ago
parent
commit
1f90227d5f
2 changed files with 123 additions and 55 deletions
  1. 7 5
      bootstrap/conformance_finding.alc
  2. 116 50
      bootstrap/core_algorithm.alc

+ 7 - 5
bootstrap/conformance_finding.alc

@@ -11,12 +11,10 @@ Boolean function find_type_mapping(model : Element):
 	// Returns True if the type mapping was altered
 
 	// Start of with some initialization
-	Boolean result
 	Element tm
 	Element elems
 	String elem
 
-	result = False
 	tm = get_type_mapping_as_dict(model)
 
 	// 1) remove elements from type mapping that are not in the model or metamodel
@@ -35,7 +33,6 @@ Boolean function find_type_mapping(model : Element):
 	if (dict_len(model["model"]) > dict_len(tm)):
 		log("Searching for model type!")
 
-		result = True
 		// TODO for now, this only returns something for a simple case, where the MM has one edge, and one node
 		//      and it makes the assumption that SCD is the M3 level...
 
@@ -45,17 +42,23 @@ Boolean function find_type_mapping(model : Element):
 
 		String node_element
 		String edge_element
+		node_element = read_root()
+		edge_element = read_root()
 
 		elems = dict_keys(model["metamodel"]["model"])
 		while (set_len(elems) > 0):
 			elem = set_pop(elems)
 
 			if (bool_not(is_edge(model["metamodel"]["model"][elem]))):
+				if (element_neq(node_element, read_root())):
+					return False!
 				node_element = elem
 			else:
 				// Is an edge, but might be the inheritance link...
 				if (read_type(model["metamodel"], elem) != "Inheritance"):
 					// Is not the inheritance link
+					if (element_neq(edge_element, read_root())):
+						return False!
 					edge_element = elem
 
 		// Now we have bot an edge_element and node_element of the metamodel
@@ -71,6 +74,5 @@ Boolean function find_type_mapping(model : Element):
 
 	// 3) (optional) verify that the mapping is correct with conformance checking
 	// TODO
-	// If not, set the result to read_root()
 	
-	return result!
+	return True!

+ 116 - 50
bootstrap/core_algorithm.alc

@@ -68,7 +68,12 @@ Element function get_full_model(model_id : String, metamodel_id : String):
 		// Found the meta-circular level, so we can stop!
 		dict_add(m, "metamodel", m)
 	else:
-		dict_add(m, "metamodel", get_full_model(metamodel_id, get_model_id("SimpleClassDiagrams")))
+		Element mm
+		mm = get_full_model(metamodel_id, get_model_id("SimpleClassDiagrams"))
+		if (element_eq(mm, read_root())):
+			return read_root()!
+		else:
+			dict_add(m, "metamodel", mm)
 
 	if (element_neq(choice, read_root())):
 		if (set_len(allAssociationDestinations(core, choice, "typing")) == 1):
@@ -81,11 +86,11 @@ Element function get_full_model(model_id : String, metamodel_id : String):
 		// Start from scratch
 		dict_add(m, "type_mapping", new_type_mapping())
 	
-	find_type_mapping(m)
-
-	// TODO store the found type model somewhere
-
-	return m!
+	if (find_type_mapping(m)):
+		// TODO store the found type model somewhere
+		return m!
+	else:
+		return read_root()!
 
 Integer function get_relation_to_model(user_id : String, model_id : String):
 	if (set_in(allAssociationDestinations(core, model_id, "owner"), user_id)):
@@ -414,13 +419,32 @@ 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_node(model_tuples, create_tuple(key, get_full_model(get_model_id(input_models[key]), get_model_id(input_metamodels[key]))))
+			Element mm
+			mm = get_full_model(get_model_id(input_models[key]), get_model_id(input_metamodels[key]))
+			if (element_eq(mm, read_root())):
+				log("Signature mismatch in operation for tag " + key)
+				output("Signature mismatch in operation for tag " + key)
+				return read_root()!
+			set_add_node(model_tuples, create_tuple(key, mm))
+
+		Element merged_metamodel
+		merged_metamodel = get_full_model(get_model_id(merged_metamodel_id), get_model_id("SimpleClassDiagrams"))
+		if (element_eq(merged_metamodel, read_root())):
+			log("Merged metamodel in operation is not of type SimpleClassDiagrams")
+			output("Merged metamodel in operation is not of type SimpleClassDiagrams")
+			return read_root()!
 
-		merged_model = model_join(model_tuples, get_full_model(merged_metamodel_id, get_model_id("SimpleClassDiagrams")), tracability_model)
+		merged_model = model_join(model_tuples, merged_metamodel, tracability_model)
 	else:
 		if (bool_and(dict_len(input_models) == 1, dict_len(output_metamodels) == 0)):
 			// Just skip the merge...
-			merged_model = model_copy(get_full_model(get_model_id(input_models[set_pop(dict_keys(input_models))]), get_model_id(input_metamodels[set_pop(dict_keys(input_metamodels))])))
+			Element m
+			m = get_full_model(get_model_id(input_models[set_pop(dict_keys(input_models))]), get_model_id(input_metamodels[set_pop(dict_keys(input_metamodels))]))
+			if (element_eq(m, read_root())):
+				log("Signature mismatch in operation for tag " + cast_v2s(set_pop(dict_keys(input_models))))
+				output("Signature mismatch in operation for tag " + cast_v2s(set_pop(dict_keys(input_models))))
+				return read_root()!
+			merged_model = model_copy(m)
 		elif (bool_and(dict_len(input_models) == 0, dict_len(output_metamodels) == 0)):
 			merged_model = read_root()
 		else:
@@ -438,14 +462,26 @@ Element function execute_operation(operation_id : String, input_models : Element
 			if (value_eq(read_attribute(core, trace_link_id, "type"), "RAMified")):
 				ramified_metamodel_id = readAssociationDestination(core, trace_link_id)
 
-		result = transform(merged_model, get_full_model(operation_id, ramified_metamodel_id))
+		Element operation
+		operation = get_full_model(operation_id, ramified_metamodel_id)
+		if (element_eq(operation, read_root())):
+			log("Operation could not be typed by specified RAMified metamodel!")
+			output("Operation could not be typed by specified RAMified metamodel!")
+			return read_root()!
+		result = transform(merged_model, operation)
 	elif (exact_type == "ManualOperation"):
 		output("Please perform manual operation " + cast_v2s(read_attribute(core, operation_id, "name")))
 		modify(merged_model, True)
 		result = True
 	elif (exact_type == "ActionLanguage"):
 		Element func
-		func = get_func_AL_model(get_full_model(operation_id, get_model_id("ActionLanguage")))
+		Element al
+		al = get_full_model(operation_id, get_model_id("ActionLanguage"))
+		if (element_eq(al, read_root())):
+			log("Action Language operation not typed by ActionLanguage metamodel!")
+			output("Action Language operation not typed by ActionLanguage metamodel!")
+			return read_root()!
+		func = get_func_AL_model(al)
 		result = func(merged_model)
 	else:
 		log("Unknown type of operation: " + exact_type)
@@ -464,7 +500,13 @@ Element function execute_operation(operation_id : String, input_models : Element
 		keys = dict_keys(output_metamodels)
 		while (set_len(keys) > 0):
 			key = set_pop(keys)
-			set_add_node(model_tuples, create_tuple(key, get_full_model(get_model_id(output_metamodels[key]), get_model_id("SimpleClassDiagrams"))))
+			Element mm
+			mm = get_full_model(get_model_id(output_metamodels[key]), get_model_id("SimpleClassDiagrams"))
+			if (element_eq(mm, read_root())):
+				log("Output metamodel cannot be interpreted using SimpleClassDiagrams: " + key)
+				output("Output metamodel cannot be interpreted using SimpleClassDiagrams: " + key)
+				return read_root()!
+			set_add_node(model_tuples, create_tuple(key, mm))
 
 		result = model_split(merged_model, model_tuples, tracability)
 
@@ -709,8 +751,13 @@ String function cmd_model_add(user_id : String, type : String, name : String):
 			// And is readable
 			if (get_model_id(name) == ""):
 				// Model doesn't exist yet
+				Element mm
+				mm = get_full_model(type_id, get_model_id("SimpleClassDiagrams"))
+				if (element_eq(mm, read_root())):
+					return "Type is not typed by SimpleClassDiagrams: " + type!
+
 				output("Waiting for model constructors...")
-				new_model = construct_model_raw(get_full_model(type_id, get_model_id("SimpleClassDiagrams")))
+				new_model = construct_model_raw(mm)
 				model_create(new_model, name, user_id, type_id, "Model")
 				return "Success"!
 			else:
@@ -727,7 +774,12 @@ String function cmd_process_execute(user_id : String, process : String, prefix :
 	process_id = get_model_id(process)
 	if (process_id != ""):
 		if (allow_read(user_id, process_id)):
-			enact_PM(get_full_model(process_id, get_model_id("ProcessModel")), prefix, user_id)
+			Element pm
+			pm = get_full_model(process_id, get_model_id("ProcessModel"))
+			if (element_eq(pm, read_root())):
+				return "Specified model cannot be interpreted as a ProcessModel: " + process!
+
+			enact_PM(pm, prefix, user_id)
 			return "Success"!
 		else:
 			return "Permission denied to model: " + process!
@@ -804,7 +856,12 @@ String function cmd_model_render(user_id : String, model_name : String, mapper_n
 
 					if (get_model_id(rendered_name) == ""):
 						// Instantiate
-						rendered_model = instantiate_model(get_full_model(get_model_id(output_map["rendered"]), get_model_id("SimpleClassDiagrams")))
+						Element rendered
+						rendered = get_full_model(get_model_id(output_map["rendered"]), get_model_id("SimpleClassDiagrams"))
+						if (element_eq(rendered, read_root())):
+							return "Rendered metamodel cannot conform to SimpleClassDiagrams"!
+
+						rendered_model = instantiate_model(rendered)
 						model_create(rendered_model, rendered_name, user_id, get_model_id(output_map["rendered"]), "Model")
 						
 						// Tracability model won't exist either
@@ -813,7 +870,9 @@ String function cmd_model_render(user_id : String, model_name : String, mapper_n
 
 					else:
 						// Read out tracability model
-						tracability_model = get_full_model(get_model_id(tracability_name), get_model_id("TracabilityModel"))
+						tracability_model = get_full_model(get_model_id(tracability_name), get_model_id("Tracability"))
+						if (element_eq(tracability_model, read_root())):
+							return "Tracability model not typed by Tracability metamodel: " + tracability_name!
 
 					// Do the operation itself!
 					result = execute_operation(mapper_ID, inputs, tracability_model)
@@ -825,6 +884,8 @@ String function cmd_model_render(user_id : String, model_name : String, mapper_n
 					// Tracability updated in-place
 					model_overwrite(tracability_model, get_model_id(tracability_name), get_model_id("Tracability"))
 					tracability_model = get_full_model(get_model_id(tracability_name), get_model_id("Tracability"))
+					if (element_eq(tracability_model, read_root())):
+						return "Tracability model not typed by Tracability metamodel: " + tracability_name!
 
 					// Also output the resulting model
 					return "Success: " + JSON_print(get_full_model(get_model_id(rendered_name), get_model_id(output_map["rendered"])))!
@@ -949,31 +1010,12 @@ String function cmd_verify(user_id : String, model_name : String, metamodel_name
 	model_id = get_model_id(model_name)
 	if (model_id != ""):
 		if (allow_read(user_id, model_id)):
-			return string_join("Success: ", conformance_scd(get_full_model(get_model_id(model_name), get_model_id(metamodel_name))))!
-		else:
-			return "Permission denied to model: " + model_name!
-	else:
-		return "Model not found: " + model_name!
+			Element m
+			m = get_full_model(get_model_id(model_name), get_model_id(metamodel_name))
+			if (element_eq(m, read_root())):
+				return "No conformance relation can be found between these models"!
 
-String function cmd_new_verify(user_id : String, model_name : String, metamodel_name : String):
-	// Check whether a model conforms to its specification (with the selected type mapping)
-	String model_id
-	String result
-	Element inputs
-
-	model_id = get_model_id(model_name)
-	if (model_id != ""):
-		if (allow_read(user_id, model_id)):
-			Element full_model
-			Element conformance_operation
-
-			full_model = get_full_model(get_model_id(model_name), get_model_id(metamodel_name))
-			conformance_operation = full_model["semantics"]
-
-			inputs = dict_create()
-			dict_add(inputs, "SimpleClassDiagrams", model_name)
-			result = execute_operation(conformance_operation, inputs, read_root())
-			return ""!
+			return string_join("Success: ", conformance_scd(m))!
 		else:
 			return "Permission denied to model: " + model_name!
 	else:
@@ -990,8 +1032,13 @@ String function cmd_model_overwrite(user_id : String, model_name : String, metam
 		if (allow_write(user_id, model_id)):
 			type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf"))
 			if (allow_read(user_id, type_id)):
+				Element mm
+				mm = get_full_model(get_model_id(metamodel_name), get_model_id("SimpleClassDiagrams"))
+				if (element_eq(mm, read_root())):
+					return "Metamodel does not conform to SimpleClassDiagrams: " + metamodel_name!
+
 				output("Waiting for model constructors...")
-				new_model = construct_model_raw(get_full_model(get_model_id(metamodel_name), get_model_id("SimpleClassDiagrams")))
+				new_model = construct_model_raw(mm)
 				model_overwrite(new_model, model_id, metamodel_name)
 				return "Success"!
 			else:
@@ -1012,11 +1059,11 @@ String function cmd_model_modify(user_id : String, model_name : String, metamode
 		if (allow_read(user_id, model_id)):
 			type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf"))
 			if (allow_read(user_id, type_id)):
-				output("Success")
 				Element new_model
-				log("Getting full model for " + model_name)
-				log("Metamodel:  " + metamodel_name)
 				new_model = get_full_model(model_id, get_model_id(metamodel_name))
+				if (element_eq(new_model, read_root())):
+					return "No conformance relation can be found between these models"!
+				output("Success")
 				modify(new_model, allow_write(user_id, model_id))
 				if (allow_write(user_id, model_id)):
 					// Overwrite the modified model
@@ -1108,6 +1155,7 @@ String function transformation_add(user_id : String, source_models : Element, ta
 	String tracability_link
 	Element keys
 	String key
+	Element mm
 
 	source = dict_create()
 	target = dict_create()
@@ -1123,7 +1171,11 @@ 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_node(formalism_map, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
+					mm = get_full_model(model_id, get_model_id("SimpleClassDiagrams"))
+					if (element_eq(mm, read_root())):
+						return "Transformation source type not in SimpleClassDiagrams hierarchy: " + key!
+
+					set_add_node(formalism_map, create_tuple(key, mm))
 					if (bool_not(set_in(all_formalisms, model_id))):
 						set_add(all_formalisms, model_id)
 				else:
@@ -1142,7 +1194,11 @@ 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_node(formalism_map, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
+					mm = get_full_model(model_id, get_model_id("SimpleClassDiagrams"))
+					if (element_eq(mm, read_root())):
+						return "Transformation target type not in SimpleClassDiagrams hierarchy: " + key!
+
+					set_add_node(formalism_map, create_tuple(key, mm))
 					if (bool_not(set_in(all_formalisms, model_id))):
 						set_add(all_formalisms, model_id)
 				else:
@@ -1223,7 +1279,7 @@ String function cmd_transformation_add_MT(user_id : String, source_models : Elem
 	String merged_formalism
 	Element keys
 	String key
-	String mm
+	Element mm
 	Element to_ramify
 	String source_formalism_id
 	String merged_formalism_id
@@ -1244,7 +1300,10 @@ String function cmd_transformation_add_MT(user_id : String, source_models : Elem
 				if (is_typed_by(model_id, get_model_id("SimpleClassDiagrams"))):
 					if (bool_not(dict_in(source, key))):
 						dict_add(source, key, model_id)
-						set_add_node(to_ramify, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
+						mm = get_full_model(model_id, get_model_id("SimpleClassDiagrams"))
+						if (element_eq(mm, read_root())):
+							return "ModelTransformation source type not in SimpleClassDiagrams hierarchy: " + name!
+						set_add_node(to_ramify, create_tuple(key, mm))
 					else:
 						return "Name was already assigned a metamodel: " + key!
 				else:
@@ -1271,7 +1330,10 @@ 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_node(to_ramify, create_tuple(key, get_full_model(model_id, get_model_id("SimpleClassDiagrams"))))
+							mm = get_full_model(model_id, get_model_id("SimpleClassDiagrams"))
+							if (element_eq(mm, read_root())):
+								return "ModelTransformation target type not in SimpleClassDiagrams hierarchy: " + name!
+							set_add_node(to_ramify, create_tuple(key, mm))
 					else:
 						return "Name was already assigned a metamodel: " + key!
 				else:
@@ -1701,7 +1763,11 @@ String function cmd_transformation_signature(user_id : String, transformation_na
 String function cmd_element_list_nice(user_id : String, model_name : String, metamodel_name : String):
 	if (get_model_id(model_name) != ""):
 		if (allow_read(user_id, get_model_id(model_name))):
-			return "Success: " + JSON_print(get_full_model(get_model_id(model_name), get_model_id(metamodel_name)))!
+			Element mm
+			mm = get_full_model(get_model_id(model_name), get_model_id(metamodel_name))
+			if (element_eq(mm, read_root())):
+				return "No conformance relation between these models"!
+			return "Success: " + JSON_print(mm)!
 		else:
 			return "Permission denied to model: " + model_name!
 	else: