Przeglądaj źródła

Merge remote-tracking branch 'yentl/master' into jit

jonathanvdc 8 lat temu
rodzic
commit
473d986847

+ 17 - 19
bootstrap/conformance_scd.alc

@@ -6,7 +6,7 @@ include "modelling.alh"
 
 Boolean function is_direct_instance(model : Element, instance : String, type : String):
 	// Just check whether or not the type mapping specifies the type as the type of the instance
-	return element_eq(dict_read_node(model["type_mapping"], model["model"][instance]), model["metamodel"]["model"][type])!
+	return value_eq(model["type_mapping"][instance], type)!
 
 Boolean function is_nominal_instance(model : Element, instance : String, type : String):
 	if (bool_not(dict_in(model["metamodel"]["model"], type))):
@@ -17,11 +17,11 @@ Boolean function is_nominal_instance(model : Element, instance : String, type :
 		// type is an edge, but we aren't
 		return False!
 
-	if (bool_not(dict_in_node(model["type_mapping"], model["model"][instance]))):
+	if (bool_not(dict_in(model["type_mapping"], instance))):
 		// doesn't even have a type
 		return False!
 
-	return is_nominal_subtype(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][instance])), type)!
+	return is_nominal_subtype(model["metamodel"], model["type_mapping"][instance], type)!
 
 Boolean function is_nominal_subtype(metamodel : Element, subclass : String, superclass : String):
 	if (element_eq(metamodel["model"][subclass], metamodel["model"][superclass])):
@@ -101,7 +101,6 @@ String function conformance_scd(model : Element):
 	metamodel = model["metamodel"]
 	typing = model["type_mapping"]
 
-
 	// Create dictionary with all associations and allowed cardinalities
 	if (list_len(model["model"]) > 0):
 		cardinalities = precompute_cardinalities(model)
@@ -110,24 +109,23 @@ String function conformance_scd(model : Element):
 		keys = dict_keys(model["model"])
 		while (0 < list_len(keys)):
 			model_name = set_pop(keys)
+			type_name = read_type(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))):
+			log("Check " + model_name)
+			log("   : " + type_name)
+
+			if (bool_not(dict_in(typing, model_name))):
 				return "Model has no type specified: " + model_info(model, model_name)!
 
-			if (bool_not(set_in_node(metamodel["model"], dict_read_node(typing, element)))):
+			if (bool_not(dict_in(metamodel["model"], typing[model_name]))):
 				return "Type of element not in specified metamodel: " + model_info(model, model_name)!
 
-			// This is true by definition of is_nominal_instance
-			//if (bool_not(is_nominal_instance(model, model_name, type_name))):
-			//	return "Element is not an instance of its specified type: " + model_info(model, model_name)!
-
 			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)))
+				src_metamodel = reverseKeyLookup(metamodel["model"], read_edge_src(metamodel["model"][typing[model_name]]))
+				dst_metamodel = reverseKeyLookup(metamodel["model"], read_edge_dst(metamodel["model"][typing[model_name]]))
 
 				if (bool_not(is_nominal_instance(model, src_model, src_metamodel))):
 					return "Source of model edge not typed by source of type: " + model_info(model, model_name)!
@@ -188,7 +186,7 @@ String function conformance_scd(model : Element):
 								error = (("Upper cardinality violation for incoming edge of type " + check_type) + " at ") + model_info(model, model_name)
 								return error!
 
-			constraint_function = read_attribute(metamodel, reverseKeyLookup(metamodel["model"], dict_read_node(typing, element)), "constraint")
+			constraint_function = read_attribute(metamodel, typing[model_name], "constraint")
 			if (element_neq(constraint_function, read_root())):
 				String result
 				result = constraint_function(model, model_name)
@@ -245,11 +243,11 @@ Element function generate_bottom_type_mapping(model : Element):
 	Element elem
 	elem_keys = dict_keys(model["model"])
 	while (0 < read_nr_out(elem_keys)):
-		elem = model["model"][set_pop(elem_keys)]
-		if (is_edge(elem)):
-			dict_add(tm, elem, mm["Edge"])
+		elem = set_pop(elem_keys)
+		if (is_edge(model["model"][elem])):
+			dict_add(tm, elem, "Edge")
 		else:
-			dict_add(tm, elem, mm["Node"])
+			dict_add(tm, elem, "Node")
 
 	return model!
 
@@ -259,7 +257,7 @@ String function model_info(model : Element, name : String):
 	String result
 	result = ""
 	result = (result + "\nModel name: ") + name
-	result = (result + "\nType: ") + cast_v2s(reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][name])))
+	result = (result + "\nType: ") + cast_v2s(model["type_mapping"][name])
 	result = (result + "\nValue: ") + cast_v2s(model["model"][name])
 	result = (result + "\nSource: ") + cast_v2s(reverseKeyLookup(model["model"], read_edge_src(model["model"][name])))
 	result = (result + "\nDestination: ") + cast_v2s(reverseKeyLookup(model["model"], read_edge_dst(model["model"][name])))

+ 4 - 1
bootstrap/library.alc

@@ -20,7 +20,10 @@ Element function export_node(model_name : String, model_reference : Element):
 		counter_i = counter_i + 1
 	
 	// current now contains the place where we should add the element
-	dict_add(current, splitted[length], model_reference)
+	if (bool_not(dict_in(current, splitted[length]))):
+		dict_add(current, splitted[length], model_reference)
+	else:
+		log("Could not export to that location: already in use!")
 
 	return model_reference!
 

+ 1 - 32
bootstrap/metamodels.alc

@@ -146,7 +146,7 @@ Element function constraint_call(model : Element, name : String):
 		return "Expected physical action value"!
 
 Element function initialize_SCD(location : String):
-	if (import_node(location) != read_root()):
+	if (element_neq(import_node(location), read_root())):
 		return import_node(location)!
 
 	Element scd
@@ -257,33 +257,6 @@ Element function initialize_PN(location_SCD : String, location_PN : String):
 
 	return pn!
 
-Element function initialize_FTG(location_SCD : String, location_FTG : String):
-	Element ftg
-	Element scd
-	String attr
-
-	scd = import_node(location_SCD)
-
-	ftg = instantiate_model(scd)
-	instantiate_node(ftg, "Class", "String")
-
-	instantiate_node(ftg, "Class", "Formalism")
-	attr = model_define_attribute(ftg, "Formalism", "location", "String")
-	instantiate_attribute(ftg, attr, "target_lower_cardinality", 1)
-	instantiate_attribute(ftg, attr, "target_upper_cardinality", 1)
-
-	instantiate_link(ftg, "Association", "Transformation", "Formalism", "Formalism")
-	attr = model_define_attribute(ftg, "Transformation", "location", "String")
-	instantiate_attribute(ftg, attr, "target_lower_cardinality", 1)
-	instantiate_attribute(ftg, attr, "target_upper_cardinality", 1)
-
-	// Add constraint on the String
-	add_constraint(ftg, "String", constraint_string)
-
-	export_node(location_FTG, ftg)
-
-	return ftg!
-
 Element function initialize_bottom(location_bottom : String):
 	Element ltm_bottom
 	ltm_bottom = instantiate_bottom()
@@ -306,19 +279,15 @@ Element function create_metamodels():
 	String location_SCD
 	String location_PN
 	String location_bottom
-	String location_FTG
 
 	location_SCD = "models/SimpleClassDiagrams"
 	location_PN = "models/PetriNets"
 	location_bottom = "models/LTM_bottom"
-	location_FTG = "models/FTG"
 
 	if (bool_not(dict_in(dict_read(dict_read(read_root(), "__hierarchy"), "models"), "SimpleClassDiagrams"))):
 		initialize_SCD(location_SCD)
 	if (bool_not(dict_in(dict_read(dict_read(read_root(), "__hierarchy"), "models"), "PetriNets"))):
 		initialize_PN(location_SCD, location_PN)
-	if (bool_not(dict_in(dict_read(dict_read(read_root(), "__hierarchy"), "models"), "FTG"))):
-		initialize_FTG(location_SCD, location_FTG)
 	if (bool_not(dict_in(dict_read(dict_read(read_root(), "__hierarchy"), "models"), "LTM_bottom"))):
 		initialize_bottom(location_bottom)
 

+ 21 - 9
bootstrap/model_management.alc

@@ -31,7 +31,7 @@ Element function model_fuse(models : Element):
 		keys = set_to_list(dict_keys(model["model"]))
 		while (read_nr_out(keys) > 0):
 			key = list_pop(keys, 0)
-			type = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][key]))
+			type = read_type(model, key)
 
 			if (is_edge(model["model"][key])):
 				String src
@@ -71,7 +71,7 @@ Element function model_copy(src_model : Element):
 
 			src = reverseKeyLookup(src_model["model"], read_edge_src(src_model["model"][name]))
 			dst = reverseKeyLookup(src_model["model"], read_edge_dst(src_model["model"][name]))
-			type = reverseKeyLookup(src_model["metamodel"]["model"], dict_read_node(src_model["type_mapping"], src_model["model"][name]))
+			type = read_type(src_model, name)
 
 			if (bool_and(dict_in(dst_model["model"], src), dict_in(dst_model["model"], dst))):
 				// All present, so create the link between them
@@ -81,12 +81,12 @@ Element function model_copy(src_model : Element):
 
 		elif (has_value(src_model["model"][name])):
 			// Has a value, so copy that as well
-			type = reverseKeyLookup(src_model["metamodel"]["model"], dict_read_node(src_model["type_mapping"], src_model["model"][name]))
+			type = read_type(src_model, name)
 			instantiate_value(dst_model, type, name, src_model["model"][name])
 
 		else:
 			// Is a node
-			type = reverseKeyLookup(src_model["metamodel"]["model"], dict_read_node(src_model["type_mapping"], src_model["model"][name]))
+			type = read_type(src_model, name)
 			instantiate_node(dst_model, type, name)
 
 	return dst_model!
