include "primitives.alh" include "conformance_scd.alh" include "constructors.alh" include "modelling.alh" include "typing.alh" Element function allInstances(model : Element, type_name : String): if (dict_in(model["metamodel"]["model"], type_name)): Element result Element accepted Element keys Element tm String key String class Element results result = set_create() accepted = get_subclasses(model["metamodel"], type_name) while (set_len(accepted) > 0): class = set_pop(accepted) set_merge(result, elements_typed_by(model, class)) return result! else: log("No such type in the metamodel: " + type_name) return set_create()! 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 = set_create() model_dict = model["model"] while (list_len(limit_set) > 0): 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 = set_create() model_dict = model["model"] while (list_len(limit_set) > 0): 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 result Element source String option Integer all_out Integer i result = set_create() source = model["model"][source_name] all_out = read_nr_out(source) i = 0 while (i < all_out): option = reverseKeyLookup(model["model"], read_out(source, i)) if (option != ""): if (assoc_name != ""): if (is_nominal_instance(model, option, assoc_name)): set_add(result, option) else: set_add(result, option) i = i + 1 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 result Element source String option Integer all_out Integer i result = set_create() source = model["model"][target_name] all_out = read_nr_in(source) i = 0 while (i < all_out): option = reverseKeyLookup(model["model"], read_in(source, i)) if (option != ""): if (assoc_name != ""): if (is_nominal_instance(model, option, assoc_name)): set_add(result, option) else: set_add(result, option) i = i + 1 return result! Element function getAttributeList(model : Element, element : String): Element result Element keys Element type Element attr_name Element types Element mm String attr_type result = dict_create() mm = model["metamodel"]["model"] types = get_superclasses(model["metamodel"], read_type(model, element)) while (set_len(types) > 0): type = set_pop(types) // Add our own attributes keys = dict_keys(mm[type]) while (set_len(keys) > 0): attr_name = set_pop(keys) if (is_physical_string(attr_name)): if (read_type(model["metamodel"], reverseKeyLookup(mm, dict_read_edge(mm[type], attr_name))) == "AttributeLink"): attr_type = reverseKeyLookup(mm, mm[type][attr_name]) // WARNING: do not change this to dict_add_fast, as this crashes random code... dict_add(result, attr_name, attr_type) return result! Element function getAttributes(model : Element, element : String): Element result Element keys Element type Element attr_name Element types Element mm result = dict_create() mm = model["metamodel"]["model"] types = get_superclasses(model["metamodel"], read_type(model, element)) while (set_len(types) > 0): type = set_pop(types) // Add our own attributes keys = dict_keys(mm[type]) while (set_len(keys) > 0): attr_name = set_pop(keys) if (is_physical_string(attr_name)): // WARNING: do not change this to dict_add_fast, as this crashes random code... dict_add(result, attr_name, read_attribute(model, element, attr_name)) return result! Element function getInstantiatableAttributes(model : Element, element : String, type : String): Element all_links Element result String link result = dict_create() all_links = allOutgoingAssociationInstances(model, element, type) while (set_len(all_links) > 0): link = set_pop(all_links) // WARNING: do not change this to dict_add_fast, as this crashes random code... dict_add(result, read_attribute(model, link, "name"), readAssociationDestination(model, link)) return result! 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_value(key) result = result + ": " result = result + cast_value(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]))! Element function allAssociationDestinations(model : Element, name : String, association_type : String): Element tmp Element result result = set_create() tmp = allOutgoingAssociationInstances(model, name, association_type) while (set_len(tmp) > 0): set_add(result, readAssociationDestination(model, set_pop(tmp))) return result! Element function allAssociationOrigins(model : Element, name : String, association_type : String): Element tmp Element result result = set_create() tmp = allIncomingAssociationInstances(model, name, association_type) while (set_len(tmp) > 0): set_add(result, readAssociationSource(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 = set_create() type = read_type(model, src) all_types = get_superclasses(model["metamodel"], type) while (set_len(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) edge_name = reverseKeyLookup(model["metamodel"]["model"], edge) if (dict_in(model["metamodel"]["model"], edge_name)): // Find destination dst_name = reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(edge)) if (is_nominal_instance(model, dst, dst_name)): // Find out whether our dst is an instance of the found destination type if (is_nominal_instance(model["metamodel"], edge_name, "Association")): set_add(result, edge_name) i = i + 1 return result!