Prechádzať zdrojové kódy

Added quick-fail for conformance check

Yentl Van Tendeloo 9 rokov pred
rodič
commit
592749bd89
1 zmenil súbory, kde vykonal 21 pridanie a 13 odobranie
  1. 21 13
      bootstrap/conformance_scd.alc

+ 21 - 13
bootstrap/conformance_scd.alc

@@ -13,6 +13,10 @@ Boolean function is_nominal_instance(model : Element, instance : String, type :
 		// type is not even in the specified metamodel, so this will never work
 		return False
 
+	if (bool_and(is_edge(model["metamodel"]["model"][type]), bool_not(is_edge(model["model"][instance])))):
+		// type is an edge, but we aren't
+		return False
+
 	if (bool_not(dict_in_node(model["type_mapping"], model["model"][instance]))):
 		// Doesn't even have a type
 		return False
@@ -57,8 +61,7 @@ String function conformance_scd(model : Element):
 	String check_type
 	Element cardinalities
 	Element scd
-	String error_msg
-	error_msg = ""
+	Integer instances
 
 	// Load in variables
 	scd = import_node("models/SimpleClassDiagrams")
@@ -76,6 +79,7 @@ String function conformance_scd(model : Element):
 		String key
 		Element tmp_dict
 
+		log("Start attribute read")
 		while (0 < list_len(keys)):
 			key = set_pop(keys)
 			if (is_nominal_instance(metamodel, key, "Association")):
@@ -96,31 +100,39 @@ String function conformance_scd(model : Element):
 
 				if (list_len(tmp_dict) > 0):
 					dict_add(cardinalities, key, tmp_dict)
+		log("Finish attribute read")
 
 		// Iterate over each element of the model, finding out whether everything is fine
 		keys = dict_keys(model["model"])
 		while (0 < list_len(keys)):
 			model_name = set_pop(keys)
+			log("Check " + model_name)
 			element = model["model"][model_name]
 
+			log("1")
 			if (bool_not(dict_in_node(typing, element))):
 				return "Model has no type specified: " + model_name
 
+			log("2")
 			if (bool_not(set_in_node(metamodel["model"], dict_read_node(typing, element)))):
 				return "Type of element not in specified metamodel: " + model_name
 
+			log("3")
 			if (bool_not(is_nominal_instance(model, model_name, reverseKeyLookup(metamodel["model"], dict_read_node(typing, element))))):
 				return "Element is not an instance of its specified type: " + model_name
 
+			log("4")
 			if (is_edge(element)):
 				src_model = reverseKeyLookup(model["model"], read_edge_src(element))
 				dst_model = reverseKeyLookup(model["model"], read_edge_dst(element))
 				src_metamodel = reverseKeyLookup(metamodel["model"], read_edge_src(dict_read_node(typing, element)))
 				dst_metamodel = reverseKeyLookup(metamodel["model"], read_edge_dst(dict_read_node(typing, element)))
 
+				log("5")
 				if (bool_not(is_nominal_instance(model, src_model, src_metamodel))):
 					return "Source of model edge not typed by source of type: " + model_name
 
+				log("6")
 				if (bool_not(is_nominal_instance(model, dst_model, dst_metamodel))):
 					return "Destination of model edge not typed by source of type: " + model_name
 
@@ -130,17 +142,12 @@ String function conformance_scd(model : Element):
 			//   A  ---------------------> B
 			//
 			// First the incoming, so we are at B in the above figure
-			Integer lower_val
-			Integer upper_val
-			Integer instances
-
+			log("7")
 			check_list = selectPossibleOutgoing(model, model_name, dict_keys(cardinalities))
 			while (0 < list_len(check_list)):
 				check_type = set_pop(check_list)
 				if (dict_in(cardinalities, check_type)):
 					// Cardinalities defined for this association, so check them
-					lower_val = cardinalities[check_type]["tlc"]
-					upper_val = cardinalities[check_type]["tuc"]
 					instances = list_len(allOutgoingAssociationInstances(model, model_name, check_type))
 					if (dict_in(cardinalities[check_type], "tlc")):
 						// A lower cardinality was defined at the target
@@ -152,13 +159,13 @@ String function conformance_scd(model : Element):
 							return "Upper cardinality violation for outgoing edge at " + model_name
 
 			// Identical, but for outgoing, and thus for A in the figure
+			log("8")
 			check_list = selectPossibleIncoming(model, model_name, dict_keys(cardinalities))
 			while (0 < list_len(check_list)):
+				log("LOOP")
 				check_type = set_pop(check_list)
 				if (dict_in(cardinalities, check_type)):
 					// Cardinalities defined for this association, so check them
-					lower_val = cardinalities[check_type]["slc"]
-					upper_val = cardinalities[check_type]["suc"]
 					instances = list_len(allIncomingAssociationInstances(model, model_name, check_type))
 					if (dict_in(cardinalities[check_type], "slc")):
 						// A lower cardinality was defined at the source
@@ -169,16 +176,16 @@ String function conformance_scd(model : Element):
 						if (integer_lt(cardinalities[check_type]["suc"], instances)):
 							return "Upper cardinality violation for incoming edge at " + model_name
 
+			log("10")
 			Element constraint_function
-			constraint_function = read_attribute(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], element)), "constraint")
+			constraint_function = read_attribute(metamodel, reverseKeyLookup(metamodel["model"], dict_read_node(typing, element)), "constraint")
 			if (element_neq(constraint_function, read_root())):
 				String result
-				log("Calling constraint function!")
 				result = constraint_function(model, model_name)
-				log("Done: result " + result)
 				if (result != "OK"):
 					return result
 
+	log("Start multiplicities")
 	// Check multiplicities, if they are defined (optional)
 	Element metamodel_keys
 	String metamodel_element
@@ -201,6 +208,7 @@ String function conformance_scd(model : Element):
 			// We have defined a lower cardinality, so check number of instances!
 			if (attr_value < list_len(allInstances(model, metamodel_element))):
 				return "Upper cardinality violated for class: " + metamodel_element
+	log("Finished multiplicities")
 
 	// Structure seems fine, now do static semantics
 	if (dict_in(metamodel, "constraints")):