@@ -104,17 +104,17 @@ Element function model_retype_on_name(model : Element, new_MM : Element, operati
 		key = set_pop(keys)
 		if (dict_in(model["model"], key)):
 			// Check if the element is still there, as a delete of a node might remove all attached links automatically
-			type = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][key]))
+			type = read_type(model, key)
 
 			if (operation == "+"):
 				// Keep all, but augment typename
-				dict_delete_node(model["type_mapping"], model["model"][key])
-				dict_add(model["type_mapping"], model["model"][key], new_MM["model"][name + type])
+				dict_delete(model["type_mapping"], key)
+				dict_add(model["type_mapping"], key, name + type)
 			elif (operation == "-"):
 				// Keep only if typename beginning matches and remove from typename
 				if (string_startswith(type, name)):
-					dict_delete_node(model["type_mapping"], model["model"][key])
-					dict_add(model["type_mapping"], model["model"][key], new_MM["model"][string_substr(type, length, string_len(type))])
+					dict_delete(model["type_mapping"], key)
+					dict_add(model["type_mapping"], key, string_substr(type, length, string_len(type)))
 				else:
 					model_delete_element(model, key)
 
@@ -198,7 +198,19 @@ Element function model_split(src_model : Element, target_metamodel : Element, re
 				if (bool_and(dict_in(mapping, src), dict_in(mapping, dst))):
 					// All present, so create the link between them
 					dict_add(mapping, name, instantiate_link(dst_model, new_type, "", mapping[src], mapping[dst]))
+				elif (bool_not(bool_or(set_in(queue, src), set_in(queue, dst)))):
+					// Source/target not in the queue, but we need it to split!
+					// This is an error as it indicates problems with links crossing different formalisms
+					log("ERROR: source/target of link to be included is not included!")
+					log("Source: " + src)
+					log("  type: " + read_type(src_model, src))
+					log("Destination: " + dst)
+					log("  type: " + read_type(src_model, dst))
+					log("For link: " + name)
+					log("  type: " + type)
+					return create_node()!
 				else:
+					// Still source or destination in the queue, so we wait for that
 					list_append(queue, name)
 
 			elif (has_value(src_model["model"][name])):

+ 44 - 35
bootstrap/modelling.alc

@@ -24,7 +24,6 @@ Element function instantiate_bottom():
 	// Add an empty model and empty type mapping
 	dict_add(new_model, "model", create_node())
 	dict_add(new_model, "type_mapping", create_node())
-	dict_add(new_model, "__kind", "formalism")
 
 	// Return the created model
 	return new_model!
@@ -84,10 +83,10 @@ Void function retype(model : Element, element : String, type : String):
 	// Retype a model, deleting any previous type the element had
 	// The type string is evaluated in the metamodel previously specified
 
-	if (dict_in_node(model["type_mapping"], model["model"][element])):
-		dict_delete_node(model["type_mapping"], model["model"][element])
+	if (dict_in(model["type_mapping"], element)):
+		dict_delete(model["type_mapping"], element)
 
-	dict_add(model["type_mapping"], model["model"][element], model["metamodel"]["model"][type])
+	dict_add(model["type_mapping"], element, type)
 
 	return!
 
@@ -132,6 +131,7 @@ String function instantiate_value(model : Element, type_name : String, instance_
 String function find_attribute_type(model : Element, elem : String, name : String):
 	String mm_elem
 	String direct_type
+	String result
 
 	direct_type = read_type(model, elem)
 
@@ -144,7 +144,8 @@ String function find_attribute_type(model : Element, elem : String, name : Strin
 		// Couldn't find element, so is not allowed!
 		return ""!
 	else:
-		return reverseKeyLookup(model["metamodel"]["model"], dict_read_edge(model["metamodel"]["model"][mm_elem], name))!
+		result = reverseKeyLookup(model["metamodel"]["model"], dict_read_edge(model["metamodel"]["model"][mm_elem], name))
+		return result!
 
 Element function get_superclasses(model : Element, name : String):
 	Element result
@@ -152,13 +153,13 @@ Element function get_superclasses(model : Element, name : String):
 	Integer j
 	Integer num_edges
 	Element edge
-	Element elem
+	String elem
 	Element nodes
 	Element inheritance
 
 	nodes = create_node()
-	set_add(nodes, model["model"][name])
-	inheritance = model["metamodel"]["model"]["Inheritance"]
+	set_add(nodes, name)
+	inheritance = "Inheritance"
 
 	// Initialize empty set
 	result = create_node()
@@ -166,15 +167,15 @@ Element function get_superclasses(model : Element, name : String):
 
 	while (list_len(nodes) > 0):
 		elem = set_pop(nodes)
-		if (bool_not(set_in(result, reverseKeyLookup(model["model"], elem)))):
-			create_edge(result, reverseKeyLookup(model["model"], elem))
+		if (bool_not(set_in(result, elem))):
+			create_edge(result, elem)
 			// Read out all outgoing edges
-			num_edges = read_nr_out(elem)
+			num_edges = read_nr_out(model["model"][elem])
 			j = 0
 			while (j < num_edges):
-				edge = read_out(elem, j)
-				if (element_eq(dict_read_node(model["type_mapping"], edge), inheritance)):
-					set_add(nodes, read_edge_dst(edge))
+				edge = read_out(model["model"][elem], j)
+				if (value_eq(model["type_mapping"][reverseKeyLookup(model["model"], edge)], inheritance)):
+					set_add(nodes, reverseKeyLookup(model["model"], read_edge_dst(edge)))
 				j = j + 1
 
 	return result!
@@ -212,10 +213,10 @@ Void function instantiate_attribute(model : Element, element : String, attribute
 		log("Could not find attribute " + cast_v2s(attribute_name))
 		log("For element " + element)
 		return!
-		
-	// Make a copy of the value, as it is likely that this value is reused later on
-	value = create_value(value)
 
+	if (has_value(value)):
+		value = create_value(value)
+		
 	attr_name = model_add_value(model, (element + ".") + attribute_name, value)
 	retype(model, attr_name, reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(model["metamodel"]["model"][attr_type])))
 	instantiate_link(model, attr_type, "", element, attr_name)
@@ -297,7 +298,7 @@ String function instantiate_link(model : Element, type : String, name : String,
 Void function model_delete_element(model : Element, name : String):
 	// Remove the link
 	// 1) from the type mapping
-	dict_delete_node(model["type_mapping"], model["model"][name])
+	dict_delete(model["type_mapping"], name)
 
 	// 2) from the model
 	delete_element(model["model"][name])
@@ -317,9 +318,10 @@ Element function read_attribute(model : Element, element : String, attribute : S
 	Integer i
 	Integer count
 	Element edge
-	Element edge_type
+	String edge_type_name
 	Element elem
 	Element typing
+	Element name
 
 	elem = model["model"][element]
 	typing = model["type_mapping"]
@@ -328,9 +330,10 @@ Element function read_attribute(model : Element, element : String, attribute : S
 	i = 0
 	while (i < count):
 		edge = read_out(elem, i)
-		if (dict_in_node(typing, edge)):
-			edge_type = dict_read_node(typing, edge)
-			if (element_eq(edge_type, dict_read_edge(read_edge_src(edge_type), attribute))):
+		name = reverseKeyLookup(model["model"], edge)
+		if (dict_in(typing, name)):
+			edge_type_name = typing[name]
+			if (edge_type_name == reverseKeyLookup(model["metamodel"]["model"], dict_read_edge(read_edge_src(model["metamodel"]["model"][edge_type_name]), attribute))):
 				return read_edge_dst(edge)!
 		i = i + 1
 
@@ -347,8 +350,8 @@ Void function unset_attribute(model : Element, element : String, attribute : Str
 
 	while (list_len(attr_links) > 0):
 		attr_link = set_pop(attr_links)
-		dict_delete_node(model["type_mapping"], read_edge_dst(model["model"][attr_link]))
-		dict_delete_node(model["type_mapping"], model["model"][attr_link])
+		dict_delete(model["type_mapping"], reverseKeyLookup(model["model"], read_edge_dst(model["model"][attr_link])))
+		dict_delete(model["type_mapping"], attr_link)
 		dict_delete_node(model["model"], reverseKeyLookup(model["model"], read_edge_dst(model["model"][attr_link])))
 		delete_element(model["model"][attr_link])
 
@@ -359,22 +362,29 @@ Void function add_AL_links(model : Element, list : Element, element : Element, t
 		return!
 
 	Element link
+	String link_name
+
 	link = dict_read_edge(element, linkname)
+	link_name = "__" + cast_id2s(link)
 
 	// The link
-	dict_add(model["model"], "__" + cast_id2s(link), link)
-	dict_add(model["type_mapping"], link, model["metamodel"]["model"][(type + "_") + linkname])
+	dict_add(model["model"], link_name, link)
+	dict_add(model["type_mapping"], link_name, (type + "_") + linkname)
 
 	// The name link
 	link = read_out(link, 0)
-	dict_add(model["model"], "__" + cast_id2s(link), link)
-	dict_add(model["type_mapping"], link, model["metamodel"]["model"]["to_str"])
+	link_name = "__" + cast_id2s(link)
+
+	dict_add(model["model"], link_name, link)
+	dict_add(model["type_mapping"], link_name, "to_str")
 
 	// The name node
 	link = read_edge_dst(link)
+	link_name = "__" + cast_id2s(link)
+
 	if (bool_not(set_in_node(model["model"], link))):
-		dict_add(model["model"], "__" + cast_id2s(link), link)
-		dict_add(model["type_mapping"], link, model["metamodel"]["model"]["String"])
+		dict_add(model["model"], link_name, link)
+		dict_add(model["type_mapping"], link_name, "String")
 
 	// Now add the destination to the worker list
 	Element node
@@ -391,6 +401,7 @@ String function add_AL(model : Element, element : Element):
 	Element work_node
 	Element elem
 	String type
+	String elem_name
 
 	todo = create_node()
 	node = create_node()
@@ -412,8 +423,9 @@ String function add_AL(model : Element, element : Element):
 					type = "Any"
 
 			// Add the node itself
-			dict_add(model["model"], "__" + cast_id2s(elem), elem)
-			dict_add(model["type_mapping"], elem, model["metamodel"]["model"][type])
+			elem_name = "__" + cast_id2s(elem)
+			dict_add(model["model"], elem_name, elem)
+			dict_add(model["type_mapping"], elem_name, type)
 
 			// Now add its edges
 			if (type == "if"):
@@ -572,15 +584,12 @@ Element function construct_model_raw(metamodel : Element):
 			input()
 			add_constraint(model, input(), construct_function())
 		elif (command == "import_node"):
-			log("Dropping import_node as not allowed")
 			input()
 			input()
 		elif (command == "export_node"):
-			log("Dropping export_node as not allowed")
 			input()
 			input()
 		elif (command == "instantiate_model"):
-			log("Dropping instantiate_model as not allowed")
 			input()
 			input()
 		else:

+ 24 - 19
bootstrap/object_operations.alc

@@ -4,7 +4,6 @@ include "constructors.alh"
 include "modelling.alh"
 
 Element function allInstances(model : Element, type_name : String):
-	Element type_mapping
 	Element result
 	Element type
 
@@ -106,7 +105,7 @@ Element function getAttributeList(model : Element, element : String):
 	String attr_type
 
 	result = create_node()
-	types = get_superclasses(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][element])))
+	types = get_superclasses(model["metamodel"], read_type(model, element))
 
 	while (read_nr_out(types) > 0):
 		type = set_pop(types)
@@ -147,17 +146,22 @@ Element function getInstantiatableAttributes(model : Element, element : String):
 	return result!
 
 String function reverseKeyLookup(dict : Element, element : Element):
-	Element elements
-	String name
-
-	elements = dict_keys(dict)
-	while (0 < list_len(elements)):
-		name = set_pop(elements)
-		if (element_eq(dict[name], element)):
-			return name!
-
+	Integer nr_in
+	Integer nr_out
+	Integer counter
+	Element link
+
+	nr_in = read_nr_in(element)
+	counter = 0
+	while (counter < nr_in):
+		if (element_eq(read_edge_src(read_in(element, counter)), dict)):
+			// Got a match
+			return (read_edge_dst(read_out(read_in(element, counter), 0)))!
+
+		counter = counter + 1
+	
 	return string_join(string_join("(unknown: ", cast_e2s(element)), " )")!
-
+	
 String function print_dict(dict : Element):
 	Element keys
 	Element key
@@ -215,7 +219,7 @@ Element function allowedAssociationsBetween(model : Element, src : String, dst :
 	String dst_name
 
 	result = create_node()
-	type = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][src]))
+	type = read_type(model, src)
 	all_types = get_superclasses(model["metamodel"], type)
 
 	while (read_nr_out(all_types) > 0):
@@ -241,20 +245,21 @@ Element function allowedAssociationsBetween(model : Element, src : String, dst :
 String function read_type(model : Element, name : String):
 	String result
 
-	Element mm
 	Element tm
 
-	mm = model["metamodel"]["model"]
 	if (dict_in(model["model"], name)):
-		if (dict_in_node(model["type_mapping"], model["model"][name])):
-			tm = dict_read_node(model["type_mapping"], model["model"][name])
+		if (dict_in(model["type_mapping"], name)):
+			result = model["type_mapping"][name]
 			
-			result = reverseKeyLookup(mm, tm)
-			if (element_eq(mm[result], tm)):
+			if (dict_in(model["metamodel"]["model"], result)):
 				return result!
 			else:
+				log("Could not find " + result)
 				return ""!
 		else:
+			log("Untyped " + name)
+			log("Type mapping: " + dict_to_string(model["type_mapping"]))
 			return ""!
 	else:
+		log("Couldn't find " + name)
 		return ""!

+ 2 - 3
bootstrap/ramify.alc

@@ -135,9 +135,8 @@ Element function ramify(model : Element):
 		key = set_pop(keys)
 		entry = old_m[key]
 
-		type_name = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], entry))
+		type_name = read_type(model, key)
 		if (type_name == "Class"):
-			log("Added Pre_" + key)
 			instantiate_node(new_model, type_name, "Pre_" + key)
 			instantiate_node(new_model, type_name, "Post_" + key)
 
@@ -166,7 +165,7 @@ Element function ramify(model : Element):
 
 	while (read_nr_out(to_link) > 0):
 		entry = set_pop(to_link)
-		type_name = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], entry))
+		type_name = read_type(model, reverseKeyLookup(model["model"], entry))
 		// Primitive values themselves are not copied, so skip that here
 
 		// An instance link, so just copy over (don't make element of Root Element), and don't even copy if it is lower cardinality

