فهرست منبع

First cache all cardinalities so we don't have to read the attribute thousands of times

Yentl Van Tendeloo 9 سال پیش
والد
کامیت
13c4e0e038
2فایلهای تغییر یافته به همراه63 افزوده شده و 42 حذف شده
  1. 63 36
      bootstrap/conformance_scd.alc
  2. 0 6
      bootstrap/object_operations.alc

+ 63 - 36
bootstrap/conformance_scd.alc

@@ -19,7 +19,7 @@ Boolean function is_nominal_subtype(metamodel : Element, subclass : Element, sup
 	Element new_superclass
 	Element result
 
-	log((("Nominal subtype? " + cast_e2s(subclass)) + " --|> ") + cast_e2s(superclass))
+	log((("Nominal subtype? " + reverseKeyLookup(metamodel["model"], subclass)) + " --|> ") + reverseKeyLookup(metamodel["model"], superclass))
 	superclasses = get_superclasses(metamodel, subclass)
 
 	while (0 < list_len(superclasses)):
@@ -83,13 +83,42 @@ String function conformance_scd(model : Element):
 	Element element
 	Element check_list
 	Element check_type
+	Element cardinalities
 
 	// Load in variables
-	keys = dict_keys(model["model"])
 	metamodel = model["metamodel"]
 	typing = model["type_mapping"]
+	cardinalities = create_node()
+
+	// Create dictionary with all associations and allowed cardinalities
+	keys = dict_keys(metamodel["model"])
+	Integer slc
+	Integer suc
+	Integer tlc
+	Integer tuc
+	String key
+	Element tmp_dict
+	while (0 < list_len(keys)):
+		key = set_pop(keys)
+		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
+	keys = dict_keys(model["model"])
 	while (0 < list_len(keys)):
 		model_name = set_pop(keys)
 		element = model["model"][model_name]
@@ -121,48 +150,46 @@ String function conformance_scd(model : Element):
 		//   A  ---------------------> B
 		//
 		// First the incoming, so we are at B in the above figure
+		log("At element " + model_name)
+		Integer lower_val
+		Integer upper_val
+		Integer instances
 		check_list = allPossibleIncoming(model, model_name)
 		while (0 < list_len(check_list)):
-			Integer instances
-			Integer lower_val
-			Integer upper_val
 			check_type = set_pop(check_list)
-			log("Lookup!")
-			log(cast_e2s(check_type))
-			log(cast_e2s(reverseKeyLookup(model["model"], check_type)))
-			log(cast_e2s(reverseKeyLookup(metamodel["model"], check_type)))
-			lower_val = read_attribute(metamodel, reverseKeyLookup(metamodel["model"], check_type), "target_lower_cardinality")
-			upper_val = read_attribute(metamodel, reverseKeyLookup(metamodel["model"], check_type), "target_upper_cardinality")
-			log("Look up " + cast_e2s(element))
-			log("   " + cast_e2s(check_type))
-			instances = list_len(allIncomingAssociationInstances(model, element, check_type))
-			if (element_neq(lower_val, read_root())):
-				// A lower multiplicity was defined at the target
-				if (lower_val > instances):
-					return "Lower cardinality violation for incoming edge at " + model_name
-			if (element_neq(upper_val, read_root())):
-				// A lower multiplicity was defined at the target
-				if (upper_val < instances):
-					return "Upper cardinality violation for incoming edge at " + model_name
+			if (dict_in(cardinalities, reverseKeyLookup(metamodel["model"], check_type))):
+				// Cardinalities defined for this association, so check them
+				log("  check " + reverseKeyLookup(metamodel["model"], check_type))
+				lower_val = cardinalities[check_type]["tlc"]
+				upper_val = cardinalities[check_type]["tlc"]
+				instances = list_len(allIncomingAssociationInstances(model, element, check_type))
+				if (dict_in(cardinalities[check_type], "tlc")):
+					// A lower cardinality was defined at the target
+					if (integer_gt(cardinalities[check_type]["tlc"], instances)):
+						return "Lower cardinality violation for incoming edge at " + model_name
+				if (dict_in(cardinalities[check_type], "tuc")):
+					// An upper cardinality was defined at the target
+					if (integer_gt(cardinalities[check_type]["tuc"], instances)):
+						return "Upper cardinality violation for incoming edge at " + model_name
 
 		// Identical, but for outgoing, and thus for A in the figure
 		check_list = allPossibleOutgoing(model, model_name)
 		while (0 < list_len(check_list)):
-			Integer instances
-			Integer lower_val
-			Integer upper_val
 			check_type = set_pop(check_list)
-			lower_val = read_attribute(metamodel, reverseKeyLookup(metamodel["model"], check_type), "source_lower_cardinality")
-			upper_val = read_attribute(metamodel, reverseKeyLookup(metamodel["model"], check_type), "source_upper_cardinality")
-			instances = list_len(allOutgoingAssociationInstances(model, element, check_type))
-			if (element_neq(lower_val, read_root())):
-				// A lower multiplicity was defined at the source
-				if (lower_val > instances):
-					return "Lower cardinality violation for incoming edge at " + model_name
-			if (element_neq(upper_val, read_root())):
-				// A lower multiplicity was defined at the source
-				if (upper_val < instances):
-					return "Upper cardinality violation for incoming edge at " + model_name
+			if (dict_in(cardinalities, reverseKeyLookup(metamodel["model"], check_type))):
+				// Cardinalities defined for this association, so check them
+				log("  check " + reverseKeyLookup(metamodel["model"], check_type))
+				lower_val = cardinalities[check_type]["slc"]
+				upper_val = cardinalities[check_type]["slc"]
+				instances = list_len(allOutgoingAssociationInstances(model, element, check_type))
+				if (dict_in(cardinalities[check_type], "slc")):
+					// A lower cardinality was defined at the source
+					if (integer_gt(cardinalities[check_type]["slc"], instances)):
+						return "Lower cardinality violation for outgoing edge at " + model_name
+				if (dict_in(cardinalities[check_type], "suc")):
+					// An upper cardinality was defined at the source
+					if (integer_gt(cardinalities[check_type]["suc"], instances)):
+						return "Upper cardinality violation for outgoing edge at " + model_name
 
 	// Check multiplicities, if they are defined (optional)
 	Element metamodel_keys

+ 0 - 6
bootstrap/object_operations.alc

@@ -37,7 +37,6 @@ Element function allPossibleIncoming(model : Element, target : String):
 	result = create_node()
 	metamodel = model["metamodel"]
 	all_elems = dict_keys(metamodel["model"])
-	log("Read all possible incoming edges for " + target)
 	
 	while (0 < list_len(all_elems)):
 		type = set_pop(all_elems)
@@ -45,8 +44,6 @@ Element function allPossibleIncoming(model : Element, target : String):
 		if (is_edge(elem)):
 			if (is_nominal_instance(model, model["model"][target], read_edge_src(elem))):
 				set_add(result, elem)
-				log("Found " + reverseKeyLookup(metamodel["model"], elem))
-				log("      " + type)
 	
 	return result
 
@@ -123,10 +120,7 @@ Element function getAttributeList(model : Element, element : String):
 	// Add our own attributes
 	while (0 < list_len(keys)):
 		attr_name = set_pop(keys)
-		log("Test for " + cast_e2s(attr_name))
 		if (is_physical_string(attr_name)):
-			log("Found attribute " + cast_v2s(attr_name))
-
 			attr_type = getName(model["metamodel"], type[attr_name])
 			dict_add(result, attr_name, attr_type)