Browse Source

Cache selectPossibleIncoming and selectPossibleOutgoing for much higher performance

Yentl Van Tendeloo 9 years ago
parent
commit
7d22fc31ef
1 changed files with 49 additions and 27 deletions
  1. 49 27
      bootstrap/conformance_scd.alc

+ 49 - 27
bootstrap/conformance_scd.alc

@@ -21,7 +21,10 @@ Boolean function is_nominal_instance(model : Element, instance : String, type :
 		// doesn't even have a type
 		// doesn't even have a type
 		return False
 		return False
 
 
-	return is_nominal_subtype(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][instance])), type)
+	Boolean result
+	result = is_nominal_subtype(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][instance])), type)
+
+	return result
 
 
 Boolean function is_nominal_subtype(metamodel : Element, subclass : String, superclass : String):
 Boolean function is_nominal_subtype(metamodel : Element, subclass : String, superclass : String):
 	if (element_eq(metamodel["model"][subclass], metamodel["model"][superclass])):
 	if (element_eq(metamodel["model"][subclass], metamodel["model"][superclass])):
@@ -63,6 +66,12 @@ String function conformance_scd(model : Element):
 	Element scd
 	Element scd
 	Integer instances
 	Integer instances
 
 
+	Element spo_cache
+	Element spi_cache
+
+	spo_cache = create_node()
+	spi_cache = create_node()
+
 	// Load in variables
 	// Load in variables
 	scd = import_node("models/SimpleClassDiagrams")
 	scd = import_node("models/SimpleClassDiagrams")
 	metamodel = model["metamodel"]
 	metamodel = model["metamodel"]
@@ -71,36 +80,34 @@ String function conformance_scd(model : Element):
 
 
 	// Create dictionary with all associations and allowed cardinalities
 	// Create dictionary with all associations and allowed cardinalities
 	if (list_len(model["model"]) > 0):
 	if (list_len(model["model"]) > 0):
-		keys = dict_keys(metamodel["model"])
 		Integer slc
 		Integer slc
 		Integer suc
 		Integer suc
 		Integer tlc
 		Integer tlc
 		Integer tuc
 		Integer tuc
 		String key
 		String key
 		Element tmp_dict
 		Element tmp_dict
+		String type_name
 
 
-		log("Start attribute read")
+		keys = allInstances(metamodel, "Association")
 		while (0 < list_len(keys)):
 		while (0 < list_len(keys)):
 			key = set_pop(keys)
 			key = set_pop(keys)
-			if (is_nominal_instance(metamodel, key, "Association")):
-				tmp_dict = create_node()
-				slc = read_attribute(metamodel, key, "source_lower_cardinality")
-				suc = read_attribute(metamodel, key, "source_upper_cardinality")
-				tlc = read_attribute(metamodel, key, "target_lower_cardinality")
-				tuc = read_attribute(metamodel, key, "target_upper_cardinality")
-
-				if (element_neq(slc, read_root())):
-					dict_add(tmp_dict, "slc", slc)
-				if (element_neq(suc, read_root())):
-					dict_add(tmp_dict, "suc", suc)
-				if (element_neq(tlc, read_root())):
-					dict_add(tmp_dict, "tlc", tlc)
-				if (element_neq(tuc, read_root())):
-					dict_add(tmp_dict, "tuc", tuc)
-
-				if (list_len(tmp_dict) > 0):
-					dict_add(cardinalities, key, tmp_dict)
-		log("Finish attribute read")
+			tmp_dict = create_node()
+			slc = read_attribute(metamodel, key, "source_lower_cardinality")
+			suc = read_attribute(metamodel, key, "source_upper_cardinality")
+			tlc = read_attribute(metamodel, key, "target_lower_cardinality")
+			tuc = read_attribute(metamodel, key, "target_upper_cardinality")
+
+			if (element_neq(slc, read_root())):
+				dict_add(tmp_dict, "slc", slc)
+			if (element_neq(suc, read_root())):
+				dict_add(tmp_dict, "suc", suc)
+			if (element_neq(tlc, read_root())):
+				dict_add(tmp_dict, "tlc", tlc)
+			if (element_neq(tuc, read_root())):
+				dict_add(tmp_dict, "tuc", tuc)
+
+			if (list_len(tmp_dict) > 0):
+				dict_add(cardinalities, key, tmp_dict)
 
 
 		// Iterate over each element of the model, finding out whether everything is fine
 		// Iterate over each element of the model, finding out whether everything is fine
 		keys = dict_keys(model["model"])
 		keys = dict_keys(model["model"])
@@ -108,6 +115,7 @@ String function conformance_scd(model : Element):
 			model_name = set_pop(keys)
 			model_name = set_pop(keys)
 			log("Check " + model_name)
 			log("Check " + model_name)
 			element = model["model"][model_name]
 			element = model["model"][model_name]
+			type_name = reverseKeyLookup(metamodel["model"], dict_read_node(typing, element))
 
 
 			if (bool_not(dict_in_node(typing, element))):
 			if (bool_not(dict_in_node(typing, element))):
 				return "Model has no type specified: " + model_name
 				return "Model has no type specified: " + model_name
@@ -115,7 +123,7 @@ String function conformance_scd(model : Element):
 			if (bool_not(set_in_node(metamodel["model"], dict_read_node(typing, element)))):
 			if (bool_not(set_in_node(metamodel["model"], dict_read_node(typing, element)))):
 				return "Type of element not in specified metamodel: " + model_name
 				return "Type of element not in specified metamodel: " + model_name
 
 