+ 5 - 5
bootstrap/transform.alc

@@ -70,7 +70,7 @@ Element function get_possible_bindings(host_model : Element, schedule_model : El
 
 	options = create_node()
 
-	typename = reverseKeyLookup(schedule_model["metamodel"]["model"], dict_read_node(schedule_model["type_mapping"], schedule_model["model"][current_element]))
+	typename = read_type(schedule_model, current_element)
 	original_typename = string_substr(typename, 4, string_len(typename))
 
 	if (is_edge(schedule_model["model"][current_element])):
@@ -292,7 +292,7 @@ Void function rewrite(host_model : Element, schedule_model : Element, RHS : Stri
 			value_function = read_attribute(schedule_model, RHS_map[label], "value")
 			value = value_function(host_model, mapping)
 
-			typename = reverseKeyLookup(schedule_model["metamodel"]["model"], dict_read_node(schedule_model["type_mapping"], schedule_model["model"][RHS_map[label]]))
+			typename = read_type(schedule_model, RHS_map[label])
 			original_typename = string_substr(typename, 5, string_len(typename))
 			new_name = instantiate_value(host_model, original_typename, "", value)
 			dict_add(new_mapping, label, new_name)
@@ -304,7 +304,7 @@ Void function rewrite(host_model : Element, schedule_model : Element, RHS : Stri
 			// First check whether both source and destination are already created
 			if (bool_and(dict_in(new_mapping, src), dict_in(new_mapping, dst))):
 				// Both are present, so we can make the link
-				typename = reverseKeyLookup(schedule_model["metamodel"]["model"], dict_read_node(schedule_model["type_mapping"], schedule_model["model"][RHS_map[label]]))
+				typename = read_type(schedule_model, RHS_map[label])
 				original_typename = string_substr(typename, 5, string_len(typename))
 				new_name = instantiate_link(host_model, original_typename, "", new_mapping[src], new_mapping[dst])
 				dict_add(new_mapping, label, new_name)
@@ -314,7 +314,7 @@ Void function rewrite(host_model : Element, schedule_model : Element, RHS : Stri
 		else:
 			// Node
 			// Create the node and add it
-			typename = reverseKeyLookup(schedule_model["metamodel"]["model"], dict_read_node(schedule_model["type_mapping"], schedule_model["model"][RHS_map[label]]))
+			typename = read_type(schedule_model, RHS_map[label])
 			original_typename = string_substr(typename, 5, string_len(typename))
 			new_name = instantiate_node(host_model, original_typename, "")
 			dict_add(new_mapping, label, new_name)
@@ -373,7 +373,7 @@ Boolean function transform_composite(host_model : Element, schedule_model : Elem
 	current = set_pop(allAssociationDestinations(schedule_model, composite, "Initial"))
 	while (is_nominal_instance(schedule_model, current, "Rule")):
 		// Still a rule that we must execute
-		typename = reverseKeyLookup(schedule_model["metamodel"]["model"], dict_read_node(schedule_model["type_mapping"], schedule_model["model"][current]))
+		typename = read_type(schedule_model, current)
 		if (typename == "Atomic"):
 			result = transform_atomic(host_model, schedule_model, current)
 		elif (typename == "Query"):

+ 105 - 47
core/core_algorithm.alc

@@ -12,25 +12,29 @@ include "metamodels.alh"
 
 Element core = ?
 
+String core_location = "models/CoreFormalism"
+String core_model_location = "models/core"
+
 Void function main():
 	// Initialize the Core Formalism
-	String core_location
 	String core_model
-	String core_model_location
 	String core_formalism_model
-	String scd_location
 	String scd_model
 	String admin_group
 	String admin_user
 	String nobody_group
+	String instance_of
+	String core_formalism
+	Element scd
 
+	String scd_location
 	scd_location = "models/SimpleClassDiagrams"
-	core_location = "models/CoreFormalism"
-	core_model_location = "models/core"
+	scd = import_node(scd_location)
 
 	// Create the Model itself and make public
-	core = instantiate_model(import_node(core_location))
-	export_node(core_model_location, core)
+	core_formalism = import_node(core_location)
+	core = instantiate_model(core_formalism)
+	export_node(core_model_location, core["model"])
 
 	// Switch all new users to the user_function
 	// This accesses the bootstrap level, so do not change this unless you know what you are doing
@@ -79,9 +83,10 @@ Void function main():
 	// Add the SimpleClassDiagrams formalism already
 	scd_model = instantiate_node(core, "Model", "")
 	instantiate_attribute(core, scd_model, "name", "SimpleClassDiagrams")
-	instantiate_attribute(core, scd_model, "location", scd_location)
+	instantiate_attribute(core, scd_model, "location", scd_location + "/model")
 	instantiate_attribute(core, scd_model, "permissions", "221")
-	instantiate_link(core, "instanceOf", "", scd_model, scd_model)
+	instance_of = instantiate_link(core, "instanceOf", "", scd_model, scd_model)
+	instantiate_attribute(core, instance_of, "type_mapping", scd["type_mapping"])
 
 	// Make necessary links for the formalism to the owners
 	instantiate_link(core, "group", "", scd_model, admin_group)
@@ -90,9 +95,10 @@ Void function main():
 	// Add the core formalism already
 	core_formalism_model = instantiate_node(core, "Model", "")
 	instantiate_attribute(core, core_formalism_model, "name", "CoreFormalism")
-	instantiate_attribute(core, core_formalism_model, "location", core_location)
+	instantiate_attribute(core, core_formalism_model, "location", core_location + "/model")
 	instantiate_attribute(core, core_formalism_model, "permissions", "221")
-	instantiate_link(core, "instanceOf", "", core_formalism_model, scd_model)
+	instance_of = instantiate_link(core, "instanceOf", "", core_formalism_model, scd_model)
+	instantiate_attribute(core, instance_of, "type_mapping", core_formalism["type_mapping"])
 
 	// Make necessary links for the formalism to the owners
 	instantiate_link(core, "group", "", core_formalism_model, admin_group)
@@ -103,7 +109,8 @@ Void function main():
 	instantiate_attribute(core, core_model, "name", "core")
 	instantiate_attribute(core, core_model, "location", core_model_location)
 	instantiate_attribute(core, core_model, "permissions", "200")
-	instantiate_link(core, "instanceOf", "", core_model, core_formalism_model)
+	instance_of = instantiate_link(core, "instanceOf", "", core_model, core_formalism_model)
+	instantiate_attribute(core, instance_of, "type_mapping", core["type_mapping"])
 
 	// Make necessary links for the formalism to the owners
 	instantiate_link(core, "group", "", core_model, admin_group)
@@ -118,6 +125,40 @@ Void function main():
 	// Note that if there are no admin users left, it will be very difficult to manage, as nobody will have admin permissions!
 	return !
 
+String function get_instanceOf_link(model_id : String):
+	Element all_links
+	String choice
+
+	all_links = allOutgoingAssociationInstances(core, model_id, "instanceOf")
+
+	if (read_nr_out(all_links) > 1):
+		log("WARNING: multiple instanceOf relations were detected for this model; picking one at random!")
+	elif (read_nr_out(all_links) == 0):
+		log("ERROR: untyped model!")
+	
+	choice = set_pop(allOutgoingAssociationInstances(core, model_id, "instanceOf"))
+
+	return choice!
+
+Element function get_full_model(model_id : String):
+	Element m
+	Element all_links
+	String choice
+
+	choice = get_instanceOf_link(model_id)
+
+	m = create_node()
+	dict_add(m, "model", import_node(read_attribute(core, model_id, "location")))
+	dict_add(m, "type_mapping", read_attribute(core, choice, "type_mapping"))
+
+	if (readAssociationDestination(core, choice) == model_id):
+		// Found the meta-circular level, so we can stop!
+		dict_add(m, "metamodel", m)
+	else:
+		dict_add(m, "metamodel", get_full_model(readAssociationDestination(core, choice)))
+
+	return m!
+
 Integer function get_relation_to_model(user_id : String, model_id : String):
 	if (set_in(allAssociationDestinations(core, model_id, "owner"), user_id)):
 		// We are the owner
@@ -224,7 +265,9 @@ Element function user_function():
 	exec(root["bootstrap/transform.alc"]["initializers"])
 	exec(root["bootstrap/conformance_scd.alc"]["initializers"])
 	exec(root["core/core_algorithm.alc"]["initializers"])
-	core = import_node("models/core")
+
+	// Load in a hard-reference to the previously created model
+	core = import_node(core_model_location)
 
 	output("Log on as which user?")
 	username = input()
@@ -301,9 +344,10 @@ String function get_group_id(name : String):
 Void function model_create(model : Element, name : String, user_id : String, type_id : String, kind : String):
 	String location
 	String model_id
+	String instance_of
 
 	location = "/models/" + cast_id2s(model)
-	export_node(location, model)
+	export_node(location, model["model"])
 
 	// Manage meta-info
 	model_id = instantiate_node(core, kind, "")
@@ -312,22 +356,40 @@ Void function model_create(model : Element, name : String, user_id : String, typ
 	instantiate_attribute(core, model_id, "permissions", "200")
 	instantiate_link(core, "owner", "", model_id, user_id)
 	instantiate_link(core, "group", "", model_id, get_group_id("nobody"))
-	instantiate_link(core, "instanceOf", "", model_id, type_id)
+	instance_of = instantiate_link(core, "instanceOf", "", model_id, type_id)
+	instantiate_attribute(core, instance_of, "type_mapping", model["type_mapping"])
 
 	return!
 
 Void function model_overwrite(model : Element, model_id : String):
 	String location
+	String instanceOf_link
 
 	location = "/models/" + cast_id2s(model)
-	export_node(location, model)
+	export_node(location, model["model"])
 
 	// Change location in meta-data
 	unset_attribute(core, model_id, "location")
 	instantiate_attribute(core, model_id, "location", location)
 
+	instanceOf_link = get_instanceOf_link(model_id)
+	unset_attribute(core, instanceOf_link, "type_mapping")
+	instantiate_attribute(core, instanceOf_link, "type_mapping", model["type_mapping"])
+
 	return!
 
+Boolean function check_is_typed_by(model_id : String, metamodel_id : String):
+	// TODO check if there is actually an instanceOf link between them
+	//    --> quick check!
+
+	return True!
+
+Boolean function check_conformance(model_id : String):
+	// TODO check if it actually conforms, considering that instanceOf link
+	//    --> in-depth check
+
+	return True!
+
 Void function user_function_skip_init(user_id : String):
 	String cmd
 
@@ -402,7 +464,8 @@ Void function user_function_skip_init(user_id : String):
 						// Model doesn't exist yet
 						output("Waiting for model constructors...")
 
-						new_model = construct_model_raw(import_node(read_attribute(core, type_id, "location")))
+						new_model = construct_model_raw(get_full_model(type_id))
+
 						model_create(new_model, name, user_id, type_id, "Model")
 						output("Model upload success!")
 					else:
@@ -438,13 +501,23 @@ Void function user_function_skip_init(user_id : String):
 						inputs = create_node()
 						while (read_nr_out(sources) > 0):
 							source = set_pop(sources)
-							log("Got source link: " + cast_e2s(source))
 							output(string_join("Which model to bind for source element ", read_attribute(core, source, "name")))
 							source_model_name = input()
 							name_id = get_model_id(source_model_name)
 							if (name_id != ""):
 								if (allow_read(user_id, name_id)):
-									dict_add(inputs, read_attribute(core, source, "name"), source_model_name)
+									// Check for conformance to the specified metamodel!
+									Element specified_model
+									// TODO Maybe find out which conformance relation to use, as there might be multiple!
+									if (check_is_typed_by(name_id, source)):
+										if (check_conformance(name_id)):
+											dict_add(inputs, read_attribute(core, source, "name"), source_model_name)
+										else:
+											output("Model has correct type but does not conform completely!")
+											set_add(sources, source)
+									else:
+										output("Model has different type!")
+										set_add(sources, source)
 								else:
 									output("Permission denied")
 									set_add(sources, source)
@@ -489,21 +562,20 @@ Void function user_function_skip_init(user_id : String):
 							String ramified_metamodel_id
 							Boolean result
 
-							schedule_model = import_node(read_attribute(core, transformation_id, "location"))
+							schedule_model = get_full_model(transformation_id)
+
 							// Need to fall back to the default approach, which is way slower
 							// 1) Create empty instance of merged metamodel
 
 							ramified_metamodel_id = set_pop(followAssociation(core, transformation_id, "instanceOf"))
-							log("Got ramified MM: " + ramified_metamodel_id)
 							trace_links = allOutgoingAssociationInstances(core, ramified_metamodel_id, "tracability")
-							log("With tracability links: " + set_to_string(trace_links))
 							merged_metamodel_id = ""
 							while (read_nr_out(trace_links) > 0):
 								trace_link_id = set_pop(trace_links)
 								if (value_eq(read_attribute(core, trace_link_id, "type"), "RAMified")):
 									merged_metamodel_id = readAssociationDestination(core, trace_link_id)
 							if (merged_metamodel_id != ""):
-								merged_model = instantiate_model(import_node(read_attribute(core, merged_metamodel_id, "location")))
+								merged_model = instantiate_model(get_full_model(merged_metamodel_id))
 
 								// 2) Merge source models
 
@@ -515,7 +587,7 @@ Void function user_function_skip_init(user_id : String):
 								input_keys = dict_keys(inputs)
 								while (read_nr_out(input_keys) > 0):
 									key = set_pop(input_keys)
-									model_join(merged_model, import_node(read_attribute(core, get_model_id(inputs[key]), "location")), key + "/")
+									model_join(merged_model, get_full_model(get_model_id(inputs[key])), key + "/")
 
 								// 3) Transform
 
@@ -530,23 +602,16 @@ Void function user_function_skip_init(user_id : String):
 								output_keys = dict_keys(outputs)
 								while (read_nr_out(output_keys) > 0):
 									key = set_pop(output_keys)
-									log("Key: " + key)
-									log("Model id: " + get_model_id(key))
 									desired_metamodel_id = get_model_id(key)
-									log("Instance of: " + desired_metamodel_id)
-									split_off_model = model_split(merged_model, import_node(read_attribute(core, desired_metamodel_id, "location")), key + "/")
+									split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/")
 
 									// Check if the destination model already exists
 									if (get_model_id(outputs[key]) == ""):
 										// New model
 										model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model")
-										log("Created new model with name: " + cast_v2s(outputs[key]))
-										log("Split off model has size: " + cast_v2s(read_nr_out(split_off_model["model"])))
 									else:
 										// Model exists, so we overwrite
 										model_overwrite(split_off_model, get_model_id(outputs[key]))
-										log("Overwrite existing model with name: " + cast_v2s(outputs[key]))
-										log("Split off model has size: " + cast_v2s(read_nr_out(split_off_model["model"])))
 							else:
 								output("Could not resolve intermediate merged metamodel")
 						elif (exact_type == "ActionLanguage"):
@@ -571,7 +636,7 @@ Void function user_function_skip_init(user_id : String):
 				if (allow_write(user_id, model_id)):
 					if (allow_read(user_id, set_pop(followAssociation(core, model_id, "instanceOf")))):
 						output("Waiting for model constructors...")
-						new_model = construct_model_raw(import_node(read_attribute(core, set_pop(followAssociation(core, model_id, "instanceOf")), "location")))
+						new_model = construct_model_raw(get_full_model(set_pop(followAssociation(core, model_id, "instanceOf"))))
 						model_overwrite(new_model, model_id)
 						output("Model overwrite success!")
 					else:
@@ -593,7 +658,7 @@ Void function user_function_skip_init(user_id : String):
 				if (allow_read(user_id, model_id)):
 					type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf"))
 					if (allow_read(user_id, type_id)):
-						modify(import_node(read_attribute(core, model_id, "location")), allow_write(user_id, model_id))
+						modify(get_full_model(model_id), allow_write(user_id, model_id))
 					else:
 						output("Permission denied")
 				else:
@@ -633,7 +698,6 @@ Void function user_function_skip_init(user_id : String):
 			String group
 			String name
 			String type
-			String size
 
 			models = allInstances(core, "Model")
 			while (read_nr_out(models) > 0):
@@ -642,9 +706,8 @@ Void function user_function_skip_init(user_id : String):
 				owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name")
 				group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name")
 				name = read_attribute(core, m, "name")
-				size = cast_i2s(read_nr_out(dict_read(import_node(read_attribute(core, m, "location")), "model")))
 				type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")
-				output((((((((((("  " + permissions) + "  ") + owner) + " ") + group) + "    ") + size) + "   ") + name) + " : ") + type)
+				output((((((((("  " + permissions) + "  ") + owner) + " ") + group) + "   ") + name) + " : ") + type)
 
 		elif (cmd == "transformation_add_MT_language"):
 			// Create a model transformation language from a set of input and output formalisms
@@ -672,7 +735,7 @@ Void function user_function_skip_init(user_id : String):
 					if (allow_read(user_id, model_id)):
 						type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf"))
 						if (bool_or(old_type_id == "", type_id == old_type_id)):
-							set_add(all_formalisms, create_tuple(name, import_node(read_attribute(core, model_id, "location"))))
+							set_add(all_formalisms, create_tuple(name, get_full_model(model_id)))
 							old_type_id = type_id
 						elif (old_type_id != type_id):
 							// Already have a previous type_id and now another: CLASH
@@ -736,7 +799,7 @@ Void function user_function_skip_init(user_id : String):
 					target_model_id = get_model_id(target_model_name)
 					if (target_model_id == ""):
 						// New model, so everything is fine
-						target_model = ramify(import_node(read_attribute(core, merged_model_id, "location")))
+						target_model = ramify(get_full_model(merged_model_id))
 						model_create(target_model, target_model_name, user_id, set_pop(allAssociationDestinations(core, merged_model_id, "instanceOf")), "Model")
 						target_model_id = get_model_id(target_model_name)
 						tracability_link = instantiate_link(core, "tracability", "", target_model_id, merged_model_id)
@@ -744,7 +807,7 @@ Void function user_function_skip_init(user_id : String):
 					else:
 						// Existing model, so overwrite
 						if (allow_write(user_id, target_model_id)):
-							target_model = ramify(import_node(read_attribute(core, merged_model_id, "location")))
+							target_model = ramify(get_full_model(merged_model_id))
 							model_overwrite(target_model, target_model_id)
 							model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, target_model_id, "tracability")))
 							tracability_link = instantiate_link(core, "tracability", "", target_model_id, merged_model_id)
@@ -837,7 +900,7 @@ Void function user_function_skip_init(user_id : String):
 						String new_model
 						// Finished with all information, now create the model itself!
 						output("Waiting for model constructors...")
-						new_model = construct_model_raw(import_node(read_attribute(core, ramified_metamodel_id, "location")))
+						new_model = construct_model_raw(get_full_model(ramified_metamodel_id))
 						model_create(new_model, name, user_id, ramified_metamodel_id, "ModelTransformation")
 						model_id = get_model_id(name)
 
@@ -881,7 +944,6 @@ Void function user_function_skip_init(user_id : String):
 			String group
 			String name
 			String type
-			String size
 
 			models = allInstances(core, "Transformation")
 			while (read_nr_out(models) > 0):
@@ -890,9 +952,8 @@ Void function user_function_skip_init(user_id : String):
 				owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name")
 				group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name")
 				name = read_attribute(core, m, "name")
-				size = cast_i2s(read_nr_out(dict_read(import_node(read_attribute(core, m, "location")), "model")))
 				type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")
-				output((((((((((("  " + permissions) + "  ") + owner) + " ") + group) + "    ") + size) + "   ") + ((("[" + read_type(core, m)) + "] ") + name)) + " : ") + type)
+				output((((((((("  " + permissions) + "  ") + owner) + " ") + group) + "   ") + ((("[" + read_type(core, m)) + "] ") + name)) + " : ") + type)
 
 		elif (cmd == "permission_modify"):
 			String permissions
@@ -1084,9 +1145,6 @@ Void function user_function_skip_init(user_id : String):
 
 						overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
 
-						log("Size of overlap: " + cast_v2s(read_nr_out(overlap)))
-						log("Overlap: " + set_to_string(overlap))
-
 						if (read_nr_out(overlap) == 0):
 							instantiate_link(core, "belongsTo", "", other_user_id, group_id)
 							output("User added to the group!")

+ 20 - 1
core/core_formalism.mvc

@@ -40,6 +40,23 @@ SimpleClassDiagrams CoreFormalism {
         $
     }
 
+    Class TypeMapping {
+        $
+            if (has_value(self)):
+                return "TypeMapping cannot have a value for root node!"!
+            Element keys
+            String key
+            keys = dict_keys(self)
+            while (read_nr_out(keys) > 0):
+                key = set_pop(keys)
+                if (bool_not(is_physical_string(key))):
+                    return ("Key on type mapping is not a string: " + cast_e2s(key))!
+                elif (bool_not(is_physical_string(self[key]))):
+                    return ("Value on type mapping is not a string for key " + cast_e2s(key))!
+            return "OK"!
+        $
+    }
+
     Class User {
         name : String
         password : String
@@ -59,7 +76,9 @@ SimpleClassDiagrams CoreFormalism {
         permissions : Permissions
     }
 
-    Association instanceOf (Model, Model) {}
+    Association instanceOf (Model, Model) {
+        type_mapping : TypeMapping
+    }
 
     Association owner (Model, User) {
         target_lower_cardinality = 1

+ 14 - 21
core/mini_modify.alc

@@ -77,6 +77,7 @@ Element function modify(model : Element, write : Boolean):
 							instantiate_node(model, mm_type_name, element_name)
 							output("Instantiation successful!")
 				else:
+					log("Could not find element in " + set_to_string(dict_keys(model["metamodel"]["model"])))
 					output("Unknown type specified; aborting")
 			else:
 				output("Permission denied")
@@ -209,7 +210,7 @@ Element function modify(model : Element, write : Boolean):
 				v_m = set_pop(keys_m)
 				// Filter out anonymous objects
 				if (bool_not(string_startswith(v_m, "__"))):
-					typename = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][v_m]))
+					typename = read_type(model, v_m)
 					output((("  " + v_m) + " : ") + typename)
 
 		elif (cmd == "list_full"):
@@ -220,26 +221,22 @@ Element function modify(model : Element, write : Boolean):
 			while (read_nr_out(keys_m) > 0):
 				v_m = set_pop(keys_m)
 				// Filter out anonymous objects
-				typename = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][v_m]))
+				typename = read_type(model, v_m)
 				output((("  " + v_m) + " : ") + typename)
 
 		elif (cmd == "read"):
 			output("Element to read?")
 			cmd = input()
 			if (dict_in(model["model"], cmd)):
