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" //helper function that returns the type of an attribute in string format Element function find_attribute_type_s(model : Element, elem : String, name : String): Element mm_elem Element direct_type direct_type = dict_read_node(model["type_mapping"], model["model"][elem]) mm_elem = find_attribute_definer(model["metamodel"], direct_type, name) if (element_eq(mm_elem, read_root())): // Couldn't find element, so is not allowed! log("Undefined attribute!") return read_root() else: return getName(model["metamodel"], read_edge_dst( dict_read_edge(mm_elem, name))) //given a model and a node, it will return the name of it's type in the metamodel String function getTypeName(model:Element, node:Element): return getName(model["metamodel"], dict_read_node(model["type_mapping"], node)) //given a model and a node it will return the name of it's type in the metametamodel String function getMetaTypeName(model:Element, node:Element): return getTypeName(model["metamodel"], dict_read_node(model["type_mapping"], node)) Boolean function isAttributeRelated(model:Element, node:Element): if(getMetaTypeName(model, node) == "Type"): return True elif(getMetaTypeName(model, node) == "l5"): if(getMetaTypeName(model, read_edge_dst(node)) == "Type" ): return True return False //function to print information about a node (attributes, type and name) Element function printNode(tf_pn_model: Element, tf_pn_node: Element): //print header with name, metatype //print node_name String tf_pn_node_name tf_pn_node_name = getName(tf_pn_model, tf_pn_node) log(string_join("--name: ",tf_pn_node_name) ) //print node type log(string_join("type: ", getTypeName(tf_pn_model, tf_pn_node) )) //print node metatype String metatype metatype = getMetaTypeName(tf_pn_model, tf_pn_node) log(string_join("metatype: ", metatype)) if (isAttributeRelated(tf_pn_model, tf_pn_node)): log(">attribute related") //print attributes log("attributes:") //get the list of attributes Element tf_pn_attributelist tf_pn_attributelist = dict_keys(getAttributeList(tf_pn_model, tf_pn_node_name)) String tf_pn_attributename String tf_pn_attributetype while (integer_lt(0, read_nr_out(tf_pn_attributelist))): //print attribute name and its value tf_pn_attributename = set_pop(tf_pn_attributelist) tf_pn_attributetype = find_attribute_type_s(tf_pn_model, tf_pn_node_name, tf_pn_attributename) if( tf_pn_attributetype == "String"): log(string_join(string_join(string_join(" ",tf_pn_attributename), " : "),read_attribute(tf_pn_model, tf_pn_node_name, tf_pn_attributename))) elif (tf_pn_attributetype == "Integer"): log(string_join(string_join(string_join(" ",tf_pn_attributename), " : "),cast_i2s(read_attribute(tf_pn_model, tf_pn_node_name, tf_pn_attributename)))) else: log(string_join(tf_pn_attributename, " : ")) log(read_attribute(tf_pn_model, tf_pn_node_name, tf_pn_attributename)) return 0 Boolean function node_match(transf_model : Element, transf_elem : Element, host_model : Element, host_elem : Element): //type equality String type1 type1 = getTypeName(transf_model, transf_elem) String type2 type2 = string_join(getTypeName(host_model, host_elem), "_LHS") if (type1 != type2): return False //semantic check Element func func = transf_model["semantic_checks"][read_attribute(transf_model, getName(transf_model,transf_elem), "function")] return func(host_model, host_elem) Integer function are_connected(model: Element, el1:Element, el2:Element): String el1_mmt String el2_mmt el1_mmt = getMetaTypeName(model, el1) el2_mmt = getMetaTypeName(model, el2) if ( el1_mmt == "Class" ): if(el2_mmt == "Class"): return 0 //not connected, no edge inbetween elif(el2_mmt == "l5"): if( element_eq(read_edge_src(el2) , el1)): return 1 //outgoing elif( element_eq(read_edge_dst(el2) , el1)): return 2 //incoming else: return 0 //the edge is not connected else: log("is_connected_to: unsupported type for second element") log(string_join("type = ", el2_mmt)) elif (el1_mmt == "l5"): if( element_eq(read_edge_src(el1) , el2)): return 2 //incoming elif( element_eq(read_edge_dst(el1) , el2)): return 1 //outgoing else: return 0 //edge is not connected else: log("is_connected_to: unsupported type for first element") log(string_join("type = ", el1_mmt)) return 0 // if the function doesn't support it, assume disconnected Element function new_SearchState(OldSearchState : Element, TransfModel : Element, NewTransfElem: Element, HostModel : Element, NewHostElem : Element): //some variables Element nss // new searchstate nss = create_node() Integer index // used for list looping Element elem // reusable loop variable //new MATCHES dict_add(nss, "matches", OldSearchState["matches"]) //hopefully works as a reference //new CURMATCH Element OldCurMatchKeys // for looping trough old curmatch (for copying) OldCurMatchKeys = dict_keys(OldSearchState["curmatch"]) Element new_curmatch //the new curmatch new_curmatch = create_node() Element oldkey // loop variable while (integer_lt(0, list_len(OldCurMatchKeys))): //copying the old curmatch oldkey = set_pop(OldCurMatchKeys) dict_add(new_curmatch, oldkey, OldSearchState["curmatch"][oldkey]) //WARNING dict_read_node needed??? Element newPair // the new pair to be added newPair = create_node() dict_add(newPair, "pn", NewTransfElem) //PatternNode dict_add(newPair, "hn", NewHostElem) // HostNode Integer plabel plabel = read_attribute(TransfModel, getName(TransfModel, NewTransfElem), "plabel") dict_add(new_curmatch, plabel, newPair) //add pair to new curmatch dict_add(nss, "curmatch", new_curmatch) //add curmatch to state //new N_PATTERN_OUT (copy everything but the new match elements) Element ol //old list = old pattern out Element nl //new list = new N pattern out ol = OldSearchState["N_pattern_out"] nl = create_node() index = 0 while (index < list_len(ol)): //loop trough old list elem = list_read(ol, index) index = index + 1 if(bool_not(element_eq(elem, NewTransfElem))): list_append(nl, elem) dict_add(nss, "N_pattern_out", nl) //new N_HOST_OUT (copy everything but the new match elements) ol = OldSearchState["N_host_out"] nl = create_node() index = 0 while (index < list_len(ol)): //loop trough old list elem = list_read(ol, index) index = index + 1 if(bool_not(element_eq(elem, NewHostElem))): list_append(nl, elem) dict_add(nss, "N_host_out", nl) //new N_PATTERN_IN (copy everything but the new match elements) ol = OldSearchState["N_pattern_in"] nl = create_node() index = 0 while (index < list_len(ol)): //loop trough old list elem = list_read(ol, index) index = index + 1 if(bool_not(element_eq(elem, NewTransfElem))): list_append(nl, elem) dict_add(nss, "N_pattern_in", nl) //new N_HOST_IN (copy everything but the new match elements ol = OldSearchState["N_host_in"] nl = create_node() index = 0 while (index < list_len(ol)): //loop trough old list elem = list_read(ol, index) index = index + 1 if(bool_not(element_eq(elem, NewHostElem))): list_append(nl, elem) dict_add(nss, "N_host_in", nl) //new V_PATTERN ol = OldSearchState["V_pattern"] nl = create_node() index = 0 Integer connectedness while (index < list_len(ol)): //loop trough old list elem = list_read(ol, index) index = index + 1 if(bool_not(element_eq(elem, NewTransfElem))): connectedness = are_connected(TransfModel, NewTransfElem, elem) if (connectedness == 0): // if not connected, keep in V list_append(nl, elem) elif (connectedness == 1): //if connected in outwards manner, don't keep in v and add to outlist list_append(nss["N_pattern_out"], elem) elif (connectedness == 2): //if connected in inwards manner, don't keep in v and add to inlist list_append(nss["N_pattern_in"], elem) else: log("new_SearchState: unsupported connectedness value") log(cast_i2s(connectedness)) dict_add(nss, "V_pattern", nl) //new V_HOST ol = OldSearchState["V_host"] nl = create_node() index = 0 while (index < list_len(ol)): //loop trough old list elem = list_read(ol, index) index = index + 1 if(bool_not(element_eq(elem, NewHostElem))): connectedness = are_connected(HostModel, NewHostElem, elem) if (connectedness == 0): // if not connected, keep in V list_append(nl, elem) elif (connectedness == 1): //if connected in outwards manner, don't keep in v and add to outlist list_append(nss["N_host_out"], elem) elif (connectedness == 2): //if connected in inwards manner, don't keep in v and add to inlist list_append(nss["N_host_in"], elem) else: log("new_SearchState: unsupported connectedness value") log(cast_i2s(connectedness)) dict_add(nss, "V_host", nl) // copy pattern_size dict_add(nss, "pattern_size", OldSearchState["pattern_size"]) return nss Element function transf_vf2(SearchState: Element, transf_m : Element, host_m : Element): // get the current match from the search-state Element current_match current_match = dict_read(SearchState,"curmatch") //if match is complete: add to matches and return Integer pattern_size pattern_size = SearchState["pattern_size"] if pattern_size == list_len(current_match): list_append(SearchState["matches"], SearchState["curmatch"]) return SearchState //feasability checks if (list_len(SearchState["N_pattern_out"]) > list_len(SearchState["N_host_out"])): return SearchState if (list_len(SearchState["N_pattern_in"]) > list_len(SearchState["N_host_in"])): return SearchState if (list_len(SearchState["V_pattern"]) > list_len(SearchState["V_host"])): return SearchState //initialise some variables Integer index2 //an index used for looping trough host_list Element host_list // the set with host nodes to be considered Element pattern_node // node to be tested from the patterns side Element host_node //node to be tested from the hosts side Element nss //variable for storing next searchstate //search candidate if ( list_len(SearchState["N_pattern_out"]) > 0 ): //check for candidates in (N_pattern_out, N_host_out) host_list = SearchState["N_host_out"] pattern_node = list_read(SearchState["N_pattern_out"], 0) index2 = 0 while (index2 < list_len(host_list)): host_node = list_read(host_list, index2) index2= index2 + 1 if(node_match(transf_m, pattern_node, host_m, host_node)): nss = new_SearchState(SearchState, transf_m, pattern_node, host_m, host_node) nss = transf_vf2(nss, transf_m, host_m) dict_delete(SearchState, "matches") dict_add(SearchState, "matches", nss["matches"]) elif ( list_len(SearchState["N_pattern_in"]) > 0 ): //check for candidates in (N_pattern_in, N_host_in) host_list = SearchState["N_host_in"] pattern_node = list_read(SearchState["N_pattern_in"], 0) index2 = 0 while (index2 < list_len(host_list)): host_node = list_read(host_list, index2) index2= index2 + 1 if(node_match(transf_m, pattern_node, host_m, host_node)): nss = new_SearchState(SearchState, transf_m, pattern_node, host_m, host_node) nss = transf_vf2(nss, transf_m, host_m) dict_delete(SearchState, "matches") dict_add(SearchState, "matches", nss["matches"]) elif ( list_len(SearchState["V_pattern"]) > 0 ): //check for candidates in (V_pattern, V_host)) host_list = SearchState["V_host"] pattern_node = list_read(SearchState["V_pattern"], 0) index2 = 0 while (index2 < list_len(host_list)): host_node = list_read(host_list, index2) index2= index2 + 1 if(node_match(transf_m, pattern_node, host_m, host_node)): nss = new_SearchState(SearchState, transf_m, pattern_node, host_m, host_node) nss = transf_vf2(nss, transf_m, host_m) dict_delete(SearchState, "matches") dict_add(SearchState, "matches", nss["matches"]) else: log("no candidate found") return SearchState // given a pattern, this function will return all matches in a model Element function tf_matchAll(tf_ma_transformation: Element, tf_ma_pattern : Element, tf_ma_model: Element ): //find all nodes in the pattern Element tf_ma_metamodelTransf //transformation metamodel tf_ma_metamodelTransf = tf_ma_transformation["metamodel"]["model"] Element pre2ram_et // type of the pre2ram edge pre2ram_et = dict_read(tf_ma_metamodelTransf, "pre2ram") Element tf_ma_pattern_edges //all pre2ram edges tf_ma_pattern_edges = allOutgoingAssociationInstances(tf_ma_transformation, tf_ma_pattern, pre2ram_et) Element tf_ma_ramified_nodes //dict in the form plabel->node tf_ma_ramified_nodes = create_node() Element tf_ma_ramified_node while (integer_lt(0, list_len(tf_ma_pattern_edges))): tf_ma_ramified_node = read_edge_dst(set_pop(tf_ma_pattern_edges)) list_append(tf_ma_ramified_nodes, tf_ma_ramified_node) //find all nodes in the graph that are not related to attributes: ie a userdefined type Element hostmodel_mm //metamodel of hostgraph hostmodel_mm = tf_ma_model["metamodel"]["model"] Element hostmodel_keys //keys of all elements in the model hostmodel_keys = dict_keys(tf_ma_model["model"]) Element host_nodes //all nodes in the host graph host_nodes = create_node() Element host_model_key while (integer_lt(0, read_nr_out(hostmodel_keys))): host_model_key = set_pop(hostmodel_keys) if bool_not(isAttributeRelated(tf_ma_model, tf_ma_model["model"][host_model_key])): list_append(host_nodes, tf_ma_model["model"][host_model_key]) // initialise the start-state //initialise an start state Element SearchState SearchState = create_node() dict_add(SearchState, "matches", create_node()) dict_add(SearchState, "curmatch", create_node()) dict_add(SearchState, "N_pattern_out", create_node()) dict_add(SearchState, "N_host_out", create_node()) dict_add(SearchState, "N_pattern_in", create_node()) dict_add(SearchState, "N_host_in", create_node()) dict_add(SearchState, "V_pattern", tf_ma_ramified_nodes) dict_add(SearchState, "V_host", host_nodes) dict_add(SearchState, "pattern_size", list_len(tf_ma_ramified_nodes)) //call vf2 for the matching SearchState = transf_vf2(SearchState, tf_ma_transformation, tf_ma_model) return SearchState["matches"] Element function tf_executeRule(tf_er_transformation: Element,tf_er_rule: Element, tf_er_model: Element): //TODO support for multiple ruleTypes //find LHS //TODO if no lhs (is this allowed to happen?) Element tf_er_lhs tf_er_lhs = allOutgoingAssociationInstances(tf_er_transformation, tf_er_rule, dict_read(dict_read(dict_read(tf_er_transformation, "metamodel"), "model"), "lhs")) tf_er_lhs = tf_matchAll(tf_er_transformation, read_edge_dst(set_pop(tf_er_lhs)), tf_er_model) Integer nr_of_lhs_matches nr_of_lhs_matches = list_len(tf_er_lhs) //log(string_join(cast_i2s(list_len(tf_er_lhs)), " matches found")) //find NACs if at least one lhs is found (otherwise not needed) Integer nr_of_nac_matches nr_of_nac_matches = 0 Element tf_er_nac tf_er_nac = create_node() if(nr_of_lhs_matches > 0): Element tf_er_nac_ tf_er_nac_ = allOutgoingAssociationInstances(tf_er_transformation, tf_er_rule, dict_read(dict_read(dict_read(tf_er_transformation, "metamodel"), "model"), "nac")) Element partial_nac_matches while (read_nr_out(tf_er_nac_) > 0): partial_nac_matches = tf_matchAll(tf_er_transformation, read_edge_dst(set_pop(tf_er_nac_)), tf_er_model) while (read_nr_out(partial_nac_matches)>0): list_append(tf_er_nac, set_pop(partial_nac_matches)) nr_of_nac_matches = list_len(tf_er_nac) //log(string_join(cast_i2s(list_len(tf_er_nac)), " matches found")) //remove from lhs matches that share a node with a nac match Element final_matches final_matches = create_node() Element lhs_match Element nac_match Element lhs_match_keys Element lhs_match_key Boolean allow_match Integer nac_index while(list_len(tf_er_lhs) > 0): lhs_match = set_pop(tf_er_lhs) allow_match=True nac_index = 0 while(bool_and(nac_index < read_nr_out(tf_er_nac), allow_match)): nac_match = list_read(tf_er_nac, nac_index) nac_index = nac_index + 1 lhs_match_keys = dict_keys(lhs_match) while (bool_and(read_nr_out(lhs_match_keys)>0, allow_match)): lhs_match_key = set_pop(lhs_match_keys) if dict_in(nac_match, lhs_match_key): if (element_eq(nac_match[lhs_match_key]["hn"],lhs_match[lhs_match_key]["hn"])): allow_match = False if (allow_match): list_append(final_matches, lhs_match) log(string_join("number of allowed matches: ", cast_i2s(list_len(final_matches)))) //TODO RHS return 0 Element function tf_transform(tf_tf_transformation: Element, tf_tf_model: Element): //create a list of all rules Element tf_tf_rules tf_tf_rules = allInstances(tf_tf_transformation, dict_read(dict_read(dict_read(tf_tf_transformation, "metamodel"), "model"), "Rule")) //TODO give order to rules //execute rules in random order Element tf_tf_rule while (integer_lt(0, read_nr_out(tf_tf_rules))): tf_tf_rule = set_pop(tf_tf_rules) //tf_printNode(tf_tf_transformation, tf_tf_rule) tf_executeRule(tf_tf_transformation, tf_tf_rule, tf_tf_model) return 0 Element function test_simple_petrinet1(root:Element): //create a petrinet for testing purposes // P1 -> T1 -> P2 -> T2 // 1 1 2 0 1 ////////////////////////////////// //initialise an empty petrinet Element my_model my_model = instantiate_model(root["PetriNets"]) dict_add(root, "pnt_test1", my_model) // init t1 instantiate_node(my_model, "Transition", "t1") // init p1 instantiate_node(my_model, "Place", "p1") instantiate_attribute(my_model, "p1","tokens",1) // init link1 instantiate_link(my_model, "P2T", "p1_to_t1", "p1", "t1") instantiate_attribute(my_model, "p1_to_t1", "weight", 1) //init p2 instantiate_node(my_model, "Place", "p2") instantiate_attribute(my_model, "p2","tokens",0) //init link2 instantiate_link(my_model, "T2P", "t1_to_p2", "t1", "p2") instantiate_attribute(my_model, "t1_to_p2", "weight", 2) //init t2 instantiate_node(my_model, "Transition", "t2") //init link3 instantiate_link(my_model, "P2T", "p2_to_t2", "p2", "t2") instantiate_attribute(my_model, "p2_to_t2", "weight", 1) return my_model Element function petrinet_transformation(root: Element): // Create A transformation model for petrinets (useful for testing) ////////////////////////////////// //initialise an empty transformation model for petrinet Element my_model my_model = instantiate_model(root["PetriNets_MTransformation"]) define_inheritance(my_model, "l3") dict_add(root, "transf_petrinet_fire", my_model) //////////////////////////// // root node instantiate_node(my_model, "Transformation", "PetrinetFire") instantiate_attribute(my_model, "PetrinetFire", "name", "PetriNetFire") //////////////////////////// // rule: find transitions //rule: find_transitions instantiate_node(my_model, "Rule", "find_transitions") instantiate_attribute(my_model, "find_transitions", "name", "find_transitions") instantiate_attribute(my_model, "find_transitions", "precedence", 1) //connect to transformation instantiate_link(my_model, "transformation_to_rule", "", "PetrinetFire", "find_transitions") //precondition: lhs_precondition instantiate_node(my_model, "Precondition","lhs_precondition") //connect to rule instantiate_link(my_model, "lhs", "", "find_transitions", "lhs_precondition") //Transition_LHS: lhs_find_all instantiate_node(my_model, "Transition_LHS","lhs_find_all") instantiate_attribute(my_model, "lhs_find_all", "plabel", 1) instantiate_attribute(my_model, "lhs_find_all", "function", "always_true") //connect to rule instantiate_link(my_model, "pre2ram", "", "lhs_precondition", "lhs_find_all") //precondition: nac_precondition instantiate_node(my_model, "Precondition","nac_precondition") //connect to rule instantiate_link(my_model, "nac", "", "find_transitions", "nac_precondition") //Transition_LHS: nac_transition_place_before instantiate_node(my_model, "Transition_LHS","nac_transition_before") instantiate_attribute(my_model, "nac_transition_before", "plabel", 1) instantiate_attribute(my_model, "nac_transition_before", "function", "always_true") //connect to rule instantiate_link(my_model, "pre2ram", "", "nac_precondition", "nac_transition_before") //Place_LHS: nac_place_before instantiate_node(my_model, "Place_LHS","nac_place_before") instantiate_attribute(my_model, "nac_place_before", "plabel", 2) instantiate_attribute(my_model, "nac_place_before", "function", "always_true") //connect to rule instantiate_link(my_model, "pre2ram", "", "nac_precondition", "nac_place_before") //P2T_LHS: nac_ft_p2t instantiate_link(my_model, "P2T_LHS", "nac_p2tlhs_before", "nac_place_before", "nac_transition_before") instantiate_attribute(my_model, "nac_p2tlhs_before", "plabel", 3) instantiate_attribute(my_model, "nac_p2tlhs_before", "function", "is_not_consumable") //connect to rule instantiate_link(my_model, "pre2ram", "", "nac_precondition", "nac_p2tlhs_before") Element semantic_checks semantic_checks = create_node() dict_add(semantic_checks, "always_true", always_true) dict_add(semantic_checks, "is_not_consumable", is_not_consumable) dict_add(my_model, "semantic_checks", semantic_checks) return my_model Boolean function is_not_consumable(model : Element, matched_node : Element): //get place before Element place_before place_before = read_edge_src(matched_node) //get tokens from place Integer tokens tokens = read_attribute(model, getName(model, place_before), "tokens") //get weight from matched_node Integer weight weight = read_attribute(model, getName(model, matched_node), "weight") return weight > tokens Boolean function always_true(model : Element, self : Element): return True 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(model : Element): Element set_enabled set_enabled = petrinet_enabled_set(model) output("Enabled transitions:") while (0 < read_nr_out(set_enabled)): output(getName(model, set_pop(set_enabled))) return model Element function petrinet_enabled_set(model : Element): Element all_transitions all_transitions = allInstances(model, model["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(model, under_study, model["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 = read_attribute(model, getName(model, arc_under_study), "weight") present_tokens = read_attribute(model, getName(model, 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(model : Element): output("Transition to fire?") Element transition transition = input() if (dict_in(model["model"], transition)): transition = model["model"][transition] if (set_in(petrinet_enabled_set(model), transition)): Element workset Element working_place Element working_arc Integer new_value // Consume tokens workset = allIncomingAssociationInstances(model, transition, model["metamodel"]["model"]["P2T"]) while (0 < read_nr_out(workset)): working_arc = set_pop(workset) working_place = read_edge_src(working_arc) new_value = integer_subtraction(read_attribute(model, getName(model, working_place), "tokens"), read_attribute(model, getName(model, working_arc), "weight")) unset_attribute(model, getName(model, working_place), "tokens") instantiate_attribute(model, getName(model, working_place), "tokens", new_value) output(((" " + getName(model, working_place)) + ": ") + cast_i2s(read_attribute(model, getName(model, working_place), "tokens"))) // Add tokens workset = allOutgoingAssociationInstances(model, transition, model["metamodel"]["model"]["T2P"]) while (0 < read_nr_out(workset)): working_arc = set_pop(workset) working_place = read_edge_dst(working_arc) new_value = integer_addition(read_attribute(model, getName(model, working_place), "tokens"), read_attribute(model, getName(model, working_arc), "weight")) unset_attribute(model, getName(model, working_place), "tokens") instantiate_attribute(model, getName(model, working_place), "tokens", new_value) output(((" " + getName(model, working_place)) + ": ") + cast_i2s(read_attribute(model, getName(model, working_place), "tokens"))) output("Transition fired!") else: output("Cannot fire if not enabled; aborting") else: output("Unknown transition; aborting") return model Element function petrinet_loaded(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", 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", 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(" attr_add -- Add an attribute to an element") output(" attr_del -- Delete an attribute of an element") output(" rename -- Rename an existing element") output(" modify -- Modify the attributes of an 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 model elif (cmd == "instantiate"): String mm_type_name output("Type to instantiate?") mm_type_name = input() if (dict_in(model["metamodel"]["model"], mm_type_name)): String element_name output("Name of new element?") element_name = input() if (dict_in(model["model"], element_name)): output("Element already exists; aborting") else: if (is_edge(model["metamodel"]["model"][mm_type_name])): output("Source name?") String src_name src_name = input() if (dict_in(model["model"], src_name)): output("Destination name?") String dst_name dst_name = input() if (dict_in(model["model"], dst_name)): instantiate_link(model, mm_type_name, element_name, src_name, dst_name) if (dict_in(model["model"], element_name)): output("Instantiation successful!") else: output("Instantiation error!") else: output("Unknown destination; aborting") else: output("Unknown source; aborting") else: instantiate_node(model, mm_type_name, element_name) if (dict_in(model["model"], element_name)): output("Instantiation successful!") else: output("Instantiation error!") else: output("Unknown type specified; aborting") elif (cmd == "modify"): String model_name output("Element to modify?") model_name = input() if (dict_in(model["model"], model_name)): Element attrs attrs = getAttributeList(model, model_name) String attr_name output("Attribute to modify?") attr_name = input() if (set_in(dict_keys(attrs), attr_name)): output("New value?") unset_attribute(model, model_name, attr_name) instantiate_attribute(model, model_name, attr_name, input()) output("Modified!") else: output("No such attribute!") else: output("No such model!") elif (cmd == "attr_add"): String model_name output("Which model do you want to assign an attribute to?") model_name = input() if (dict_in(model["model"], model_name)): Element attrs attrs = getAttributeList(model, model_name) String attr_name output("Which attribute do you wish to assign?") attr_name = input() if (set_in(dict_keys(attrs), attr_name)): output("Value of attribute?") instantiate_attribute(model, model_name, attr_name, input()) output("Added attribute!") else: output("No such attribute!") else: output("No such model!") elif (cmd == "attr_del"): String model_name output("Which model do you want to remove an attribute of?") model_name = input() if (dict_in(model["model"], model_name)): Element attrs attrs = getAttributeList(model, model_name) output(print_dict(attrs)) String attr_name output("Which attribute do you want to delete?") attr_name = input() if (set_in(dict_keys(attrs), attr_name)): unset_attribute(model, model_name, attr_name) else: output("No such attribute!") else: output("No such model!") elif (cmd == "delete"): output("What is the name of the element you want to delete?") cmd = input() if (dict_in(model["model"], cmd)): model_delete_element(model, cmd) output("Deleted!") else: output("No such element; aborting") elif (cmd == "rename"): output("Old name?") String old_name_e old_name_e = input() if (dict_in(model["model"], old_name_e)): output("New name?") String new_name_e new_name_e = input() if (dict_in(model["model"], new_name_e)): output("New name already used; aborting") else: dict_add(model["model"], new_name_e, model["model"][old_name_e]) dict_delete(model["model"], old_name_e) output("Rename complete!") else: output("Unknown element; aborting") elif (cmd == "list"): Element keys_m keys_m = dict_keys(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(model["metamodel"], dict_read_node(model["type_mapping"], 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(model["model"], cmd)): Element read_elem read_elem = model["model"][cmd] metamodel_element_pn = dict_read_node(model["type_mapping"], read_elem) output("Name: " + cmd) output("Type: " + getName(model["metamodel"], metamodel_element_pn)) if (is_edge(read_elem)): output("Source: " + getName(model, read_edge_src(read_elem))) output("Destination: " + getName(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(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_v2s(attr_list_pn[attr_key_pn]))) output("Attributes:") attr_list_pn = getAttributeList(model, cmd) 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(((((" " + cast_v2s(attr_key_pn)) + " : ") + cast_v2s(attr_list_pn[attr_key_pn])) + " = ") + cast_v2s(read_attribute(model, getName(model, read_elem), attr_key_pn))) else: output("Unknown element; aborting") elif (cmd == "verify"): output(conformance_scd(model)) elif (cmd == "types"): Element keys_t keys_t = dict_keys(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(model["metamodel"]["metamodel"], dict_read_node(model["metamodel"]["type_mapping"], model["metamodel"]["model"][v_t])))) elif (cmd == "retype"): output("Element to retype?") String elementname elementname = input() if (dict_in(model["model"], elementname)): output("New type") typename = input() if (dict_in(model["metamodel"]["model"], typename)): // OK, do the retyping // First try removing the previous type if it exists dict_delete(model["type_mapping"], model["model"][elementname]) // Now add the new type dict_add(model["type_mapping"], model["model"][elementname], 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 = model 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(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(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 root = create_metamodels() 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_model(root[mm_name]) 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 = root[name] petrinet_loaded(my_model) else: output("Model not found; aborting") elif (command == "list"): Element keys String m_menu_list keys = dict_keys(root) output("Found models:") while (read_nr_out(keys) > 0): m_menu_list = set_pop(keys) output(((" " + m_menu_list) + " : ") + reverseNameLookup(root, 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, 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() log("==========================================================================") log("=== creating metamodels") Element root root = create_metamodels() log("=== load instantiation of transformation metamodel") Element transf transf = petrinet_transformation(root) log("=== load test1") Element test1 test1 = test_simple_petrinet1(root) log("=== check conformance of transformation") log(conformance_scd(transf)) log("=== run transform") tf_transform(transf, test1) log("=== done") log("==========================================================================") return