-			if (bool_not(is_nominal_instance(model, model_name, reverseKeyLookup(metamodel["model"], dict_read_node(typing, element))))):
+			if (bool_not(is_nominal_instance(model, model_name, type_name))):
 				return "Element is not an instance of its specified type: " + model_name
 				return "Element is not an instance of its specified type: " + model_name
 
 
 			if (is_edge(element)):
 			if (is_edge(element)):
@@ -136,7 +144,9 @@ String function conformance_scd(model : Element):
 			//   A  ---------------------> B
 			//   A  ---------------------> B
 			//
 			//
 			// First the incoming, so we are at B in the above figure
 			// First the incoming, so we are at B in the above figure
-			check_list = selectPossibleOutgoing(model, model_name, dict_keys(cardinalities))
+			if (bool_not(dict_in(spo_cache, type_name))):
+				dict_add(spo_cache, type_name, selectPossibleOutgoing(metamodel, type_name, dict_keys(cardinalities)))
+			check_list = spo_cache[type_name]
 			while (0 < list_len(check_list)):
 			while (0 < list_len(check_list)):
 				check_type = set_pop(check_list)
 				check_type = set_pop(check_list)
 				if (dict_in(cardinalities, check_type)):
 				if (dict_in(cardinalities, check_type)):
@@ -146,14 +156,22 @@ String function conformance_scd(model : Element):
 						if (dict_in(cardinalities[check_type], "tlc")):
 						if (dict_in(cardinalities[check_type], "tlc")):
 							// A lower cardinality was defined at the target
 							// A lower cardinality was defined at the target
 							if (integer_gt(cardinalities[check_type]["tlc"], instances)):
 							if (integer_gt(cardinalities[check_type]["tlc"], instances)):
+								log("Instances: " + cast_i2s(instances))
+								log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
+								log("Type: " + check_type)
 								return "Lower cardinality violation for outgoing edge at " + model_name
 								return "Lower cardinality violation for outgoing edge at " + model_name
 						if (dict_in(cardinalities[check_type], "tuc")):
 						if (dict_in(cardinalities[check_type], "tuc")):
 							// An upper cardinality was defined at the target
 							// An upper cardinality was defined at the target
 							if (integer_lt(cardinalities[check_type]["tuc"], instances)):
 							if (integer_lt(cardinalities[check_type]["tuc"], instances)):
+								log("Instances: " + cast_i2s(instances))
+								log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
+								log("Type: " + check_type)
 								return "Upper cardinality violation for outgoing edge at " + model_name
 								return "Upper cardinality violation for outgoing edge at " + model_name
 
 
 			// Identical, but for outgoing, and thus for A in the figure
 			// Identical, but for outgoing, and thus for A in the figure
-			check_list = selectPossibleIncoming(model, model_name, dict_keys(cardinalities))
+			if (bool_not(dict_in(spi_cache, type_name))):
+				dict_add(spi_cache, type_name, selectPossibleIncoming(metamodel, type_name, dict_keys(cardinalities)))
+			check_list = spi_cache[type_name]
 			while (0 < list_len(check_list)):
 			while (0 < list_len(check_list)):
 				check_type = set_pop(check_list)
 				check_type = set_pop(check_list)
 				if (dict_in(cardinalities, check_type)):
 				if (dict_in(cardinalities, check_type)):
@@ -163,10 +181,16 @@ String function conformance_scd(model : Element):
 						if (dict_in(cardinalities[check_type], "slc")):
 						if (dict_in(cardinalities[check_type], "slc")):
 							// A lower cardinality was defined at the source
 							// A lower cardinality was defined at the source
 							if (integer_gt(cardinalities[check_type]["slc"], instances)):
 							if (integer_gt(cardinalities[check_type]["slc"], instances)):
+								log("Instances: " + cast_i2s(instances))
+								log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
+								log("Type: " + check_type)
 								return "Lower cardinality violation for incoming edge at " + model_name
 								return "Lower cardinality violation for incoming edge at " + model_name
 						if (dict_in(cardinalities[check_type], "suc")):
 						if (dict_in(cardinalities[check_type], "suc")):
 							// An upper cardinality was defined at the source
 							// An upper cardinality was defined at the source
 							if (integer_lt(cardinalities[check_type]["suc"], instances)):
 							if (integer_lt(cardinalities[check_type]["suc"], instances)):
+								log("Instances: " + cast_i2s(instances))
+								log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
+								log("Type: " + check_type)
 								return "Upper cardinality violation for incoming edge at " + model_name
 								return "Upper cardinality violation for incoming edge at " + model_name
 
 
 			Element constraint_function
 			Element constraint_function
@@ -177,7 +201,6 @@ String function conformance_scd(model : Element):
 				if (result != "OK"):
 				if (result != "OK"):
 					return result
 					return result
 
 
-	log("Start multiplicities")
 	// Check multiplicities, if they are defined (optional)
 	// Check multiplicities, if they are defined (optional)
 	Element metamodel_keys
 	Element metamodel_keys
 	String metamodel_element
 	String metamodel_element
@@ -200,7 +223,6 @@ String function conformance_scd(model : Element):
 			// We have defined a lower cardinality, so check number of instances!
 			// We have defined a lower cardinality, so check number of instances!
 			if (attr_value < list_len(allInstances(model, metamodel_element))):
 			if (attr_value < list_len(allInstances(model, metamodel_element))):
 				return "Upper cardinality violated for class: " + metamodel_element
 				return "Upper cardinality violated for class: " + metamodel_element
-	log("Finished multiplicities")
 
 
 	// Structure seems fine, now do static semantics
 	// Structure seems fine, now do static semantics
 	if (dict_in(metamodel, "constraints")):
 	if (dict_in(metamodel, "constraints")):