-				Element read_elem
-				read_elem = model["model"][cmd]
-				metamodel_element_pn = dict_read_node(model["type_mapping"], read_elem)
-
-				output("Name: " + cmd)
-				output("Type: " + reverseKeyLookup(model["metamodel"]["model"], metamodel_element_pn))
-				if (is_edge(read_elem)):
-					output("Source: " + reverseKeyLookup(model["model"], read_edge_src(read_elem)))
-					output("Destination: " + reverseKeyLookup(model["model"], read_edge_dst(read_elem)))
-				if (cast_v2s(read_elem) != "None"):
-					output("Value: " + cast_v2s(read_elem))
+				output("ID: " + cmd)
+				output("Type: " + read_type(model, cmd))
+				if (is_edge(model["model"][cmd])):
+					output("Source: " + reverseKeyLookup(model["model"], read_edge_src(model["model"][cmd])))
+					output("Destination: " + reverseKeyLookup(model["model"], read_edge_dst(model["model"][cmd])))
+				if (has_value(model["model"][cmd])):
+					output("Value: " + cast_v2s(model["model"][cmd]))
 				output("Defines attributes:")
-				attr_list_pn = getInstantiatableAttributes(model, read_elem)
+				attr_list_pn = getInstantiatableAttributes(model, cmd)
 				attr_keys_pn = dict_keys(attr_list_pn)
 				while (0 < read_nr_out(attr_keys_pn)):
 					attr_key_pn = set_pop(attr_keys_pn)
