include "primitives.alh" include "constructors.alh" include "object_operations.alh" include "library.alh" include "conformance_scd.alh" include "io.alh" Element function create_metamodels(): // TODO // For the moment, we make the assumption that it doesn't exist yet. // We create both the Simple Class Diagrams model, retype it, and then make the metamodel as an instance of this // In the future, this should already exist though... if (bool_not(dict_in(dict_read(read_root(), "__hierarchy"), "models"))): Element scd Element scd_model scd = create_node() scd_model = create_node() dict_add(scd, "model", scd_model) instantiate_bottom_node(scd, "Class") instantiate_bottom_value(scd, "Type", Type) instantiate_bottom_value(scd, "__String", String) instantiate_bottom_value(scd, "__name", "name") instantiate_bottom_edge(scd, "Attribute", dict_read(scd_model, "Class"), dict_read(scd_model, "Type")) instantiate_bottom_edge(scd, "__Name", dict_read(scd_model, "Attribute"), dict_read(scd_model, "__String")) instantiate_bottom_edge(scd, "Association", dict_read(scd_model, "Class"), dict_read(scd_model, "Class")) instantiate_bottom_edge(scd, "Inheritance", dict_read(scd_model, "Class"), dict_read(scd_model, "Class")) instantiate_bottom_edge(scd, "__name_edge", dict_read(scd_model, "__Name"), dict_read(scd_model, "__name")) instantiate_bottom_edge(scd, "__inh_1", dict_read(scd_model, "Association"), dict_read(scd_model, "Class")) instantiate_bottom_edge(scd, "__inh_2", dict_read(scd_model, "Attribute"), dict_read(scd_model, "Class")) instantiate_bottom_value(scd, "__attribute", "attribute") instantiate_bottom_edge(scd, "__attribute_edge", dict_read(scd_model, "Attribute"), dict_read(scd_model, "__attribute")) // Instantiated, now retype to make sure that everything is correct Element mapping mapping = create_node() dict_add(mapping, dict_read(scd_model, "Class"), dict_read(scd_model, "Class")) dict_add(mapping, dict_read(scd_model, "Type"), dict_read(scd_model, "Type")) dict_add(mapping, dict_read(scd_model, "__String"), dict_read(scd_model, "Type")) dict_add(mapping, dict_read(scd_model, "Attribute"), dict_read(scd_model, "Attribute")) dict_add(mapping, dict_read(scd_model, "__Name"), dict_read(scd_model, "Attribute")) dict_add(mapping, dict_read(scd_model, "Association"), dict_read(scd_model, "Association")) dict_add(mapping, dict_read(scd_model, "Inheritance"), dict_read(scd_model, "Association")) dict_add(mapping, dict_read(scd_model, "__inh_1"), dict_read(scd_model, "Inheritance")) dict_add(mapping, dict_read(scd_model, "__inh_2"), dict_read(scd_model, "Inheritance")) dict_add(mapping, dict_read(scd_model, "__name"), dict_read(scd_model, "__String")) dict_add(mapping, dict_read(scd_model, "__name_edge"), dict_read(scd_model, "__Name")) dict_add(mapping, dict_read(scd_model, "__attribute"), dict_read(scd_model, "__String")) dict_add(mapping, dict_read(scd_model, "__attribute_edge"), dict_read(scd_model, "__Name")) retype(scd, scd, dict_read(scd_model, "Inheritance"), mapping) export_node("models/SimpleClassDiagrams", scd) // TODO this code is also very dirty as there is no nice "dictionary" and "list" syntax yet Element pn_metamodel pn_metamodel = instantiate_new_model(scd, dict_read(scd_model, "Inheritance")) Element tokens tokens = create_node() dict_add(tokens, "tokens", Integer) instantiate_model_lib(pn_metamodel, dict_read(scd_model, "Class"), "Place", create_node(), tokens, create_node()) instantiate_model_lib(pn_metamodel, dict_read(scd_model, "Class"), "Transition", create_node(), create_node(), create_node()) Element weight weight = create_node() dict_add(weight, "weight", Integer) Element p2t_links p2t_links = create_node() list_append(p2t_links, dict_read(dict_read(pn_metamodel, "model"), "Place")) list_append(p2t_links, dict_read(dict_read(pn_metamodel, "model"), "Transition")) Element t2p_links t2p_links = create_node() list_append(t2p_links, dict_read(dict_read(pn_metamodel, "model"), "Transition")) list_append(t2p_links, dict_read(dict_read(pn_metamodel, "model"), "Place")) instantiate_model_lib(pn_metamodel, dict_read(scd_model, "Association"), "P2T", p2t_links, weight, create_node()) instantiate_model_lib(pn_metamodel, dict_read(scd_model, "Association"), "T2P", t2p_links, weight, create_node()) set_model_constraints(pn_metamodel, petrinet_constraints) export_node("models/PetriNets", pn_metamodel) // Also create conformance bottom metamodel Element mm_bottom Element mm_bottom_model mm_bottom = create_node() mm_bottom_model = create_node() dict_add(mm_bottom, "model", mm_bottom_model) instantiate_bottom_node(mm_bottom, "Node") instantiate_bottom_value(mm_bottom, "Type", Type) instantiate_bottom_value(mm_bottom, "Integer", Integer) instantiate_bottom_value(mm_bottom, "Action", Action) instantiate_bottom_value(mm_bottom, "Float", Float) instantiate_bottom_value(mm_bottom, "String", String) instantiate_bottom_value(mm_bottom, "Boolean", Boolean) instantiate_bottom_edge(mm_bottom, "Edge", dict_read(mm_bottom_model, "Node"), dict_read(mm_bottom_model, "Node")) instantiate_bottom_edge(mm_bottom, "__Inheritance", dict_read(mm_bottom_model, "Node"), dict_read(mm_bottom_model, "Node")) instantiate_bottom_edge(mm_bottom, "__inh_1", dict_read(mm_bottom_model, "Type"), dict_read(mm_bottom_model, "Node")) instantiate_bottom_edge(mm_bottom, "__inh_2", dict_read(mm_bottom_model, "Integer"), dict_read(mm_bottom_model, "Node")) instantiate_bottom_edge(mm_bottom, "__inh_3", dict_read(mm_bottom_model, "Action"), dict_read(mm_bottom_model, "Node")) instantiate_bottom_edge(mm_bottom, "__inh_4", dict_read(mm_bottom_model, "Float"), dict_read(mm_bottom_model, "Node")) instantiate_bottom_edge(mm_bottom, "__inh_5", dict_read(mm_bottom_model, "String"), dict_read(mm_bottom_model, "Node")) instantiate_bottom_edge(mm_bottom, "__inh_6", dict_read(mm_bottom_model, "Boolean"), dict_read(mm_bottom_model, "Node")) instantiate_bottom_edge(mm_bottom, "__inh_7", dict_read(mm_bottom_model, "Edge"), dict_read(mm_bottom_model, "Node")) // Retype it with itself mapping = create_node() dict_add(mapping, dict_read(mm_bottom_model, "Node"), dict_read(mm_bottom_model, "Node")) dict_add(mapping, dict_read(mm_bottom_model, "Type"), dict_read(mm_bottom_model, "Type")) dict_add(mapping, dict_read(mm_bottom_model, "Integer"), dict_read(mm_bottom_model, "Type")) dict_add(mapping, dict_read(mm_bottom_model, "Float"), dict_read(mm_bottom_model, "Type")) dict_add(mapping, dict_read(mm_bottom_model, "String"), dict_read(mm_bottom_model, "Type")) dict_add(mapping, dict_read(mm_bottom_model, "Boolean"), dict_read(mm_bottom_model, "Type")) dict_add(mapping, dict_read(mm_bottom_model, "Action"), dict_read(mm_bottom_model, "Type")) dict_add(mapping, dict_read(mm_bottom_model, "Edge"), dict_read(mm_bottom_model, "Edge")) dict_add(mapping, dict_read(mm_bottom_model, "__Inheritance"), dict_read(mm_bottom_model, "Edge")) dict_add(mapping, dict_read(mm_bottom_model, "__inh_1"), dict_read(mm_bottom_model, "__Inheritance")) dict_add(mapping, dict_read(mm_bottom_model, "__inh_2"), dict_read(mm_bottom_model, "__Inheritance")) dict_add(mapping, dict_read(mm_bottom_model, "__inh_3"), dict_read(mm_bottom_model, "__Inheritance")) dict_add(mapping, dict_read(mm_bottom_model, "__inh_4"), dict_read(mm_bottom_model, "__Inheritance")) dict_add(mapping, dict_read(mm_bottom_model, "__inh_5"), dict_read(mm_bottom_model, "__Inheritance")) dict_add(mapping, dict_read(mm_bottom_model, "__inh_6"), dict_read(mm_bottom_model, "__Inheritance")) dict_add(mapping, dict_read(mm_bottom_model, "__inh_7"), dict_read(mm_bottom_model, "__Inheritance")) retype(mm_bottom, mm_bottom, dict_read(mm_bottom_model, "__Inheritance"), mapping) export_node("models/LTM_bottom", mm_bottom) return 0 String function petrinet_constraints(pn_mo : Element): // Check places to have positive number of tokens Element all_elems Element elem_constraint all_elems = allInstances(pn_mo, dict_read(dict_read(dict_read(pn_mo, "metamodel"), "model"), "Place")) while (0 < read_nr_out(all_elems)): elem_constraint = set_pop(all_elems) if (integer_lt(readAttribute(pn_mo, elem_constraint, "tokens"), 0)): return "Negative number of tokens in Place " + getName(pn_mo, elem_constraint) // Check P2T transitions to have positive weight all_elems = allInstances(pn_mo, dict_read(dict_read(dict_read(pn_mo, "metamodel"), "model"), "P2T")) while (0 < read_nr_out(all_elems)): elem_constraint = set_pop(all_elems) if (integer_lt(readAttribute(pn_mo, elem_constraint, "weight"), 0)): return "Negative weight in arc " + getName(pn_mo, elem_constraint) // Check T2P transitions to have positive weight all_elems = allInstances(pn_mo, dict_read(dict_read(dict_read(pn_mo, "metamodel"), "model"), "T2P")) while (0 < read_nr_out(all_elems)): elem_constraint = set_pop(all_elems) if (integer_lt(readAttribute(pn_mo, elem_constraint, "weight"), 0)): return "Negative weight in arc " + getName(pn_mo, elem_constraint) return "OK" Element function pn_operations(): Element ops ops = create_node() dict_add(ops, "fire", petrinet_fire) dict_add(ops, "enabled", petrinet_enabled) return ops Element function petrinet_enabled(pn_m : Element): Element set_enabled set_enabled = petrinet_enabled_set(pn_m) output("Enabled transitions:") while (0 < read_nr_out(set_enabled)): output(getName(pn_m, set_pop(set_enabled))) return pn_m Element function petrinet_enabled_set(pn_mod : Element): Element all_transitions all_transitions = allInstances(pn_mod, dict_read(dict_read(dict_read(pn_mod, "metamodel"), "model"), "Transition")) Element enabled_transitions enabled_transitions = create_node() Element under_study Element in_arcs Element arc_under_study Boolean enabled while (0 < read_nr_out(all_transitions)): under_study = set_pop(all_transitions) enabled = True // Find all incoming transitions in_arcs = allIncomingAssociationInstances(pn_mod, under_study, dict_read(dict_read(dict_read(pn_mod, "metamodel"), "model"), "P2T")) while (0 < read_nr_out(in_arcs)): arc_under_study = set_pop(in_arcs) Integer present_tokens Integer required_tokens required_tokens = readAttribute(pn_mod, arc_under_study, "weight") present_tokens = readAttribute(pn_mod, read_edge_src(arc_under_study), "tokens") if (present_tokens < required_tokens): // Less tokens than required, so disable the transition completely enabled = False if (enabled): set_add(enabled_transitions, under_study) return enabled_transitions Element function petrinet_fire(pn_mode : Element): output("Transition to fire?") Element transition transition = input() if (dict_in(dict_read(pn_mode, "model"), transition)): transition = dict_read(dict_read(pn_mode, "model"), transition) if (set_in(petrinet_enabled_set(pn_mode), transition)): Element workset Element working_place Element working_arc // Consume tokens workset = allIncomingAssociationInstances(pn_mode, transition, dict_read(dict_read(dict_read(pn_mode, "metamodel"), "model"), "P2T")) while (0 < read_nr_out(workset)): working_arc = set_pop(workset) working_place = read_edge_src(working_arc) setAttribute(pn_mode, working_place, "tokens", integer_subtraction(readAttribute(pn_mode, working_place, "tokens"), readAttribute(pn_mode, working_arc, "weight"))) output(((" " + getName(pn_mode, working_place)) + ": ") + cast_i2s(readAttribute(pn_mode, working_place, "tokens"))) // Add tokens workset = allOutgoingAssociationInstances(pn_mode, transition, dict_read(dict_read(dict_read(pn_mode, "metamodel"), "model"), "T2P")) while (0 < read_nr_out(workset)): working_arc = set_pop(workset) working_place = read_edge_dst(working_arc) setAttribute(pn_mode, working_place, "tokens", integer_addition(readAttribute(pn_mode, working_place, "tokens"), readAttribute(pn_mode, working_arc, "weight"))) output(((" " + getName(pn_mode, working_place)) + ": ") + cast_i2s(readAttribute(pn_mode, working_place, "tokens"))) output("Transition fired!") else: output("Cannot fire if not enabled; aborting") else: output("Unknown transition; aborting") return pn_mode Element function petrinet_loaded(pn_model : Element): String cmd Element attr_list_pn Element attr_keys_pn String attr_key_pn Element metamodel_element_pn String typename Boolean bottom Element other_metamodel bottom = False other_metamodel = create_node() dict_add(other_metamodel, "model", dict_read(pn_model, "model")) dict_add(other_metamodel, "type_mapping", create_node()) dict_add(other_metamodel, "metamodel", import_node("models/LTM_bottom")) dict_add(other_metamodel, "inheritance", dict_read(dict_read(dict_read(other_metamodel, "metamodel"), "model"), "__Inheritance")) output("Model loaded, ready for commands!") output("Use 'help' command for a list of possible commands") while (True): output("Please give your command.") cmd = input() if (cmd == "help"): output("Generic model operations:") output(" instantiate -- Create a new model element") output(" delete -- Delete an existing element") output(" modify -- Modify attribute of an existing element") output(" rename -- Rename an existing element") output(" list -- Prints the list of elements in the model") output(" types -- Prints the list of elements that can be instantiated") output(" read -- Prints the current state of a model element") output(" verify -- Check whether the model conforms to the metamodel") output(" retype -- Change the type of an element") output(" switch -- Switch between conformance bottom and the linguistic metamodel") output(" exit -- Unload the model and go back to the loading prompt") if (bool_not(bottom)): output("Model-specific operations:") Element specific_ops specific_ops = dict_keys(pn_operations()) String specific_op while (0 < dict_len(specific_ops)): specific_op = set_pop(specific_ops) output(" " + specific_op) elif (cmd == "exit"): return pn_model elif (cmd == "instantiate"): String mm_type_name output("Type to instantiate?") mm_type_name = input() if (dict_in(dict_read(dict_read(pn_model, "metamodel"), "model"), mm_type_name)): metamodel_element_pn = dict_read(dict_read(dict_read(pn_model, "metamodel"), "model"), mm_type_name) String element_name output("Name of new element?") element_name = input() if (dict_in(dict_read(pn_model, "model"), element_name)): output("Element already exists; aborting") else: Boolean cnt cnt = True Element additional_opts additional_opts = create_node() if (is_edge(metamodel_element_pn)): output("Source name?") String src_name src_name = input() if (dict_in(dict_read(pn_model, "model"), src_name)): list_append(additional_opts, dict_read(dict_read(pn_model, "model"), src_name)) output("Destination name?") String dst_name dst_name = input() if (dict_in(dict_read(pn_model, "model"), dst_name)): list_append(additional_opts, dict_read(dict_read(pn_model, "model"), dst_name)) else: output("Unknown destination; aborting") cnt = False else: output("Unknown source; aborting") cnt = False if (type_eq(typeof(metamodel_element_pn), Type)): // It is a value output("Value?") list_append(additional_opts, input()) if (cnt): attr_list_pn = getAttributeList(pn_model, metamodel_element_pn) attr_keys_pn = dict_keys(attr_list_pn) Element attrs attrs = create_node() while (0 < read_nr_out(attr_keys_pn)): attr_key_pn = set_pop(attr_keys_pn) output(((attr_key_pn + " : ") + cast_t2s(dict_read(attr_list_pn, attr_key_pn))) + "?") dict_add(attrs, attr_key_pn, input()) Element resulting_element resulting_element = instantiate_model_lib(pn_model, metamodel_element_pn, element_name, additional_opts, create_node(), attrs) output("Instantiation successful!") else: output("Unknown type specified; aborting") elif (cmd == "delete"): output("What is the name of the element you want to delete?") cmd = input() if (dict_in(dict_read(pn_model, "model"), cmd)): delete_element(dict_read(dict_read(pn_model, "model"), cmd)) output("Deleted!") else: output("No such element; aborting") elif (cmd == "modify"): output("Element to modify?") cmd = input() if (dict_in(dict_read(pn_model, "model"), cmd)): Element mod mod = dict_read(dict_read(pn_model, "model"), cmd) metamodel_element_pn = dict_read_node(dict_read(pn_model, "type_mapping"), mod) attr_list_pn = getAttributeList(pn_model, metamodel_element_pn) attr_keys_pn = dict_keys(attr_list_pn) while (0 < read_nr_out(attr_keys_pn)): attr_key_pn = set_pop(attr_keys_pn) output(((" " + attr_key_pn) + " : ") + cast_t2s(dict_read(attr_list_pn, attr_key_pn))) output("Attribute to modify?") String attr_name attr_name = input() if (set_in(dict_keys(getAttributeList(pn_model, metamodel_element_pn)), attr_name)): output("New value?") setAttribute(pn_model, mod, attr_name, input()) output("Modified!") else: output("Unknown attribute; aborting") else: output("Element does not exist; aborting") elif (cmd == "rename"): output("Old name?") String old_name_e old_name_e = input() if (dict_in(dict_read(pn_model, "model"), old_name_e)): output("New name?") String new_name_e new_name_e = input() if (dict_in(dict_read(pn_model, "model"), new_name_e)): output("New name already used; aborting") else: dict_add(dict_read(pn_model, "model"), new_name_e, dict_read(dict_read(pn_model, "model"), old_name_e)) dict_delete(dict_read(pn_model, "model"), old_name_e) output("Rename complete!") else: output("Unknown element; aborting") elif (cmd == "list"): Element keys_m keys_m = dict_keys(dict_read(pn_model, "model")) output("List of all elements:") String v_m while (read_nr_out(keys_m) > 0): v_m = set_pop(keys_m) // Filter out anonymous objects typename = getName(dict_read(pn_model, "metamodel"), dict_read_node(dict_read(pn_model, "type_mapping"), dict_read(dict_read(pn_model, "model"), v_m))) if (bool_not(string_startswith(v_m, "__"))): output(((" " + v_m) + " : ") + typename) elif (cmd == "read"): output("Element to read?") cmd = input() if (dict_in(dict_read(pn_model, "model"), cmd)): Element read_elem read_elem = dict_read(dict_read(pn_model, "model"), cmd) metamodel_element_pn = dict_read_node(dict_read(pn_model, "type_mapping"), read_elem) output("Name: " + cmd) output("Type: " + getName(dict_read(pn_model, "metamodel"), metamodel_element_pn)) if (is_edge(read_elem)): output("Source: " + getName(pn_model, read_edge_src(read_elem))) output("Destination: " + getName(pn_model, read_edge_dst(read_elem))) if (cast_v2s(read_elem) != "None"): output("Value: " + cast_v2s(read_elem)) output("Defines attributes:") attr_list_pn = getInstantiatableAttributes(pn_model, read_elem) attr_keys_pn = dict_keys(attr_list_pn) while (0 < read_nr_out(attr_keys_pn)): attr_key_pn = set_pop(attr_keys_pn) output((((" " + attr_key_pn) + " : ") + cast_t2s(dict_read(attr_list_pn, attr_key_pn)))) output("Attributes:") attr_list_pn = getAttributeList(pn_model, metamodel_element_pn) attr_keys_pn = dict_keys(attr_list_pn) while (0 < read_nr_out(attr_keys_pn)): attr_key_pn = set_pop(attr_keys_pn) output(((((" " + attr_key_pn) + " : ") + cast_t2s(dict_read(attr_list_pn, attr_key_pn))) + " = ") + cast_v2s(readAttribute(pn_model, read_elem, attr_key_pn))) else: output("Unknown element; aborting") elif (cmd == "verify"): output(conformance_scd(pn_model)) elif (cmd == "types"): Element keys_t keys_t = dict_keys(dict_read(dict_read(pn_model, "metamodel"), "model")) output("List of types:") String v_t while (read_nr_out(keys_t) > 0): v_t = set_pop(keys_t) if (bool_not(string_startswith(v_t, "__"))): output(string_join((" " + v_t) + " : ", getName(dict_read(dict_read(pn_model, "metamodel"), "metamodel"), dict_read_node(dict_read(dict_read(pn_model, "metamodel"), "type_mapping"), dict_read(dict_read(dict_read(pn_model, "metamodel"), "model"), v_t))))) elif (cmd == "retype"): output("Element to retype?") String elementname elementname = input() if (dict_in(dict_read(pn_model, "model"), elementname)): output("New type") typename = input() if (dict_in(dict_read(dict_read(pn_model, "metamodel"), "model"), typename)): // OK, do the retyping // First try removing the previous type if it exists dict_delete(dict_read(pn_model, "type_mapping"), dict_read(dict_read(pn_model, "model"), elementname)) // Now add the new type dict_add(dict_read(pn_model, "type_mapping"), dict_read(dict_read(pn_model, "model"), elementname), dict_read(dict_read(dict_read(pn_model, "metamodel"), "model"), typename)) output("Retyped!") else: output("Unknown type; aborting") else: output("Unknown element; aborting") elif (cmd == "switch"): bottom = bool_not(bottom) Element tmp_model tmp_model = pn_model pn_model = other_metamodel other_metamodel = tmp_model if (bottom): // The type mapping we are using is probably not complete for our model // so we completely recreate it from the model we have. output("Switching to conformance bottom mode!") generate_bottom_type_mapping(pn_model) else: // We already switched the models and such, so we are already done! output("Switching to linguistic metamodel!") elif (bool_and(dict_in(pn_operations(), cmd), bool_not(bottom))): // A model-specific operation, so execute that one Element specific_op specific_op = dict_read(pn_operations(), cmd) specific_op(pn_model) else: output("Unknown command; aborting") output("Use command 'help' to get a list of available commands") Element function initial_prompt(): output("Welcome to the Model Management Interface, running live on the Modelverse!") output("Use 'help' command for a list of possible commands") String command Element root Element metamodel String name Element my_model String mm_name create_metamodels() dict_add(dict_read(read_root(), "__hierarchy"), "models", create_node()) root = dict_read(dict_read(read_root(), "__hierarchy"), "models") while (True): output("Please give your command.") command = input() if (command == "help"): output("Currently no model is loaded, so your operations are limited to:") output(" new -- Create a new model and save it for future use") output(" load -- Load a previously made model") output(" rename -- Rename a previously made model") output(" delete -- Delete a previously made model") output(" list -- Show a list of all stored models") output(" help -- Show a list of possible commands") elif (command == "new"): output("Metamodel to instantiate?") mm_name = input() if (dict_in(root, mm_name)): output("Name of model?") name = input() if (dict_in(root, name)): output("Model exists; aborting") else: my_model = instantiate_new_model(dict_read(root, mm_name), create_node()) dict_add(root, name, my_model) petrinet_loaded(my_model) else: output("Unknown metamodel; aborting") elif (command == "load"): output("Model to load?") name = input() if (dict_in(root, name)): my_model = dict_read(root, name) petrinet_loaded(my_model) else: output("Model not found; aborting") elif (command == "list"): Element keys keys = dict_keys(root) output("Found models:") String m_menu_list while (read_nr_out(keys) > 0): m_menu_list = set_pop(keys) output(((" " + m_menu_list) + " : ") + reverseNameLookup(root, dict_read(dict_read(root, m_menu_list), "metamodel"))) elif (command == "delete"): output("Model to delete?") name = input() if (dict_in(root, name)): dict_delete(root, name) output("Deleted!") else: output("Model not found; aborting") elif (command == "rename"): output("Old name?") String old_name old_name = input() if (dict_in(root, old_name)): output("New name?") String new_name new_name = input() if (dict_in(root, new_name)): output("Model exists; aborting") else: dict_add(root, new_name, dict_read(root, old_name)) dict_delete(root, old_name) output("Rename complete!") else: output("Model not found; aborting") else: output("Command not recognized, use 'help' for a list of possible commands") Void function main(): initial_prompt()