include "primitives.alh" include "utils.alh" Element function get_type_mapping(model : Element): // Deserialize dictionary as model Element tm_model tm_model = dict_create() Element m Element mm Element edge Element keys String key String m_name String mm_name Element m_model Element mm_model Element tm m_model = model["model"] mm_model = model["metamodel"]["model"] tm = model["type_mapping"] keys = dict_keys(model["type_mapping"]) while (set_len(keys) > 0): key = set_pop(keys) m = m_model[key] mm = mm_model[tm[key]] edge = create_edge(m, mm) m_name = "instance_" + key mm_name = "type_" + cast_string(tm[key]) dict_add_fast(tm_model, m_name, m) if (bool_not(dict_in(tm_model, mm_name))): dict_add_fast(tm_model, mm_name, mm) dict_add_fast(tm_model, cast_id(edge), edge) return tm_model! Void function set_type_mapping(model : Element, type_mapping_model : Element): // Serialize model to dictionary Element type_mapping Element keys String key String source_name String destination_name String tmp_source_name String tmp_destination_name Element lookups String value String src_id String dst_id Element mm_model Element m_model m_model = model["model"] mm_model = model["metamodel"]["model"] type_mapping = dict_create() keys = dict_keys(type_mapping_model) Element reverse_mapping reverse_mapping = dict_create() while (set_len(keys) > 0): key = set_pop(keys) value = cast_id(type_mapping_model[key]) if (bool_not(dict_in(reverse_mapping, value))): dict_add(reverse_mapping, value, set_create()) set_add(reverse_mapping[value], key) keys = dict_keys(type_mapping_model) while (set_len(keys) > 0): key = set_pop(keys) if (is_edge(type_mapping_model[key])): src_id = cast_id(read_edge_src(type_mapping_model[key])) if (bool_not(dict_in(reverse_mapping, src_id))): continue! lookups = set_copy(reverse_mapping[src_id]) source_name = "" while (set_len(lookups) > 0): tmp_source_name = set_pop(lookups) if (string_startswith(tmp_source_name, "instance_")): source_name = string_replace(tmp_source_name, "instance_", "") break! dst_id = cast_id(read_edge_dst(type_mapping_model[key])) if (bool_not(dict_in(reverse_mapping, dst_id))): continue! lookups = set_copy(reverse_mapping[dst_id]) destination_name = "" while (set_len(lookups) > 0): tmp_destination_name = set_pop(lookups) if (string_startswith(tmp_destination_name, "type_")): destination_name = string_replace(tmp_destination_name, "type_", "") break! if (bool_and(bool_and(dict_in(m_model, source_name), dict_in(mm_model, destination_name)), read_nr_out(type_mapping_model[key]) == 0)): // Element is in neither model or metamodel // Must be a typing link! // So add it dict_add_fast(type_mapping, source_name, destination_name) dict_overwrite(model, "type_mapping", type_mapping) return! Element function elements_typed_by(model : Element, type_name : String): Element result Element temp_result String temp Element m_model m_model = model["model"] result = set_create() temp_result = reverseKeyLookupMultiValue(get_type_mapping_as_dict(model), type_name) while (set_len(temp_result) > 0): temp = set_pop(temp_result) if (dict_in(m_model, temp)): set_add(result, temp) return result! Element function get_type_mapping_as_dict(model : Element): return model["type_mapping"]! String function read_type(model : Element, name : String): String result Element tm if (dict_in(model["model"], name)): if (dict_in(model["type_mapping"], name)): result = model["type_mapping"][name] if (dict_in(model["metamodel"]["model"], result)): return result! else: return ""! else: return ""! else: return ""! Void function retype(model : Element, element : String, type : String): // Retype a model, deleting any previous type the element had // The type string is evaluated in the metamodel previously specified dict_overwrite(model["type_mapping"], element, type) return! Void function new_type_mapping(model : Element): dict_overwrite(model, "type_mapping", dict_create()) return ! Void function remove_type(model : Element, name : String): if (dict_in(model["type_mapping"], name)): dict_delete(model["type_mapping"], name) String elem elem = cast_id(model["model"][name]) if (dict_in(model["type_mapping"], elem)): dict_delete(model["type_mapping"], elem) return !