@@ -249,7 +246,7 @@ Element function modify(model : Element, write : Boolean):
 				attr_keys_pn = dict_keys(attr_list_pn)
 				while (0 < read_nr_out(attr_keys_pn)):
 					attr_key_pn = set_pop(attr_keys_pn)
-					output((((("  " + cast_v2s(attr_key_pn)) + " : ") + cast_v2s(attr_list_pn[attr_key_pn])) + " = ") + cast_v2s(read_attribute(model, reverseKeyLookup(model["model"], read_elem), attr_key_pn)))
+					output((((("  " + cast_v2s(attr_key_pn)) + " : ") + cast_v2s(attr_list_pn[attr_key_pn])) + " = ") + cast_v2s(read_attribute(model, cmd, attr_key_pn)))
 			else:
 				output("Unknown element; aborting")
 
@@ -264,7 +261,7 @@ Element function modify(model : Element, write : Boolean):
 			while (read_nr_out(keys_t) > 0):
 				v_t = set_pop(keys_t)
 				if (bool_not(string_startswith(v_t, "__"))):
-					output(string_join(("  " + v_t) + " : ", reverseKeyLookup(model["metamodel"]["metamodel"]["model"], dict_read_node(model["metamodel"]["type_mapping"], model["metamodel"]["model"][v_t]))))
+					output(string_join(("  " + v_t) + " : ", read_type(model, v_t)))
 
 		elif (cmd == "retype"):
 			if (write):
