include "primitives.alh" include "constructors.alh" include "object_operations.alh" include "library.alh" include "conformance_scd.alh" include "io.alh" include "metamodels.alh" include "modelling.alh" include "typing.alh" include "compiler.alh" include "utils.alh" Boolean verbose = True String function pretty_print(model : Element): Element keys_m String type String v_m Element attr_list Element attr_keys String attr_key String result result = "" keys_m = dict_keys(model["model"]) while (set_len(keys_m) > 0): v_m = set_pop(keys_m) type = read_type(model["metamodel"], read_type(model, v_m)) if (bool_or(type == "Class", type == "Association")): result = result + " " + v_m + " : " + read_type(model, v_m) result = result + "\n" if (type == "Association"): result = result + " " + reverseKeyLookup(model["model"], read_edge_src(model["model"][v_m])) + " --> " + reverseKeyLookup(model["model"], read_edge_dst(model["model"][v_m])) result = result + "\n" // Defines attributes attr_list = getInstantiatableAttributes(model, v_m, "AttributeLink") attr_keys = dict_keys(attr_list) while (set_len(attr_keys) > 0): attr_key = set_pop(attr_keys) result = result + " " + attr_key + " : " + cast_value(attr_list[attr_key]) result = result + "\n" // Has attributes attr_list = getAttributeList(model, v_m) attr_keys = dict_keys(attr_list) while (set_len(attr_keys) > 0): attr_key = set_pop(attr_keys) if (element_eq(read_attribute(model, v_m, attr_key), read_root())): result = result + " " + cast_string(attr_key) + " : " + cast_string(attr_list[attr_key]) + " = (undefined)" else: result = result + " " + cast_string(attr_key) + " : " + cast_string(attr_list[attr_key]) + " = " + cast_value(read_attribute(model, v_m, attr_key)) result = result + "\n" else: log("Skip instance: " + type) return result! String function cmd_help_m(write : Boolean): String result result = "" result = result + "Allowed operations:\n" if (write): result = result + " == READ/WRITE ==\n" result = result + " instantiate_node -- Create a new model element (node)\n" result = result + " instantiate_edge -- Create a new model element (edge)\n" result = result + " delete -- Delete an existing element\n" result = result + " attr_add -- Add an attribute to an element\n" result = result + " attr_add_code -- Add a coded attribute to an element\n" result = result + " attr_del -- Delete an attribute of an element\n" result = result + " attr_modify -- Modify an attribute of an element\n" result = result + " retype -- Change the type of an element\n" result = result + " upload -- Upload a completely new model\n" else: result = result + " == READ-ONLY ==\n" result = result + " read_outgoing -- Prints the list of outgoing links of an element\n" result = result + " read_incoming -- Prints the list of incoming links to an element\n" result = result + " list -- Prints the list of elements in the model\n" result = result + " list_full -- Prints the list of all elements in the model\n" result = result + " types -- Prints the list of elements that can be instantiated\n" result = result + " read -- Prints the current state of a model element\n" result = result + " verify -- Check whether the model conforms to the metamodel\n" result = result + " exit -- Leave the modification interface\n" return result! String function cmd_upload(write : Boolean, model : Element): Element new_model if (write): output("Waiting for model constructors...") new_model = compile_model(input(), model["metamodel"]) if (element_eq(new_model, read_root())): return "Compilation error"! dict_overwrite(model, "model", new_model["model"]) set_type_mapping(model, get_type_mapping(new_model)) return "Success"! else: return "Permission denied to write"! String function cmd_instantiate_node(write : Boolean, model : Element, mm_type_name : String, element_name : String): if (write): if (dict_in(model["metamodel"]["model"], mm_type_name)): if (dict_in(model["model"], element_name)): return "Element exists: " + element_name! else: if (is_edge(model["metamodel"]["model"][mm_type_name])): return "Element is not a node but an edge: " + mm_type_name! element_name = instantiate_node(model, mm_type_name, element_name) return "Success: " + element_name! else: return "Element not found: " + mm_type_name! else: return "Permission denied to write"! String function cmd_instantiate_edge(write : Boolean, model : Element, mm_type_name : String, element_name : String, source_name : String, target_name : String): if (write): if (dict_in(model["metamodel"]["model"], mm_type_name)): if (dict_in(model["model"], element_name)): return "Element exists: " + element_name! else: if (is_edge(model["metamodel"]["model"][mm_type_name])): if (dict_in(model["model"], source_name)): if (dict_in(model["model"], target_name)): element_name = instantiate_link(model, mm_type_name, element_name, source_name, target_name) return "Success: " + element_name! else: return "Element not found: " + target_name! else: return "Element not found: " + source_name! else: return "Element is a node not an edge: " + mm_type_name! else: return "Element not found: " + mm_type_name! else: return "Permission denied to write"! String function cmd_define_attribute(write : Boolean, model : Element, element_name : String, attr_name : String, type : String): if (write): if (dict_in(model["model"], element_name)): if (dict_in(model["model"], type)): Element attrs attrs = getInstantiatableAttributes(model, element_name, "AttributeLink") if (bool_not(set_in(dict_keys(attrs), attr_name))): model_define_attribute(model, element_name, attr_name, False, type) return "Success"! else: return "Attribute already defined: " + attr_name! else: return "Element not found: " + type! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_attr_add(write : Boolean, model : Element, element_name : String, attr_name : String, value : Element): if (write): if (dict_in(model["model"], element_name)): Element attrs attrs = getAttributeList(model, element_name) if (set_in(dict_keys(attrs), attr_name)): instantiate_attribute(model, element_name, attr_name, value) return "Success"! else: return "Attribute not found: " + attr_name! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_attr_add_code(write : Boolean, model : Element, element_name : String, attr_name : String): if (write): if (dict_in(model["model"], element_name)): Element attrs attrs = getAttributeList(model, element_name) if (set_in(dict_keys(attrs), attr_name)): output("Waiting for code constructors...") Element compiled compiled = compile_code(input()) if (element_eq(compiled, read_root())): return "Compilation error"! instantiate_attribute_code(model, element_name, attr_name, compiled) return "Success"! else: return "Attribute not found: " + attr_name! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_attr_del(write : Boolean, model : Element, element_name : String, attr_name : String): if (write): if (dict_in(model["model"], element_name)): Element attrs attrs = getAttributeList(model, element_name) if (set_in(dict_keys(attrs), attr_name)): unset_attribute(model, element_name, attr_name) return "Success"! else: return "Attribute not found: " + attr_name! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_attr_name(write : Boolean, model : Element, element_name : String, attr_name : String, new_attr_name : String): if (write): if (dict_in(model["model"], element_name)): Element attrs attrs = getInstantiatableAttributes(model, element_name, "AttributeLink") if (set_in(dict_keys(attrs), attr_name)): if (set_in(dict_keys(attrs), attr_name)): if (bool_not(set_in(dict_keys(attrs), new_attr_name))): Boolean optional String attr_edge attr_edge = reverseKeyLookup(model["model"], dict_read_edge(model["model"][element_name], attr_name)) optional = read_attribute(model, attr_edge, "optional") model_undefine_attribute(model, element_name, attr_name) model_define_attribute_ID(model, element_name, new_attr_name, optional, attrs[attr_name], attr_edge) return "Success"! else: return "Attribute already defined: " + new_attr_name! else: return "Attribute not defined: " + attr_name! else: return "Attribute not found: " + attr_name! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_attr_type(write : Boolean, model : Element, element_name : String, attr_name : String, new_attr_type : String): if (write): if (dict_in(model["model"], element_name)): Element attrs attrs = getInstantiatableAttributes(model, element_name, "AttributeLink") if (set_in(dict_keys(attrs), attr_name)): if (set_in(dict_keys(attrs), attr_name)): Boolean optional String attr_edge attr_edge = reverseKeyLookup(model["model"], dict_read_edge(model["model"][element_name], attr_name)) optional = read_attribute(model, attr_edge, "optional") model_undefine_attribute(model, element_name, attr_name) model_define_attribute_ID(model, element_name, attr_name, optional, new_attr_type, attr_edge) return "Success"! else: return "Attribute not defined: " + attr_name! else: return "Attribute not found: " + attr_name! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_attr_optional(write : Boolean, model : Element, element_name : String, attr_name : String, optional : Boolean): if (write): if (dict_in(model["model"], element_name)): Element attrs attrs = getInstantiatableAttributes(model, element_name, "AttributeLink") if (set_in(dict_keys(attrs), attr_name)): if (set_in(dict_keys(attrs), attr_name)): String attr_edge attr_edge = reverseKeyLookup(model["model"], dict_read_edge(model["model"][element_name], attr_name)) if (optional): log("Setting to optional") else: log("Setting to mandatory") model_undefine_attribute(model, element_name, attr_name) model_define_attribute_ID(model, element_name, attr_name, optional, attrs[attr_name], attr_edge) return "Success"! else: return "Attribute not defined: " + attr_name! else: return "Attribute not found: " + attr_name! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_undefine_attribute(write : Boolean, model : Element, element_name : String, attr_name : String): if (write): if (dict_in(model["model"], element_name)): Element attrs attrs = getInstantiatableAttributes(model, element_name, "AttributeLink") if (set_in(dict_keys(attrs), attr_name)): if (set_in(dict_keys(attrs), attr_name)): model_undefine_attribute(model, element_name, attr_name) log("REMOVE OK") return "Success"! else: return "Attribute not defined: " + attr_name! else: return "Attribute not found: " + attr_name! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_delete(write : Boolean, model : Element, element_name : String): if (write): if (dict_in(model["model"], element_name)): model_delete_element(model, element_name) return "Success"! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_list(model : Element): Element keys_m String v_m String result String typename result = "Success: " keys_m = dict_keys(model["model"]) while (set_len(keys_m) > 0): v_m = set_pop(keys_m) // Filter out anonymous objects if (bool_not(string_startswith(v_m, "__"))): typename = read_type(model, v_m) result = result + " " + v_m + " : " + typename + "\n" return result! String function cmd_list_full(model : Element): Element keys_m String v_m String result String typename result = "Success: " keys_m = dict_keys(model["model"]) while (set_len(keys_m) > 0): v_m = set_pop(keys_m) // Filter out anonymous objects typename = read_type(model, v_m) result = result + " " + v_m + " : " + typename + "\n" return result! String function cmd_read_outgoing(model : Element, element_name : String, type : String): String result Element elems if (dict_in(model["model"], element_name)): result = "Success: " elems = allOutgoingAssociationInstances(model, element_name, type) while (set_len(elems) > 0): result = string_join(result, set_pop(elems)) + "\n" return result! else: return "Element not found: " + element_name! String function cmd_read_incoming(model : Element, element_name : String, type : String): String result Element elems if (dict_in(model["model"], element_name)): result = "Success: " elems = allIncomingAssociationInstances(model, element_name, type) while (set_len(elems) > 0): result = string_join(result, set_pop(elems)) + "\n" return result! else: return "Element not found: " + element_name! String function cmd_connections_between(model : Element, source_name : String, target_name : String): String result Element options if (dict_in(model["model"], source_name)): if (dict_in(model["model"], target_name)): result = "Success: " options = allowedAssociationsBetween(model, source_name, target_name) while (set_len(options) > 0): result = string_join(result, set_pop(options)) + "\n" return result! else: return ("Element not found: " + target_name)! else: return ("Element not found: " + source_name)! String function cmd_read(model : Element, element_name : String): String result Element attr_list Element attr_keys String attr_key result = "Success: " if (dict_in(model["model"], element_name)): result = result + "Type: " + read_type(model, element_name) + "\n" if (is_edge(model["model"][element_name])): result = result + "Source: " + reverseKeyLookup(model["model"], read_edge_src(model["model"][element_name])) + "\n" result = result + "Destination: " + reverseKeyLookup(model["model"], read_edge_dst(model["model"][element_name])) + "\n" if (has_value(model["model"][element_name])): result = result + "Value: " + cast_value(model["model"][element_name]) + "\n" return result! else: return "Element not found: " + element_name! String function cmd_read_attrs(model : Element, element_name : String): String result Element attr_list Element attr_keys String attr_key result = "Success: " if (dict_in(model["model"], element_name)): attr_list = getAttributeList(model, element_name) attr_keys = dict_keys(attr_list) while (0 < set_len(attr_keys)): attr_key = set_pop(attr_keys) result = string_join(result, attr_key) + " : " + cast_value(attr_list[attr_key]) + " = " + cast_value(read_attribute(model, element_name, attr_key)) + "\n" return result! else: return "Element not found: " + element_name! String function cmd_read_defined_attrs(model : Element, element_name : String): String result Element attr_list Element attr_keys String attr_key result = "Success: " if (dict_in(model["model"], element_name)): attr_list = getInstantiatableAttributes(model, element_name, "AttributeLink") attr_keys = dict_keys(attr_list) while (0 < set_len(attr_keys)): attr_key = set_pop(attr_keys) if (value_eq(read_attribute(model, reverseKeyLookup(model["model"], dict_read_edge(model["model"][element_name], attr_key)), "optional"), True)): result = string_join(result, attr_key) + " ?: " + cast_value(attr_list[attr_key]) + "\n" else: result = string_join(result, attr_key) + " : " + cast_value(attr_list[attr_key]) + "\n" return result! else: return "Element not found: " + element_name! String function cmd_types(model : Element): Element keys_t String v_t String result keys_t = dict_keys(model["metamodel"]["model"]) result = "Success: " while (set_len(keys_t) > 0): v_t = set_pop(keys_t) if (bool_not(string_startswith(v_t, "__"))): result = result + string_join(" " + v_t + " : ", read_type(model["metamodel"], v_t)) + "\n" return result! String function cmd_retype(write : Boolean, model : Element, element_name : String, new_type : String): if (write): if (dict_in(model["model"], element_name)): if (dict_in(model["metamodel"]["model"], new_type)): retype(model, element_name, new_type) return "Success"! else: return "Element not found: " + new_type! else: return "Element not found: " + element_name! else: return "Permission denied to write"! String function cmd_read_association_source(write : Boolean, model : Element, element_name : String): if (dict_in(model["model"], element_name)): if (is_edge(model["model"][element_name])): return "Success: " + readAssociationSource(model, element_name)! else: return "Not an association: " + element_name! else: return "Element not found: " + element_name! String function cmd_read_association_destination(write : Boolean, model : Element, element_name : String): if (dict_in(model["model"], element_name)): if (is_edge(model["model"][element_name])): return "Success: " + readAssociationDestination(model, element_name)! else: return "Not an association: " + element_name! else: return "Element not found: " + element_name! String function cmd_all_instances(model : Element, type : String): String result Element elems if (dict_in(model["metamodel"]["model"], type)): result = "Success: " elems = allInstances(model, type) while (set_len(elems) > 0): result = string_join(result, set_pop(elems)) + "\n" return result! else: return "Element not found: " + type! Boolean function modify(model : Element, write : Boolean): String cmd output("Model loaded, ready for commands!") while (True): cmd = input() if (cmd == "help"): output(cmd_help_m(write)) elif (cmd == "exit"): return True! elif (cmd == "drop"): return False! elif (cmd == "upload"): output(cmd_upload(write, model)) elif (cmd == "instantiate_node"): output(cmd_instantiate_node(write, model, single_input("Type?"), single_input("Name?"))) elif (cmd == "instantiate_edge"): output(cmd_instantiate_edge(write, model, single_input("Type?"), single_input("Name?"), single_input("Source?"), single_input("Target?"))) elif (cmd == "attr_add"): output(cmd_attr_add(write, model, single_input("Name?"), single_input("Attribute name?"), single_input("Value?"))) elif (cmd == "attr_add_code"): output(cmd_attr_add_code(write, model, single_input("Name?"), single_input("Attribute name?"))) elif (cmd == "attr_del"): output(cmd_attr_del(write, model, single_input("Name?"), single_input("Attribute name?"))) elif (cmd == "attr_name"): output(cmd_attr_name(write, model, single_input("Name?"), single_input("Attribute name?"), single_input("New name?"))) elif (cmd == "attr_type"): output(cmd_attr_type(write, model, single_input("Name?"), single_input("Attribute name?"), single_input("Type name?"))) elif (cmd == "attr_optional"): output(cmd_attr_optional(write, model, single_input("Name?"), single_input("Attribute name?"), input())) elif (cmd == "delete"): output(cmd_delete(write, model, single_input("Name?"))) elif (cmd == "nice_list"): output(pretty_print(model)) elif (cmd == "list"): output(cmd_list(model)) elif (cmd == "list_full"): output(cmd_list_full(model)) elif (cmd == "JSON"): output("Success: " + JSON_print(model)) elif (cmd == "read_outgoing"): output(cmd_read_outgoing(model, single_input("Name?"), single_input("Type?"))) elif (cmd == "read_incoming"): output(cmd_read_incoming(model, single_input("Name?"), single_input("Type?"))) elif (cmd == "read"): output(cmd_read(model, single_input("Name?"))) elif (cmd == "read_attrs"): output(cmd_read_attrs(model, single_input("Name?"))) elif (cmd == "read_defined_attrs"): output(cmd_read_defined_attrs(model, single_input("Name?"))) elif (cmd == "types"): output(cmd_types(model)) elif (cmd == "retype"): output(cmd_retype(write, model, single_input("Name?"), single_input("New type?"))) elif (cmd == "read_association_source"): output(cmd_read_association_source(write, model, single_input("Name?"))) elif (cmd == "read_association_destination"): output(cmd_read_association_destination(write, model, single_input("Name?"))) elif (cmd == "connections_between"): output(cmd_connections_between(model, single_input("Source element?"), single_input("Target element?"))) elif (cmd == "all_instances"): output(cmd_all_instances(model, single_input("Type?"))) elif (cmd == "define_attribute"): output(cmd_define_attribute(write, model, single_input("On which element?"), single_input("Attribute name?"), single_input("Type?"))) elif (cmd == "undefine_attribute"): output(cmd_undefine_attribute(write, model, single_input("On which element?"), single_input("Attribute name?"))) else: output("Unknown command while modelling: " + cast_value(cmd)) output("Use command 'help' to get a list of available commands") String function single_input(prompt : String): if (verbose): output(prompt) return input()! Element function set_input(prompt : String): Element result Element inp if (verbose): output(prompt) output("-- Set input: empty string to terminate set") result = set_create() while (True): inp = input() if (value_eq(inp, "")): return result! else: set_add(result, inp) Element function dict_input(prompt : String): Element result Element key if (verbose): output(prompt) output("-- Dict input: empty key to terminate dict") result = set_create() while (True): key = input() if (value_eq(key, "")): return result! else: dict_add(result, key, input()) Void function set_verbose(v : Boolean): verbose = v return!