|
@@ -3,28 +3,16 @@ include "modelling.alh"
|
|
|
include "object_operations.alh"
|
|
|
include "library.alh"
|
|
|
include "conformance_scd.alh"
|
|
|
-include "mini_modify.alh"
|
|
|
+include "io.alh"
|
|
|
+include "metamodels.alh"
|
|
|
+include "compilation_manager.alh"
|
|
|
|
|
|
Void function main():
|
|
|
Element model
|
|
|
String verify_result
|
|
|
|
|
|
while (True):
|
|
|
- output("Which model do you want to execute with CBD semantics?")
|
|
|
- model = import_node(input())
|
|
|
-
|
|
|
- if (element_eq(model, read_root())):
|
|
|
- output("Could not find model; aborting")
|
|
|
- elif (element_neq(model["metamodel"], import_node("models/CausalBlockDiagrams_Design"))):
|
|
|
- output("Not a CBD design model; aborting")
|
|
|
- else:
|
|
|
- verify_result = conformance_scd(model)
|
|
|
- if (verify_result == "OK"):
|
|
|
- output("Model OK!")
|
|
|
- log("Model conforms!")
|
|
|
- execute_cbd(model)
|
|
|
- else:
|
|
|
- output("Non-conforming model: " + verify_result)
|
|
|
+ execute_cbd(instantiate_model(import_node("models/CausalBlockDiagrams_Design")))
|
|
|
|
|
|
Element function retype_to_runtime(design_model : Element):
|
|
|
Element runtime_model
|
|
@@ -78,7 +66,6 @@ Element function sanitize(new_runtime_model : Element, old_runtime_model : Eleme
|
|
|
String time
|
|
|
Element all_attributes
|
|
|
Integer current_time
|
|
|
- Integer termination_time
|
|
|
|
|
|
all_blocks = allInstances(new_runtime_model, "Block")
|
|
|
while (list_len(all_blocks) > 0):
|
|
@@ -93,15 +80,12 @@ Element function sanitize(new_runtime_model : Element, old_runtime_model : Eleme
|
|
|
|
|
|
if (dict_in(old_runtime_model["model"], "time")):
|
|
|
current_time = read_attribute(old_runtime_model, "time", "current_time")
|
|
|
- termination_time = read_attribute(old_runtime_model, "time", "termination_time")
|
|
|
else:
|
|
|
current_time = 0
|
|
|
- termination_time = 10
|
|
|
|
|
|
time = instantiate_node(new_runtime_model, "Time", "time")
|
|
|
instantiate_attribute(new_runtime_model, time, "start_time", current_time)
|
|
|
instantiate_attribute(new_runtime_model, time, "current_time", current_time)
|
|
|
- instantiate_attribute(new_runtime_model, time, "termination_time", termination_time)
|
|
|
|
|
|
return new_runtime_model!
|
|
|
|
|
@@ -158,31 +142,6 @@ Element function create_schedule(model : Element, start_time : Integer):
|
|
|
String function readType(model : Element, name : String):
|
|
|
return reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][name]))!
|
|
|
|
|
|
-Void function list_CBD(model : Element):
|
|
|
- Element all_elements
|
|
|
- String elem
|
|
|
- String block
|
|
|
-
|
|
|
- output("Blocks:")
|
|
|
- all_elements = allInstances(model, "Block")
|
|
|
- while (read_nr_out(all_elements) > 0):
|
|
|
- elem = set_pop(all_elements)
|
|
|
- output(((" " + elem) + ": ") + readType(model, elem))
|
|
|
-
|
|
|
- output("Links:")
|
|
|
- all_elements = allInstances(model, "Link")
|
|
|
- while (read_nr_out(all_elements) > 0):
|
|
|
- elem = set_pop(all_elements)
|
|
|
- output(((" " + reverseKeyLookup(model["model"], read_edge_src(model["model"][elem]))) + " --> ") + reverseKeyLookup(model["model"], read_edge_dst(model["model"][elem])))
|
|
|
-
|
|
|
- output("Initial conditions:")
|
|
|
- all_elements = allInstances(model, "InitialCondition")
|
|
|
- while (read_nr_out(all_elements) > 0):
|
|
|
- elem = set_pop(all_elements)
|
|
|
- output(((" " + reverseKeyLookup(model["model"], read_edge_src(model["model"][elem]))) + " --> ") + reverseKeyLookup(model["model"], read_edge_dst(model["model"][elem])))
|
|
|
-
|
|
|
- return !
|
|
|
-
|
|
|
Void function step_simulation(model : Element, schedule : Element):
|
|
|
String time
|
|
|
Float signal
|
|
@@ -264,11 +223,6 @@ Void function step_simulation(model : Element, schedule : Element):
|
|
|
|
|
|
return !
|
|
|
|
|
|
-Void function set_termination_time(model : Element):
|
|
|
- unset_attribute(model, "time", "termination_time")
|
|
|
- instantiate_attribute(model, "time", "termination_time", input())
|
|
|
- return !
|
|
|
-
|
|
|
Void function execute_cbd(design_model : Element):
|
|
|
String verify_result
|
|
|
Element runtime_model
|
|
@@ -278,88 +232,93 @@ Void function execute_cbd(design_model : Element):
|
|
|
Element schedule_init
|
|
|
Element schedule_run
|
|
|
Element schedule
|
|
|
+ Boolean conforming
|
|
|
|
|
|
old_runtime_model = instantiate_model(import_node("models/CausalBlockDiagrams_Runtime"))
|
|
|
runtime_model = retype_to_runtime(design_model)
|
|
|
runtime_model = sanitize(runtime_model, old_runtime_model)
|
|
|
running = False
|
|
|
+ conforming = string_eq(conformance_scd(design_model), "OK")
|
|
|
|
|
|
schedule_init = create_schedule(runtime_model, read_attribute(runtime_model, "time", "start_time"))
|
|
|
schedule_run = create_schedule(runtime_model, -1)
|
|
|
|
|
|
while (True):
|
|
|
+ // If we are running, we just don't block for input and automatically do a step if there is no input
|
|
|
if (running):
|
|
|
if (has_input()):
|
|
|
cmd = input()
|
|
|
else:
|
|
|
cmd = "step"
|
|
|
else:
|
|
|
- output("Which operation do you want to execute?")
|
|
|
cmd = input()
|
|
|
|
|
|
- if (cmd == "help"):
|
|
|
- output("Supported operations:")
|
|
|
- if (bool_not(running)):
|
|
|
- output(" step -- do one simulation step")
|
|
|
- output(" start -- start simulation")
|
|
|
- output(" modify -- live modelling: modify model structure")
|
|
|
- output(" list -- list blocks and connections")
|
|
|
- output(" exit -- select another model")
|
|
|
- output(" verify -- verify the runtime model")
|
|
|
- else:
|
|
|
- output(" pause -- pause simulation")
|
|
|
- output(" help -- this information")
|
|
|
- output(" term -- set termination time")
|
|
|
- elif (cmd == "step"):
|
|
|
- // Do a simulation step
|
|
|
- if (read_attribute(runtime_model, "time", "start_time") == read_attribute(runtime_model, "time", "current_time")):
|
|
|
- schedule = schedule_init
|
|
|
- else:
|
|
|
- schedule = schedule_run
|
|
|
- step_simulation(runtime_model, schedule)
|
|
|
- elif (cmd == "term"):
|
|
|
- set_termination_time(runtime_model)
|
|
|
- elif (running):
|
|
|
- if (cmd == "pause"):
|
|
|
- running = False
|
|
|
- else:
|
|
|
- output("Did not understand command!")
|
|
|
- output("Use 'help' for a list of available options")
|
|
|
- else:
|
|
|
- // Not running
|
|
|
- if (cmd == "list"):
|
|
|
- list_CBD(runtime_model)
|
|
|
- elif (cmd == "start"):
|
|
|
+ // Process input
|
|
|
+ if (cmd == "simulate"):
|
|
|
+ // Simulation should toggle running to True, but only if the model is conforming
|
|
|
+ if (conforming):
|
|
|
running = True
|
|
|
- elif (cmd == "exit"):
|
|
|
- return!
|
|
|
- elif (cmd == "modify"):
|
|
|
- verify_result = "init"
|
|
|
- while (verify_result != "OK"):
|
|
|
- modify(design_model)
|
|
|
- verify_result = conformance_scd(design_model)
|
|
|
- if (verify_result != "OK"):
|
|
|
- output("Error in design model: " + verify_result)
|
|
|
- output("Successfully made modifications to design model!")
|
|
|
|
|
|
- old_runtime_model = runtime_model
|
|
|
- log("Retype")
|
|
|
+ elif (cmd == "step"):
|
|
|
+ // Stepping should make a single step, but first need to pick the correct schedule to use
|
|
|
+ if (conforming):
|
|
|
+ if (read_attribute(runtime_model, "time", "start_time") == read_attribute(runtime_model, "time", "current_time")):
|
|
|
+ schedule = schedule_init
|
|
|
+ else:
|
|
|
+ schedule = schedule_run
|
|
|
+ step_simulation(runtime_model, schedule)
|
|
|
+
|
|
|
+ elif (cmd == "pause"):
|
|
|
+ // Pausing merely stops a running simulation
|
|
|
+ running = False
|
|
|
+
|
|
|
+ elif (cmd == "read_available_attributes"):
|
|
|
+ // Returns a list of all available attributes
|
|
|
+ Element attr_list
|
|
|
+ attr_list = dict_keys(getAttributeList(model, cmd))
|
|
|
+ while (0 < read_nr_out(attr_list)):
|
|
|
+ output(set_pop(attr_list))
|
|
|
+
|
|
|
+ elif (cmd == "read_attribute"):
|
|
|
+ // Returns the value of an attribute
|
|
|
+ output(read_attribute(runtime_model, input(), input()))
|
|
|
+
|
|
|
+ elif (cmd == "modify"):
|
|
|
+ // Modify the structure
|
|
|
+ cmd = input()
|
|
|
+ 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 (boolean_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, input(), input(), 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())
|
|
|
+
|
|
|
+ // After changes, we check whether or not the design model conforms
|
|
|
+ conforming = string_eq(conformance_scd(design_model), "OK")
|
|
|
+ if (conforming):
|
|
|
+ // Conforming, so do the retyping and sanitization step
|
|
|
runtime_model = retype_to_runtime(design_model)
|
|
|
- log("Sanitize")
|
|
|
runtime_model = sanitize(runtime_model, old_runtime_model)
|
|
|
- log("Recreate schedules")
|
|
|
schedule_init = create_schedule(runtime_model, read_attribute(runtime_model, "time", "start_time"))
|
|
|
schedule_run = create_schedule(runtime_model, -1)
|
|
|
- log("All done!")
|
|
|
- elif (cmd == "verify"):
|
|
|
- verify_result = conformance_scd(runtime_model)
|
|
|
- if (verify_result != "OK"):
|
|
|
- output("Error in runtime model: " + verify_result)
|
|
|
- else:
|
|
|
- output("Runtime model OK!")
|
|
|
+ old_runtime_model = runtime_model
|
|
|
else:
|
|
|
- output("Did not understand command!")
|
|
|
- output("Use 'help' for a list of available options")
|
|
|
-
|
|
|
- if (cast_s2i(cast_v2s(read_attribute(runtime_model, "time", "current_time"))) > cast_s2i(cast_v2s(read_attribute(runtime_model, "time", "termination_time")))):
|
|
|
- running = False
|
|
|
+ // Not conforming, so stop simulation and block for input (preferably a modify to make everything consistent again)
|
|
|
+ running = False
|
|
|
+ else:
|
|
|
+ log("Did not understand command: " + cmd)
|