@@ -275,11 +272,7 @@ Element function modify(model : Element, write : Boolean):
 					output("New type")
 					typename = input()
 					if (dict_in(model["metamodel"]["model"], typename)):
-						// OK, do the retyping
-						// First try removing the previous type if it exists
-						dict_delete_node(model["type_mapping"], model["model"][elementname])
-						// Now add the new type
-						dict_add(model["type_mapping"], model["model"][elementname], model["metamodel"]["model"][typename])
+						retype(model, elementname, typename)
 						output("Retyped!")
 					else:
 						output("Unknown type; aborting")

+ 11 - 7
hybrid_server/classes/mvkcontroller.xml

@@ -93,13 +93,17 @@
             <![CDATA[
             reply = None
             commands = []
-            while 1:
-                commands = self.mvk.execute_yields(taskname, operation, params, reply)
-                if commands is None:
-                    break
-                reply = [self.mvs_operations[command[0]](*(command[1]))[0] for command in commands]
-                #for c, r in zip(commands, reply):
-                #    print("%s --> %s" % (c, r))
+            try:
+                while 1:
+                    commands = self.mvk.execute_yields(taskname, operation, params, reply)
+                    if commands is None:
+                        break
+                    reply = [self.mvs_operations[command[0]](*(command[1]))[0] for command in commands]
+                    #for c, r in zip(commands, reply):
+                    #    print("%s --> %s" % (c, r))
+            except:
+                print("ERROR: " + str(self.mvk.debug_info.get(taskname, "Unknown taskname")))
+                raise
             ]]>
         </body>
     </method>

+ 3 - 0
integration/conftest.py

@@ -0,0 +1,3 @@
+import pytest
+def pytest_addoption(parser):
+    parser.addoption("--runslow", action="store_true", help="run slow tests")

+ 81 - 80
integration/test_mvc.py

@@ -1,6 +1,6 @@
 import unittest
 
-from utils import run_file, get_constructor, get_model_constructor
+from utils import *
 
 all_files = [   "core/mini_modify.alc",
                 "core/core_formalism.mvc",
@@ -59,9 +59,9 @@ class TestModelverseCore(unittest.TestCase):
                 "Welcome to the Model Management Interface v2.0!",
                 "Use the 'help' command for a list of possible commands",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root admin    45   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
             ],
             mode))
 
@@ -96,10 +96,10 @@ class TestModelverseCore(unittest.TestCase):
                      "  Empty : SimpleClassDiagrams",
                      "  core : CoreFormalism"]),
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    0   Empty : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   Empty : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
             ],
             mode))
 
@@ -141,10 +141,10 @@ class TestModelverseCore(unittest.TestCase):
                      "  Empty : SimpleClassDiagrams",
                      "  core : CoreFormalism"]),
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    0   Empty : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   Empty : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "Which model do you want to modify?",
                 "Model loaded, ready for commands!",
@@ -155,10 +155,10 @@ class TestModelverseCore(unittest.TestCase):
                 "Instantiation successful!",
                 "Please give your command.",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    1   Empty : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   Empty : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
             ],
             mode))
@@ -211,10 +211,10 @@ class TestModelverseCore(unittest.TestCase):
                 "Waiting for model constructors...",
                 "Model upload success!",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    0   Empty : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   Empty : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "Which model do you want to modify?",
                 "Model loaded, ready for commands!",
@@ -225,19 +225,19 @@ class TestModelverseCore(unittest.TestCase):
                 "Instantiation successful!",
                 "Please give your command.",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    1   Empty : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   Empty : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "Which model to overwrite?",
                 "Waiting for model constructors...",
                 "Model overwrite success!",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    2   Empty : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   Empty : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "Which model do you want to modify?",
                 "Model loaded, ready for commands!",
@@ -281,20 +281,20 @@ class TestModelverseCore(unittest.TestCase):
                 "Waiting for model constructors...",
                 "Model upload success!",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    14   PetriNets : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "Formalisms to include (terminate with empty string)?",
                 "Name of the RAMified transformation metamodel?",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    14   PetriNets : SimpleClassDiagrams",
-                     "  200  root nobody    14   __merged_PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root nobody    328   PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root admin    81   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root nobody   __merged_PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
             ],
             mode))
@@ -339,20 +339,20 @@ class TestModelverseCore(unittest.TestCase):
                 "Waiting for model constructors...",
                 "Model upload success!",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    14   PetriNets : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "Formalisms to include (terminate with empty string)?",
                 "Name of the RAMified transformation metamodel?",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    14   PetriNets : SimpleClassDiagrams",
-                     "  200  root nobody    14   __merged_PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root nobody    328   PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root admin    81   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root nobody   __merged_PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "RAMified metamodel to use?",
                 "Supported metamodels:",
@@ -365,18 +365,18 @@ class TestModelverseCore(unittest.TestCase):
                 "Name of new transformation?",
                 "Waiting for model constructors...",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    14   PetriNets : SimpleClassDiagrams",
-                     "  200  root nobody    14   __merged_PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root nobody    328   PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root nobody    0   PetriNets_Print : PetriNets_RAM",
-                     "  200  root admin    94   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root nobody   __merged_PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets_Print : PetriNets_RAM",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 set(["[ModelTransformation] PetriNets_Print : PetriNets_RAM",
                     ]),
                 "Ready for command...",
-                set(["  200  root nobody    0   [ModelTransformation] PetriNets_Print : PetriNets_RAM"
+                set(["  200  root nobody   [ModelTransformation] PetriNets_Print : PetriNets_RAM"
                     ]),
                 "Ready for command...",
             ],
@@ -420,20 +420,20 @@ class TestModelverseCore(unittest.TestCase):
                 "Waiting for model constructors...",
                 "Model upload success!",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    22   PetriNets : SimpleClassDiagrams",
-                     "  200  root admin    55   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "Formalisms to include (terminate with empty string)?",
                 "Name of the RAMified transformation metamodel?",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    22   PetriNets : SimpleClassDiagrams",
-                     "  200  root nobody    22   __merged_PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root nobody    352   PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root admin    81   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root nobody   __merged_PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "RAMified metamodel to use?",
                 "Supported metamodels:",
@@ -446,7 +446,7 @@ class TestModelverseCore(unittest.TestCase):
                 "Name of new transformation?",
                 "Waiting for model constructors...",
                 "Ready for command...",
-                set(["  200  root nobody    26   [ModelTransformation] PetriNets_Print : PetriNets_RAM"
+                set(["  200  root nobody   [ModelTransformation] PetriNets_Print : PetriNets_RAM"
                     ]),
                 "Ready for command...",
             ],
@@ -504,22 +504,22 @@ class TestModelverseCore(unittest.TestCase):
                 "Waiting for model constructors...",
                 "Model upload success!",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    22   PetriNets : SimpleClassDiagrams",
-                     "  200  root nobody    27   my_pn : PetriNets",
-                     "  200  root admin    65   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root nobody   my_pn : PetriNets",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "Formalisms to include (terminate with empty string)?",
                 "Name of the RAMified transformation metamodel?",
                 "Ready for command...",
-                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
-                     "  221  root admin    90   CoreFormalism : SimpleClassDiagrams",
-                     "  200  root nobody    22   PetriNets : SimpleClassDiagrams",
-                     "  200  root nobody    22   __merged_PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root nobody    352   PetriNets_RAM : SimpleClassDiagrams",
-                     "  200  root nobody    27   my_pn : PetriNets",
-                     "  200  root admin    91   core : CoreFormalism"]),
+                set(["  221  root admin   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets : SimpleClassDiagrams",
+                     "  200  root nobody   __merged_PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root nobody   PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root nobody   my_pn : PetriNets",
+                     "  200  root admin   core : CoreFormalism"]),
                 "Ready for command...",
                 "RAMified metamodel to use?",
                 "Supported metamodels:",
@@ -532,7 +532,7 @@ class TestModelverseCore(unittest.TestCase):
                 "Name of new transformation?",
                 "Waiting for model constructors...",
                 "Ready for command...",
-                set(["  200  root nobody    26   [ModelTransformation] PetriNets_Print : PetriNets_RAM"
+                set(["  200  root nobody   [ModelTransformation] PetriNets_Print : PetriNets_RAM"
                     ]),
                 "Ready for command...",
                 "Which transformation do you want to execute?",
@@ -852,6 +852,7 @@ class TestModelverseCore(unittest.TestCase):
             ],
             mode))
 
