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(name1 : String, model1 : Element, name2 : String, model2 : Element): Element new_model Element tagged_model String model_name Element model Element keys String key Element selected_MM String type Element models // Read out some data first selected_MM = model1["metamodel"] new_model = instantiate_model(selected_MM) // Create a list to nicely iterate over it models = create_node() tagged_model = create_node() list_append(tagged_model, name1) list_append(tagged_model, model1) list_append(models, tagged_model) tagged_model = create_node() list_append(tagged_model, name2) list_append(tagged_model, model2) list_append(models, tagged_model) // Do the iteration while (read_nr_out(models)): tagged_model = set_pop(models) model_name = 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!