Browse Source

get_superclasses now returns the full set of superclasses, instead of only the direct superclasses

Yentl Van Tendeloo 9 years ago
parent
commit
95180d98c2
3 changed files with 34 additions and 50 deletions
  1. 6 16
      bootstrap/conformance_scd.alc
  2. 24 27
      bootstrap/modelling.alc
  3. 4 7
      bootstrap/object_operations.alc

+ 6 - 16
bootstrap/conformance_scd.alc

@@ -36,10 +36,7 @@ Boolean function is_nominal_instance(model : Element, instance : String, type :
 		// doesn't even have a type
 		return False
 
-	Boolean result
-	result = is_nominal_subtype(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][instance])), type)
-
-	return result
+	return is_nominal_subtype(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][instance])), type)
 
 Boolean function is_nominal_subtype(metamodel : Element, subclass : String, superclass : String):
 	if (element_eq(metamodel["model"][subclass], metamodel["model"][superclass])):
@@ -51,18 +48,7 @@ Boolean function is_nominal_subtype(metamodel : Element, subclass : String, supe
 	if (bool_not(dict_in(metamodel["model"], superclass))):
 		return False
 
-	Element superclasses
-	Element new_superclass
-	Element result
-
-	superclasses = get_superclasses(metamodel, subclass)
-
-	while (0 < list_len(superclasses)):
-		new_superclass = set_pop(superclasses)
-		if (is_nominal_subtype(metamodel, new_superclass, superclass)):
-			return True
-	
-	return False
+	return set_in(get_superclasses(metamodel, subclass), superclass)
 
 Element function precompute_cardinalities(model : Element):
 	Integer slc
@@ -171,7 +157,9 @@ String function conformance_scd(model : Element):
 			//
 			// First the incoming, so we are at B in the above figure
 			if (bool_not(dict_in(spo_cache, type_name))):
+				log("Fill SPO cache")
 				dict_add(spo_cache, type_name, selectPossibleOutgoing(metamodel, type_name, dict_keys(cardinalities)))
+				log("Filled SPO cache")
 
 			check_list = set_copy(spo_cache[type_name])
 			while (0 < list_len(check_list)):
@@ -197,7 +185,9 @@ String function conformance_scd(model : Element):
 
 			// Identical, but for outgoing, and thus for A in the figure
 			if (bool_not(dict_in(spi_cache, type_name))):
+				log("Fill SPI cache")
 				dict_add(spi_cache, type_name, selectPossibleIncoming(metamodel, type_name, dict_keys(cardinalities)))
+				log("Filled SPI cache")
 
 			check_list = set_copy(spi_cache[type_name])
 			while (0 < list_len(check_list)):

+ 24 - 27
bootstrap/modelling.alc

@@ -119,46 +119,43 @@ String function find_attribute_type(model : Element, elem : String, name : Strin
 Element function get_superclasses(model : Element, name : String):
 	Element result
 	Integer i
+	Integer j
 	Integer num_edges
 	Element edge
 	Element elem
+	Element nodes
 
-	elem = model["model"][name]
+	nodes = create_node()
+	set_add(nodes, model["model"][name])
 
 	// Initialize empty set
 	result = create_node()
 	i = 0
 
-	// Read out all outgoing edges
-	num_edges = read_nr_out(elem)
-	while (i < num_edges):
-		edge = read_out(elem, i)
-		if (element_eq(dict_read_node(model["type_mapping"], edge), model["inheritance"])):
-			create_edge(result, reverseKeyLookup(model["model"], read_edge_dst(edge)))
-		i = i + 1
+	while (0 < list_len(nodes)):
+		elem = set_pop(nodes)
+		create_edge(result, reverseKeyLookup(model["model"], elem))
+		// Read out all outgoing edges
+		num_edges = read_nr_out(elem)
+		j = 0
+		while (j < num_edges):
+			edge = read_out(elem, j)
+			if (element_eq(dict_read_node(model["type_mapping"], edge), model["inheritance"])):
+				set_add(nodes, read_edge_dst(edge))
+			j = j + 1
 
 	return result
 
 String function find_attribute_definer(model : Element, elem_name : String, name : String):
-	if (dict_in(model["model"][elem_name], name)):
-		// Try in the current class definition
-		return elem_name
-	else:
-		// Not found, so go to all superclasses and try there
-		Element superclasses
-		Element current
-		Element found
-
-		superclasses = get_superclasses(model, elem_name)
-		while (list_len(superclasses) > 0):
-			current = set_pop(superclasses)
-			found = find_attribute_definer(model, current, name)
-			if (bool_not(value_eq(found, ""))):
-				// Found something!
-				return current
-
-		// Error
-		return ""
+	Element superclasses
+	Element current
+
+	superclasses = get_superclasses(model, elem_name)
+	while (list_len(superclasses) > 0):
+		current = set_pop(superclasses)
+		if (dict_in(model["model"][current], name)):
+			return current
+	return ""
 
 Void function instantiate_attribute(model : Element, element : String, attribute_name : String, value : Element):
 	// Instantiate an attribute of something that needs to be instantiated

+ 4 - 7
bootstrap/object_operations.alc

@@ -37,9 +37,8 @@ Element function selectPossibleIncoming(model : Element, target : String, limit_
 	while (0 < list_len(limit_set)):
 		type = set_pop(limit_set)
 		elem = model_dict[type]
-		if (is_edge(elem)):
-			if (is_nominal_subtype(model, target, reverseKeyLookup(model_dict, read_edge_dst(elem)))):
-				set_add(result, type)
+		if (is_nominal_subtype(model, target, reverseKeyLookup(model_dict, read_edge_dst(elem)))):
+			set_add(result, type)
 	
 	return result
 
@@ -58,9 +57,8 @@ Element function selectPossibleOutgoing(model : Element, source : String, limit_
 	while (0 < list_len(limit_set)):
 		type = set_pop(limit_set)
 		elem = model_dict[type]
-		if (is_edge(elem)):
-			if (is_nominal_subtype(model, source, reverseKeyLookup(model_dict, read_edge_src(elem)))):
-				set_add(result, type)
+		if (is_nominal_subtype(model, source, reverseKeyLookup(model_dict, read_edge_src(elem)))):
+			set_add(result, type)
 	
 	return result
 
@@ -139,7 +137,6 @@ Element function getInstantiatableAttributes(model : Element, element : String):
 
 	return result
 
-// TODO Utility functions!
 String function reverseKeyLookup(dict : Element, element : Element):
 	Element elements
 	String name