include "primitives.alh" include "object_operations.alh" include "typing.alh" Boolean function find_type_mapping(model : Element): // Finds a correct type mapping for the provided model (with partial type mapping) // We go through several phases: // 1) remove elements from type mapping that are not in the model or metamodel // 2) find a mapping based on the current partial mapping // 3) (optional) verify that the mapping is correct with conformance checking // Returns True if the type mapping was altered // Start of with some initialization Element tm Element elems String elem tm = get_type_mapping_as_dict(model) // 1) remove elements from type mapping that are not in the model or metamodel elems = dict_keys(tm) while (set_len(elems) > 0): elem = set_pop(elems) if (bool_not(dict_in(model["model"], elem))): // Remove the key, as the model does not contain the element anymore dict_delete(tm, elem) else: if (bool_not(dict_in(model["metamodel"]["model"], tm[elem]))): // Remove the key, as the metamodel does not contain the type anymore dict_delete(tm, elem) // 2) find a mapping based on the current partial mapping, but only if it is not yet complete // TODO this must be expanded for other things than trivial metamodels! if (dict_len(model["model"]) > dict_len(tm)): //log("Model is incompletely typed!") //log("Model has: " + set_to_string(dict_keys(model["model"]))) //log("Type mapping has: " + set_to_string(dict_keys(tm))) //log("Missing: " + set_to_string(set_difference(dict_keys(model["model"]), dict_keys(tm)))) // TODO for now, this only returns something for a simple case, where the MM has one edge, and one node // and it makes the assumption that SCD is the M3 level... // First find the name of the edge and node elements Element elems String elem String node_element String edge_element node_element = read_root() edge_element = read_root() elems = dict_keys(model["metamodel"]["model"]) log("Elements in metamodel: " + set_to_string(elems)) while (set_len(elems) > 0): elem = set_pop(elems) // log("Check " + elem) if (bool_not(is_edge(model["metamodel"]["model"][elem]))): if (element_neq(node_element, read_root())): log("Multiple nodes detected!") return False! node_element = elem else: // Is an edge, but might be the inheritance link... log("type: " + read_type(model["metamodel"], elem)) if (read_type(model["metamodel"], elem) != "Inheritance"): // Is not the inheritance link if (element_neq(edge_element, read_root())): log("Multiple edges detected") return False! edge_element = elem if (bool_or(element_eq(node_element, read_root()), element_eq(edge_element, read_root()))): log("Not both node and edge detected") return False! // Now we have bot an edge_element and node_element of the metamodel // Now just trivially bind all elements! elems = dict_keys(model["model"]) while (set_len(elems) > 0): elem = set_pop(elems) if (is_edge(model["model"][elem])): retype(model, elem, edge_element) else: retype(model, elem, node_element) // 3) (optional) verify that the mapping is correct with conformance checking // TODO return True!