Przeglądaj źródła

Updated CBD semantics to more closely match the UI

Yentl Van Tendeloo 8 lat temu
rodzic
commit
262cf75ab9

+ 0 - 6
integration/code/cbd_runtime.mvc

@@ -59,12 +59,6 @@ SCD CausalBlockDiagrams_Runtime{
             target_upper_cardinality = 1
         }
 
-        termination_time : Natural {
-            target_lower_cardinality = 1
-            target_upper_cardinality = 1
-        }
-    }
-
     Association Link(Block, Block){
     }
     Association InitialCondition(Block, DelayBlock){

+ 69 - 110
integration/code/cbd_semantics.alc

@@ -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)

+ 1 - 4
interface/CBD/main.py

@@ -266,12 +266,11 @@ canvas.bind("<Button-3>", draw)
 canvas.bind("<ButtonRelease-3>", release)
 
 visual = Toplevel(root)
-# TODO: https://pythonprogramming.net/how-to-embed-matplotlib-graph-tkinter-gui/
 
 probes = {}
 values = {}
 
-simulation = [(1, {"a": 1, "b": 2}), (2, {"a": 3}), (3, {"a": 4, "b": 6})]
+#simulation = [(1, {"a": 1, "b": 2}), (2, {"a": 3}), (3, {"a": 4, "b": 6})]
 
 def update_graphs():
     while simulation:
@@ -298,7 +297,5 @@ def update_graphs():
             a.plot(values[k][0], values[k][1], linestyle="none", marker="o")
             fcanvas.draw()
     root.after(50, update_graphs)
-
 root.after(50, update_graphs)
-
 root.mainloop()