include "primitives.alh" include "io.alh" include "object_operations.alh" include "constructors.alh" include "metamodels.alh" include "library.alh" include "modelling.alh" Element function model_fuse(models : Element): Element new_model Element tagged_model String model_name Element model Element keys String key Element selected_MM String type // Read out some data first tagged_model = set_pop(models) set_add(models, tagged_model) new_model = instantiate_model(tagged_model[1]["metamodel"]) // Do the iteration while (read_nr_out(models)): tagged_model = set_pop(models) model_name = string_join(list_read(tagged_model, 0), "/") model = list_read(tagged_model, 1) // Add all elements from 'model', but prepend it with the 'model_name' 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])) if (is_edge(model["model"][key])): String src String dst src = model_name + reverseKeyLookup(model["model"], read_edge_src(model["model"][key])) dst = model_name + reverseKeyLookup(model["model"], read_edge_dst(model["model"][key])) if (bool_and(dict_in(new_model["model"], src), dict_in(new_model["model"], dst))): instantiate_link(new_model, type, model_name + key, src, dst) else: list_append(keys, key) elif (has_value(model["model"][key])): instantiate_value(new_model, type, model_name + key, model["model"][key]) else: instantiate_node(new_model, type, model_name + key) return new_model! Element function model_copy(src_model : Element): Element dst_model Element queue Element name String type dst_model = instantiate_model(src_model["metamodel"]) dict_add(dst_model, "model", create_node()) dict_add(dst_model, "type_mapping", create_node()) queue = set_to_list(dict_keys(src_model["model"])) while (read_nr_out(queue) > 0): name = list_pop(queue, 0) if (is_edge(src_model["model"][name])): // Is an edge, so potentially queue it String src String dst 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])) if (bool_and(dict_in(dst_model["model"], src), dict_in(dst_model["model"], dst))): // All present, so create the link between them instantiate_link(dst_model, type, name, src, dst) else: list_append(queue, name) 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])) 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])) instantiate_node(dst_model, type, name) return dst_model! Element function model_retype_on_name(model : Element, new_MM : Element, operation : String, name : String): String key String type Element keys Integer length keys = dict_keys(model["model"]) length = string_len(name) while (read_nr_out(keys) > 0): 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])) 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]) 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))]) else: model_delete_element(model, key) dict_delete(model, "metamodel") dict_add(model, "metamodel", new_MM) return model! Void function model_join(dst_model : Element, src_model : Element, retyping_key : String): Element queue Element mapping String name String type String src String dst queue = set_to_list(dict_keys(src_model["model"])) mapping = create_node() while (read_nr_out(queue) > 0): name = list_pop(queue, 0) if (is_edge(src_model["model"][name])): // Is an edge, so potentially queue it String src String dst 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])) 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, retyping_key + type, "", mapping[src], mapping[dst])) else: list_append(queue, name) 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])) dict_add(mapping, name, instantiate_value(dst_model, retyping_key + type, "", 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])) dict_add(mapping, name, instantiate_node(dst_model, retyping_key + type, "")) return! Element function model_split(src_model : Element, target_metamodel : Element, retyping_key : String): Element dst_model dst_model = instantiate_model(target_metamodel) Element queue Element mapping String name String type String src String dst Integer length queue = set_to_list(dict_keys(src_model["model"])) mapping = create_node() length = string_len(retyping_key) while (read_nr_out(queue) > 0): name = list_pop(queue, 0) if (is_edge(src_model["model"][name])): // Is an edge, so potentially queue it String src String dst 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])) 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, string_substr(type, length, string_len(type)), "", mapping[src], mapping[dst])) else: list_append(queue, name) 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])) dict_add(mapping, name, instantiate_value(dst_model, string_substr(type, length, string_len(type)), "", 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])) dict_add(mapping, name, instantiate_node(dst_model, string_substr(type, length, string_len(type)), "")) return dst_model!