+    @slow
     def test_po_transform_add_MT_pn_simulate_larger(self):
         self.transform_add_MT_pn_simulate_larger("PO")
 

+ 6 - 0
integration/utils.py

@@ -10,6 +10,7 @@ import urllib2
 import subprocess
 import signal
 import random
+import pytest
 
 sys.path.append("interface/HUTN")
 sys.path.append("scripts")
@@ -19,6 +20,11 @@ from check_objects import to_recompile
 taskname = "test_task"
 parallel_push = True
 
+slow = pytest.mark.skipif(
+    not pytest.config.getoption("--runslow"),
+        reason="need --runslow option to run"
+)
+
 ports = set()
 
 def getFreePort():

+ 0 - 1
interface/HUTN/includes/metamodels.alh

@@ -1,6 +1,5 @@
 Element function create_metamodels()
 Element function initialize_SCD(location : String)
 Element function initialize_PN(location_SCD : String, location_PN : String)
-Element function initialize_FTG(location_SCD : String, location_FTG : String)
 Element function initialize_bottom(location : String)
 Void function add_AL_to_MM(model : Element)

+ 28 - 98
kernel/modelverse_kernel/compiled.py

@@ -14,6 +14,7 @@ def reverseKeyLookup(a, b, **remainder):
     result, = yield [("CNV", ["(unknown: %s)" % b])]
     raise PrimitiveFinished(result)
 
+"""
 def read_attribute(a, b, c, **remainder):
     model_dict, b_val, c_val, type_mapping = \
                     yield [("RD", [a, "model"]),
@@ -46,69 +47,7 @@ def read_attribute(a, b, c, **remainder):
         raise PrimitiveFinished(result)
 
     raise Exception("Error in reading edge!")
-
-def precompute_cardinalities(a, **remainder):
-    result, =       yield [("CN", [])]
-
-    # Read out all edges from the metamodel
-    a, =             yield [("RD", [a, "metamodel"])]
-    model_dict, =    yield [("RD", [a, "model"])]
-    model_keys, =    yield [("RDK", [model_dict])]
-    type_mapping, =  yield [("RD", [a, "type_mapping"])]
-    elems  =         yield [("RDN", [model_dict, k]) for k in model_keys]
-    model_keys_str = yield [("RV", [i]) for i in model_keys]
-    elem_to_name =   dict(zip(elems, model_keys_str))
-    edges =          yield [("RE", [i]) for i in elems]
-    elems = [elems[i] for i, edge_val in enumerate(edges) if edge_val is not None]
-    # Now we have all edges in the metamodel
-
-    # Read out the type of the Association defining all cardinalities
-    metamodel, =     yield [("RD", [a, "metamodel"])]
-    metametamodel, = yield [("RD", [metamodel, "metamodel"])]
-    metametamodel_dict, = \
-                    yield [("RD", [metametamodel, "model"])]
-    assoc, =         yield [("RD", [metametamodel_dict, "Association"])]
-    slc, suc, tlc, tuc = \
-                    yield [("RDE", [assoc, "source_lower_cardinality"]),
-                           ("RDE", [assoc, "source_upper_cardinality"]),
-                           ("RDE", [assoc, "target_lower_cardinality"]),
-                           ("RDE", [assoc, "target_upper_cardinality"]),
-                          ]
-
-    # All that we now have to do is find, for each edge, whether or not it has an edge typed by any of these links!
-    # Just find all links typed by these links!
-    types =         yield [("RDN", [type_mapping, i]) for i in elems]
-
-    cardinalities = {}
-    for i, edge_type in enumerate(types):
-        if edge_type == slc:
-            t = "slc"
-        elif edge_type == suc:
-            t = "suc"
-        elif edge_type == tlc:
-            t = "tlc"
-        elif edge_type == tuc:
-            t = "tuc"
-        else:
-            continue
-        
-        # Found a link, so add it
-        srcdst, = yield [("RE", [elems[i]])]
-        source, destination = srcdst
-        # The edge gives the "source" the cardinality found in "destination"
-        cardinalities.setdefault(elem_to_name[source], {})[t] = destination
-
-    # Now we have to translate the "cardinalities" Python dictionary to a Modelverse dictionary
-    nodes = yield [("CN", []) for i in cardinalities]
-    yield [("CD", [result, i, node]) for i, node in zip(cardinalities.keys(), nodes)]
-    l = cardinalities.keys()
-    values = yield [("RD", [result, i]) for i in l]
-
-    for i, value in enumerate(values):
-        cards = cardinalities[l[i]]
-        yield [("CD", [value, card_type, cards[card_type]]) for card_type in cards]
-
-    raise PrimitiveFinished(result)
+"""
 
 def set_copy(a, **remainder):
     b, =         yield [("CN", [])]
@@ -117,6 +56,7 @@ def set_copy(a, **remainder):
     _ =         yield [("CE", [b, i[1]]) for i in exp_links]
     raise PrimitiveFinished(b)
 
+"""
 def allInstances(a, b, **remainder):
     b_val, =     yield [("RV", [b])]
     model_dict,= yield [("RD", [a, "model"])]
@@ -175,7 +115,9 @@ def allInstances(a, b, **remainder):
     v =         yield [("RV", [i]) for i in final]
     _ =    yield [("CE", [result, i]) for i in final]
     raise PrimitiveFinished(result)
+"""
 
+"""
 def add_AL(a, b, **remainder):
     worklist = [(b, "funcdef")]
     added = set()
@@ -210,8 +152,8 @@ def add_AL(a, b, **remainder):
         }
 
     # Already add some often used types to the type cache, so we don't have to check for their presence
-    to_str, string = yield [("RD", [metamodel_dict, "to_str"]),
-                            ("RD", [metamodel_dict, "String"])]
+    to_str, string = yield [("CNV", ["to_str"]),
+                            ("CNV", ["String"])]
 
     type_cache = {"to_str": to_str,
                   "String": string}
@@ -236,16 +178,13 @@ def add_AL(a, b, **remainder):
 
         # Fill the cache
         if expected_type not in type_cache:
-            type_cache[expected_type], = yield [("RD", [metamodel_dict, expected_type])]
+            type_cache[expected_type], = yield [("CNV", [expected_type])]
 
         # Need to add it now
-        yield [("CD", [model_dict, "__%s" % worknode, worknode])]
+        nodename = "__%s" % worknode
+        yield [("CD", [model_dict, nodename, worknode])]
         added.add(worknode)
-        # NOTE can't just use CD here, as the key is a node and not a value
-        t1, = yield [("CE", [type_map, type_cache[expected_type]])]
-        t2, = yield [("CE", [t1, worknode])]
-        if t1 is None or t2 is None:
-            raise Exception("ERROR")
+        _, =        yield [("CD", [type_map, nodename, type_cache[expected_type]])]
 
         # Now add all its outgoing links, depending on the type we actually saw
         links = type_links.get(expected_type, [])
@@ -264,32 +203,34 @@ def add_AL(a, b, **remainder):
                 # Now add: edge, edge_outlink, edge_name
 
                 # Add 'edge'
-                yield [("CD", [model_dict, "__%s" % edge, edge])]
+                edgename = "__%s" % edge
+                yield [("CD", [model_dict, edgename, edge])]
                 added.add(edge)
                 link_type = "%s_%s" % (expected_type, link_name)
                 if link_type not in type_cache:
-                    type_cache[link_type], = yield [("RD", [metamodel_dict, link_type])]
-                t, = yield [("CE", [type_map, type_cache[link_type]])]
-                yield [("CE", [t, edge])]
+                    type_cache[link_type], = yield [("CNV", [link_type])]
+                _, = yield [("CD", [type_map, edge_name, type_cache[link_type]])]
 
                 # Add 'edge_outlink'
-                yield [("CD", [model_dict, "__%s" % edge_outlink, edge_outlink])]
+                edgename = "__%s" % edge_outlink
+                yield [("CD", [model_dict, edgename, edge_outlink])]
                 added.add(edge_outlink)
-                t, = yield [("CE", [type_map, type_cache["to_str"]])]
-                yield [("CE", [t, edge_outlink])]
+                _, = yield [("CD", [type_map, edgename, type_cache["to_str"]])]
 
                 # Add 'edge_name' (if not present)
                 if edge_name not in added:
-                    yield [("CD", [model_dict, "__%s" % edge_name, edge_name])]
-                    t, = yield [("CE", [type_map, type_cache["String"]])]
-                    yield [("CE", [t, edge_name])]
+                    edgename = "__%s" % edge_name
+                    yield [("CD", [model_dict, edgename, edge_name])]
+                    _, = yield [("CD", [type_map, edgename, type_cache["String"]])]
                     added.add(edge_name)
 
                 # Add the destination to the worklist
                 worklist.append((destination, destination_type))
 
     raise PrimitiveFinished(result)
+"""
 
+"""
 def get_superclasses(a, b, **remainder):
     mm, =            yield [("RD", [a, "metamodel"])]
     mm, =            yield [("RD", [mm, "metamodel"])]
@@ -331,7 +272,9 @@ def get_superclasses(a, b, **remainder):
                         print("Read edge gives error for edge: " + str(elem))
 
     raise PrimitiveFinished(result)
+"""
 
+"""
 def selectPossibleIncoming(a, b, c, **remainder):
     model_dict, =    yield [("RD", [a, "model"])]
     limit_set_links, = \
@@ -357,7 +300,9 @@ def selectPossibleIncoming(a, b, c, **remainder):
             yield [("CE", [result, limit_set_names[i]])]
 
     raise PrimitiveFinished(result)
+"""
 
+"""
 def selectPossibleOutgoing(a, b, c, **remainder):
     model_dict, =    yield [("RD", [a, "model"])]
     limit_set_links, = \
@@ -384,6 +329,7 @@ def selectPossibleOutgoing(a, b, c, **remainder):
             yield [("CE", [result, limit_set_names[i]])]
 
     raise PrimitiveFinished(result)
+"""
 
 def check_symbols(a, b, c, **remainder):
     symbols = {}
