include "primitives.alh" include "conformance_scd.alh" include "constructors.alh" include "modelling.alh" Element function allInstances(model : Element, type_name : String): Element type_mapping Element result Element type String key Element keys keys = dict_keys(model["model"]) type = model["metamodel"]["model"][type_name] result = create_node() while (0 < list_len(keys)): key = set_pop(keys) if (is_nominal_instance(model, key, type_name)): set_add(result, key) return result! Element function selectPossibleIncoming(model : Element, target : String, limit_set : Element): // Find all possible incoming link types for the target model // Should also include those specified on the superclass(es) String type Element model_dict Element elem Element result Element target_element result = create_node() model_dict = model["model"] while (0 < list_len(limit_set)): type = set_pop(limit_set) elem = model_dict[type] if (is_nominal_subtype(model, target, reverseKeyLookup(model_dict, read_edge_dst(elem)))): set_add(result, type) return result! Element function selectPossibleOutgoing(model : Element, source : String, limit_set : Element): // Find all possible outgoing link types for the source model // Should also include those specified on the superclass(es) String type Element model_dict Element elem Element result Element source_element result = create_node() model_dict = model["model"] while (0 < list_len(limit_set)): type = set_pop(limit_set) elem = model_dict[type] if (is_nominal_subtype(model, source, reverseKeyLookup(model_dict, read_edge_src(elem)))): set_add(result, type) return result! Element function allOutgoingAssociationInstances(model : Element, source_name : String, assoc_name : String): // Read out all outgoing edges of the model and select those that are typed by the specified association Element assocs String assoc Element result Element source assocs = allInstances(model, assoc_name) source = model["model"][source_name] result = create_node() while (0 < list_len(assocs)): assoc = set_pop(assocs) if (element_eq(source, read_edge_src(model["model"][assoc]))): set_add(result, assoc) return result! Element function allIncomingAssociationInstances(model : Element, target_name : String, assoc_name : String): // Read out all outgoing edges of the model and select those that are typed by the specified association Element assocs String assoc Element result Element target assocs = allInstances(model, assoc_name) target = model["model"][target_name] result = create_node() while (0 < list_len(assocs)): assoc = set_pop(assocs) if (element_eq(target, read_edge_dst(model["model"][assoc]))): set_add(result, assoc) return result! Element function getAttributeList(model : Element, element : String): Element result Element keys Element type Element attr_name Element types String attr_type result = create_node() types = get_superclasses(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][element]))) while (read_nr_out(types) > 0): type = set_pop(types) keys = dict_keys(model["metamodel"]["model"][type]) // Add our own attributes while (0 < list_len(keys)): attr_name = set_pop(keys) if (is_physical_string(attr_name)): attr_type = reverseKeyLookup(model["metamodel"]["model"], model["metamodel"]["model"][type][attr_name]) dict_add(result, attr_name, attr_type) return result! Element function getInstantiatableAttributes(model : Element, element : String): Element result result = create_node() Element types types = get_superclasses(model, element) while (read_nr_out(types) > 0): element = set_pop(types) // Get all outgoing "dictionary" links Element set_own Element elem elem = model["model"][element] set_own = dict_keys(elem) // Filter them Element e while (0 < read_nr_out(set_own)): e = set_pop(set_own) if (is_physical_string(e)): dict_add(result, e, reverseKeyLookup(model["model"], elem[e])) 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! return string_join(string_join("(unknown: ", cast_e2s(element)), " )")! String function print_dict(dict : Element): Element keys Element key String result keys = dict_keys(dict) result = "" while (0 < list_len(keys)): key = set_pop(keys) result = result + cast_v2s(key) result = result + ": " result = result + cast_v2s(dict[key]) result = result + "\n" return result! String function readAssociationSource(model : Element, name : String): return reverseKeyLookup(model["model"], read_edge_src(model["model"][name]))! String function readAssociationDestination(model : Element, name : String): return reverseKeyLookup(model["model"], read_edge_dst(model["model"][name]))! String function followAssociation(model : Element, element_name : String, association_name : String): Element assocs String assoc Element result assocs = allOutgoingAssociationInstances(model, element_name, association_name) result = create_node() while (0 < list_len(assocs)): set_add(result, readAssociationDestination(model, set_pop(assocs))) return result! Element function allAssociationDestinations(model : Element, name : String, association_type : String): Element tmp Element result result = create_node() tmp = allOutgoingAssociationInstances(model, name, association_type) while (read_nr_out(tmp) > 0): set_add(result, readAssociationDestination(model, set_pop(tmp))) return result! Element function allowedAssociationsBetween(model : Element, src : String, dst : String): // Go to the type and find all possibilities String type Element all_types Integer nr_edges Integer i Element result Element edge String edge_name String dst_name result = create_node() type = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][src])) all_types = get_superclasses(model["metamodel"], type) while (read_nr_out(all_types) > 0): type = set_pop(all_types) nr_edges = read_nr_out(model["metamodel"]["model"][type]) i = 0 while (i < nr_edges): edge = read_out(model["metamodel"]["model"][type], i) if (set_in(model["metamodel"]["model"], edge)): // Find destination dst_name = reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(edge)) edge_name = reverseKeyLookup(model["metamodel"]["model"], edge) if (is_nominal_instance(model, dst, dst_name)): // Find out whether our dst is an instance of the found destination type set_add(result, edge_name) i = i + 1 return result! 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]) result = reverseKeyLookup(mm, tm) if (element_eq(mm[result], tm)): return result! else: return ""! else: return ""! else: return ""!