include "primitives.alh" include "modelling.alh" include "object_operations.alh" include "library.alh" include "conformance_scd.alh" include "io.alh" include "metamodels.alh" include "compilation_manager.alh" Element function retype_to_runtime(design_model : Element): Element runtime_model Element all_states Element all_links String mm_type_name String element_name String attr_name String attr_value String attribute String src String dst String time runtime_model = instantiate_model(import_node("models/FiniteStateAutomata_Runtime")) log("Retyping") all_states = allInstances(design_model, "State") while (list_len(all_states) > 0): element_name = set_pop(all_states) mm_type_name = reverseKeyLookup(design_model["metamodel"]["model"], dict_read_node(design_model["type_mapping"], design_model["model"][element_name])) element_name = instantiate_node(runtime_model, mm_type_name, element_name) instantiate_attribute(runtime_model, element_name, "name", read_attribute(design_model, element_name, "name")) // Don't merge this together with the block conversion, as the destination block might not exist yet! all_links = allInstances(design_model, "Transition") while (read_nr_out(all_links) > 0): element_name = set_pop(all_links) src = reverseKeyLookup(design_model["model"], read_edge_src(design_model["model"][element_name])) dst = reverseKeyLookup(design_model["model"], read_edge_dst(design_model["model"][element_name])) instantiate_link(runtime_model, "Transition", element_name, src, dst) instantiate_attribute(runtime_model, element_name, "event", read_attribute(design_model, element_name, "event")) if (element_neq(read_attribute(design_model, element_name, "raise"), read_root())): // There is a raise attribute instantiate_attribute(runtime_model, element_name, "raise", read_attribute(design_model, element_name, "raise")) log("DONE") return runtime_model! Element function sanitize(new_runtime_model : Element, old_runtime_model : Element, auto : Boolean): String cstate String cstate_obj log("Start sanitize") cstate_obj = instantiate_node(new_runtime_model, "CurrentState", "") if (read_nr_out(allInstances(old_runtime_model, "CurrentStateLink")) > 0): cstate = readAssociationDestination(old_runtime_model, set_pop(allInstances(old_runtime_model, "CurrentStateLink"))) if (bool_not(dict_in(new_runtime_model["model"], cstate))): // Current state removed, so fix if (auto): cstate = set_pop(allInstances(new_runtime_model, "InitialState")) else: while (bool_not(dict_in(new_runtime_model["model"], cstate))): output("REQUEST_CURRENT_STATE") cstate = input() else: // Initialize for the first time cstate = set_pop(allInstances(new_runtime_model, "InitialState")) instantiate_link(new_runtime_model, "CurrentStateLink", "", cstate_obj, cstate) log("Sanitize OK") return new_runtime_model! Void function do_transition(model : Element, start_time : Float, event : String): // Read out current state String cstate_link String cstate_obj String cstate String transition String new_state String raise log("Transition executing") cstate_link = set_pop(allInstances(model, "CurrentStateLink")) cstate = readAssociationDestination(model, cstate_link) cstate_obj = readAssociationSource(model, cstate_link) // Read out all outgoing transitions Element all_transitions all_transitions = allOutgoingAssociationInstances(model, cstate, "Transition") output("SIM_TIME " + cast_v2s(time() - start_time)) output("SIM_EVENT " + cast_v2s(event)) while (read_nr_out(all_transitions) > 0): transition = set_pop(all_transitions) if (value_eq(read_attribute(model, transition, "event"), event)): // Found a match model_delete_element(model, cstate_link) // Set destination of state instantiate_link(model, "CurrentStateLink", "", cstate_obj, new_state) output("SIM_STATE " + cast_v2s(new_state)) // Raise "raise" attribute of transition raise = read_attribute(model, transition, "raise") if (element_neq(raise, read_root())): // Raise the event output("SIM_RAISE " + cast_v2s(raise)) return ! return! Void function execute_fsa(design_model : Element): String verify_result Element runtime_model Element old_runtime_model String cmd Boolean running String conforming Float simulation_time Float start_time Boolean automatic_sanitization automatic_sanitization = True start_time = time() simulation_time = 0.0 old_runtime_model = instantiate_model(import_node("models/FiniteStateAutomata_Runtime")) runtime_model = retype_to_runtime(design_model) conforming = conformance_scd(design_model) log("Conformance: " + conforming) if (conforming == "OK"): output("CONFORMANCE_OK") else: output("CONFORMANCE_FAIL") while (True): if (has_input()): cmd = input() else: if (conforming == "OK"): cmd = "skip" else: cmd = input() log("Do: " + cmd) // Process input if (cmd == "skip"): if (conforming == "OK"): output("SIM_TIME " + cast_v2s(time() - start_time)) output("SIM_STATE " + cast_v2s(readAssociationDestination(runtime_model, set_pop(allInstances(runtime_model, "CurrentStateLink"))))) elif (cmd == "pause"): // Pausing merely stops a running simulation simulation_time = time() - start_time output("PAUSED") while (cmd != "simulate"): cmd = input() start_time = time() - simulation_time output("CONTINUE") elif (cmd == "auto_sanitize"): automatic_sanitization = input() elif (cmd == "event"): String evt evt = input() do_transition(runtime_model, start_time, evt) elif (cmd == "read_available_attributes"): // Returns a list of all available attributes Element attr_list Element attrs Element attr attr_list = getAttributeList(design_model, input()) attrs = dict_keys(attr_list) while (0 < read_nr_out(attrs)): attr = set_pop(attrs) output("AVAILABLE_ATTR_VALUE " + cast_v2s(attr)) output("AVAILABLE_ATTR_TYPE " + cast_v2s(dict_read(attr_list, attr))) output("AVAILABLE_ATTR_END") elif (cmd == "read_attribute"): // Returns the value of an attribute output("ATTR_VALUE " + cast_v2s(read_attribute(design_model, input(), input()))) elif (bool_or(cmd == "switch_initial", bool_or(bool_or(cmd == "set_attribute", cmd == "instantiate_node"), bool_or(cmd == "delete_element", cmd == "instantiate_association")))): // Modify the structure if (cmd == "set_attribute"): // Setting an attribute String element_name String attribute_name element_name = input() attribute_name = input() // Delete it if it exists already if (bool_not(element_eq(read_attribute(design_model, element_name, attribute_name), read_root()))): unset_attribute(design_model, element_name, attribute_name) // And finally set it instantiate_attribute(design_model, element_name, attribute_name, input()) elif (cmd == "instantiate_node"): // Instantiate a node instantiate_node(design_model, input(), input()) elif (cmd == "instantiate_association"): // Instantiate an association instantiate_link(design_model, input(), input(), input(), input()) elif (cmd == "delete_element"): // Delete the provided element model_delete_element(design_model, input()) elif (cmd == "switch_initial"): // Switch the initial state if (read_nr_out(allInstances(design_model, "InitialState")) > 0): retype(design_model, set_pop(allInstances(design_model, "InitialState")), "State") retype(design_model, input(), "InitialState") // After changes, we check whether or not the design model conforms if (conforming == "OK"): // Was correct, so store just to make sure simulation_time = time() - start_time conforming = conformance_scd(design_model) if (conforming == "OK"): // Conforming, so do the retyping and sanitization step runtime_model = retype_to_runtime(design_model) runtime_model = sanitize(runtime_model, old_runtime_model, automatic_sanitization) old_runtime_model = runtime_model start_time = time() - simulation_time output("CONFORMANCE_OK") log("Conformance became OK") else: // Not conforming, so stop simulation and block for input (preferably a modify to make everything consistent again) output("CONFORMANCE_FAIL " + conforming) else: log("Did not understand command: " + cmd) Void function main(): Element model String verify_result while (True): execute_fsa(instantiate_model(import_node("models/FiniteStateAutomata_Design")))