@@ -437,19 +383,3 @@ def instantiated_name(a, b, **remainder):
     if name_value == "":
         b, = yield [("CNV", ["__" + str(a)])]
     raise PrimitiveFinished(b)
-
-def retype(a, b, c, **remainder):
-    tm, =       yield [("RD", [a, "type_mapping"])]
-    m, =        yield [("RD", [a, "model"])]
-    mm, =       yield [("RD", [a, "metamodel"])]
-    mm_dict, =  yield [("RD", [mm, "model"])]
-    c_val, =    yield [("RV", [c])]
-    mm_ref, =   yield [("RD", [mm_dict, c_val])]
-    b_val, =    yield [("RV", [b])]
-    m_ref, =    yield [("RD", [m, b_val])]
-    prev_edge, = yield [("RDNE", [tm, m_ref])]
-    if prev_edge is not None:
-        yield [("DE", [prev_edge])]
-    t, =        yield [("CE", [tm, mm_ref])]
-    yield [("CE", [t, m_ref])]
-    raise PrimitiveFinished(None)

+ 12 - 79
kernel/modelverse_kernel/compiled_legacy.py

@@ -13,6 +13,7 @@ def reverseKeyLookup(a, b, **remainder):
     result, = yield [("CNV", ["(unknown: %s)" % b])]
     raise PrimitiveFinished(result)
 
+"""
 def read_attribute(a, b, c, **remainder):
     model_dict, b_val, c_val, type_mapping = \
                     yield [("RD", [a, "model"]),
@@ -45,69 +46,7 @@ def read_attribute(a, b, c, **remainder):
         raise PrimitiveFinished(result)
 
     raise Exception("Error in reading edge!")
-
-def precompute_cardinalities(a, **remainder):
-    result, =       yield [("CN", [])]
-
-    # Read out all edges from the metamodel
-    a, =             yield [("RD", [a, "metamodel"])]
-    model_dict, =    yield [("RD", [a, "model"])]
-    model_keys, =    yield [("RDK", [model_dict])]
-    type_mapping, =  yield [("RD", [a, "type_mapping"])]
-    elems  =         yield [("RDN", [model_dict, k]) for k in model_keys]
-    model_keys_str = yield [("RV", [i]) for i in model_keys]
-    elem_to_name =   dict(zip(elems, model_keys_str))
-    edges =          yield [("RE", [i]) for i in elems]
-    elems = [elems[i] for i, edge_val in enumerate(edges) if edge_val is not None]
-    # Now we have all edges in the metamodel
-
-    # Read out the type of the Association defining all cardinalities
-    metamodel, =     yield [("RD", [a, "metamodel"])]
-    metametamodel, = yield [("RD", [metamodel, "metamodel"])]
-    metametamodel_dict, = \
-                    yield [("RD", [metametamodel, "model"])]
-    assoc, =         yield [("RD", [metametamodel_dict, "Association"])]
-    slc, suc, tlc, tuc = \
-                    yield [("RDE", [assoc, "source_lower_cardinality"]),
-                           ("RDE", [assoc, "source_upper_cardinality"]),
-                           ("RDE", [assoc, "target_lower_cardinality"]),
-                           ("RDE", [assoc, "target_upper_cardinality"]),
-                          ]
-
-    # All that we now have to do is find, for each edge, whether or not it has an edge typed by any of these links!
-    # Just find all links typed by these links!
-    types =         yield [("RDN", [type_mapping, i]) for i in elems]
-
-    cardinalities = {}
-    for i, edge_type in enumerate(types):
-        if edge_type == slc:
-            t = "slc"
-        elif edge_type == suc:
-            t = "suc"
-        elif edge_type == tlc:
-            t = "tlc"
-        elif edge_type == tuc:
-            t = "tuc"
-        else:
-            continue
-        
-        # Found a link, so add it
-        srcdst, = yield [("RE", [elems[i]])]
-        source, destination = srcdst
-        # The edge gives the "source" the cardinality found in "destination"
-        cardinalities.setdefault(elem_to_name[source], {})[t] = destination
-
-    # Now we have to translate the "cardinalities" Python dictionary to a Modelverse dictionary
-    nodes = yield [("CN", []) for i in cardinalities]
-    yield [("CD", [result, i, node]) for i, node in zip(cardinalities.keys(), nodes)]
-    l = cardinalities.keys()
-    values = yield [("RD", [result, i]) for i in l]
-
-    for i, value in enumerate(values):
-        cards = cardinalities[l[i]]
-        yield [("CD", [value, card_type, cards[card_type]]) for card_type in cards]
-
-    raise PrimitiveFinished(result)
+"""
 
 def set_copy(a, **remainder):
     b, =         yield [("CN", [])]
@@ -116,6 +55,7 @@ def set_copy(a, **remainder):
     _ =         yield [("CE", [b, i[1]]) for i in exp_links]
     raise PrimitiveFinished(b)
 
+"""
 def allInstances(a, b, **remainder):
     b_val, =     yield [("RV", [b])]
     model_dict,= yield [("RD", [a, "model"])]
@@ -174,7 +114,9 @@ def allInstances(a, b, **remainder):
     v =         yield [("RV", [i]) for i in final]
     _ =    yield [("CE", [result, i]) for i in final]
     raise PrimitiveFinished(result)
+"""
 
+"""
 def add_AL(a, b, **remainder):
     worklist = [(b, "funcdef")]
     added = set()
@@ -288,7 +230,9 @@ def add_AL(a, b, **remainder):
                 worklist.append((destination, destination_type))
 
     raise PrimitiveFinished(result)
+"""
 
+"""
 def get_superclasses(a, b, **remainder):
     mm, =            yield [("RD", [a, "metamodel"])]
     mm, =            yield [("RD", [mm, "metamodel"])]
@@ -328,7 +272,9 @@ def get_superclasses(a, b, **remainder):
                     worklist.append(dst)
 
     raise PrimitiveFinished(result)
+"""
 
+"""
 def selectPossibleIncoming(a, b, c, **remainder):
     model_dict, =    yield [("RD", [a, "model"])]
     limit_set_links, = \
@@ -360,7 +306,9 @@ def selectPossibleIncoming(a, b, c, **remainder):
             yield [("CE", [result, limit_set_names[i]])]
 
     raise PrimitiveFinished(result)
+"""
 
+"""
 def selectPossibleOutgoing(a, b, c, **remainder):
     model_dict, =    yield [("RD", [a, "model"])]
     limit_set_links, = \
@@ -393,6 +341,7 @@ def selectPossibleOutgoing(a, b, c, **remainder):
             yield [("CE", [result, limit_set_names[i]])]
 
     raise PrimitiveFinished(result)
+"""
 
 def check_symbols(a, b, c, **remainder):
     symbols = {}
@@ -453,22 +402,6 @@ def instantiated_name(a, b, **remainder):
         b, = yield [("CNV", ["__" + str(a)])]
     raise PrimitiveFinished(b)
 
-def retype(a, b, c, **remainder):
-    tm, =       yield [("RD", [a, "type_mapping"])]
-    m, =        yield [("RD", [a, "model"])]
-    mm, =       yield [("RD", [a, "metamodel"])]
-    mm_dict, =  yield [("RD", [mm, "model"])]
-    c_val, =    yield [("RV", [c])]
-    mm_ref, =   yield [("RD", [mm_dict, c_val])]
-    b_val, =    yield [("RV", [b])]
-    m_ref, =    yield [("RD", [m, b_val])]
-    prev_edge, = yield [("RDNE", [tm, m_ref])]
-    if prev_edge is not None:
-        yield [("DE", [prev_edge])]
-    t, =        yield [("CE", [tm, mm_ref])]
-    yield [("CE", [t, m_ref])]
-    raise PrimitiveFinished(None)
-
 def __get_input(parameters):
     mvk = parameters["mvk"]
     task_root = parameters["task_root"]

+ 1 - 3
kernel/modelverse_kernel/main.py

@@ -106,7 +106,7 @@ class ModelverseKernel(object):
 
             return handler.handle_request(reply)
         except:
-            print("Unknown error @ " + str(self.debug_info.get(taskname, "Username unknown")))
+            print("Unknown error @ " + str(self.debug_info.get(taskname, "Unknown task")))
             raise
 
     def execute_rule(self, taskname):
@@ -700,11 +700,9 @@ class ModelverseKernel(object):
             # gives us O(1) state reads per jit-interpreter transition.
             exception_return, = yield [("RD", [task_frame, primitive_functions.EXCEPTION_RETURN_KEY])]
             if prev_frame is None:
-                print("Frame empty; delete task " + str(self.taskname))
                 _, =            yield [("DN", [task_root])]
                 del self.debug_info[self.taskname]
             else:
-                print("Previous frame found")
                 if self.debug_info[self.taskname]:
                     self.debug_info[self.taskname].pop()
                 _, _ =          yield [("CD", [task_root, "frame", prev_frame]),

+ 2 - 0
state/modelverse_state/main.py

@@ -149,6 +149,7 @@ class ModelverseState(object):
     def create_nodevalue(self, value):
         if not self.is_valid_datavalue(value):
             print("Not correct: " + str(value))
+            #raise Exception()
             return (None, status.FAIL_CNV_OOB)
         self.values[self.free_id] = value
         self.nodes.add(self.free_id)
@@ -250,6 +251,7 @@ class ModelverseState(object):
                     # Now get the target of the original link
                     if found is not None:
                         print("Duplicate key on value: %s : %s (%s <-> %s)!" % (v, type(v), found, e1))
+                        raise Exception()
                         return (None, status.FAIL_RDICTE_AMBIGUOUS)
                     found = e1
                     self.cache.setdefault(node, {})[value] = e1