Pārlūkot izejas kodu

Make upload not crash

Yentl Van Tendeloo 7 gadi atpakaļ
vecāks
revīzija
59e789a98c

+ 54 - 0
models/ctcbd_spring.mvc

@@ -0,0 +1,54 @@
+ConstantBlock cte_k {
+    value = 1
+}
+
+ConstantBlock cte_g {
+    value = 10
+}
+
+ConstantBlock cte_m {
+    value = 1
+}
+
+ConstantBlock cte_v0 {
+    value = 1
+}
+
+ConstantBlock cte_y0 {
+    value = 20
+}
+
+MultiplyBlock m0 {}
+MultiplyBlock m1 {}
+MultiplyBlock m2 {}
+NegatorBlock n0 {}
+InverseBlock i0 {}
+AdditionBlock a0 {}
+IntegratorBlock int0 {}
+IntegratorBlock int1 {}
+
+ProbeBlock pv {
+    name = "velocity"
+}
+ProbeBlock py {
+    name = "displacement"
+}
+
+Link (cte_k, m0) {}
+Link (int1, m0) {}
+Link (cte_g, m1) {}
+Link (cte_m, m1) {}
+Link (cte_m, i0) {}
+Link (m0, n0) {}
+Link (n0, a0) {}
+Link (m1, a0) {}
+Link (i0, m2) {}
+Link (a0, m2) {}
+Link (m2, int0) {}
+Link (int0, int1) {}
+
+InitialCondition (cte_v0, int0) {}
+InitialCondition (cte_y0, int1) {}
+
+Link (int0, pv) {}
+Link (int1, py) {}

+ 19 - 7
models/ctcbd_toPartialRuntime.mvc

@@ -49,7 +49,7 @@ Composite schedule {
                                 return 0.01!
                         $
             }
-            Post_Design/MultiplicationBlock expand_rhs_8 {
+            Post_Design/MultiplyBlock expand_rhs_8 {
                 label = "8"
             }
             Post_Design/AdditionBlock expand_rhs_9 {
@@ -103,7 +103,7 @@ Composite schedule {
             Pre_Design/ConstantBlock opt_inv_lhs_0 {
                 label = "0"
             }
-            Pre_Design/InvertorBlock opt_inv_lhs_1 {
+            Pre_Design/InverseBlock opt_inv_lhs_1 {
                 label = "1"
             }
             Pre_Design/Block opt_inv_lhs_2 {
@@ -120,7 +120,7 @@ Composite schedule {
             Post_Design/ConstantBlock opt_inv_rhs_0 {
                 label = "0"
             }
-            Post_Design/InvertorBlock opt_inv_rhs_1 {
+            Post_Design/InverseBlock opt_inv_rhs_1 {
                 label = "1"
             }
             Post_Design/Block opt_inv_rhs_2 {
@@ -147,7 +147,7 @@ Composite schedule {
             Pre_Design/ConstantBlock opt_neg_lhs_0 {
                 label = "0"
             }
-            Pre_Design/InvertorBlock opt_neg_lhs_1 {
+            Pre_Design/InverseBlock opt_neg_lhs_1 {
                 label = "1"
             }
             Pre_Design/Block opt_neg_lhs_2 {
@@ -164,7 +164,7 @@ Composite schedule {
             Post_Design/ConstantBlock opt_neg_rhs_0 {
                 label = "0"
             }
-            Post_Design/InvertorBlock opt_neg_rhs_1 {
+            Post_Design/InverseBlock opt_neg_rhs_1 {
                 label = "1"
             }
             Post_Design/Block opt_neg_rhs_2 {
@@ -270,7 +270,7 @@ Composite schedule {
             Pre_Design/ConstantBlock opt_mult_lhs_1 {
                 label = "1"
             }
-            Pre_Design/MultiplicationBlock opt_mult_lhs_2 {
+            Pre_Design/MultiplyBlock opt_mult_lhs_2 {
                 label = "2"
             }
             Pre_Design/Block opt_mult_lhs_3 {
@@ -293,7 +293,7 @@ Composite schedule {
             Post_Design/ConstantBlock opt_mult_rhs_1 {
                 label = "1"
             }
-            Post_Design/MultiplicationBlock opt_mult_rhs_2 {
+            Post_Design/MultiplyBlock opt_mult_rhs_2 {
                 label = "2"
             }
             Post_Design/Block opt_mult_rhs_3 {
@@ -422,6 +422,18 @@ Composite schedule {
                                 instantiate_link(model, "PartialRuntime/InitialCondition", "", map_D2P(model, readAssociationSource(model, element_name)), map_D2P(model, readAssociationDestination(model, element_name)))
 
                             return!
+
+                        String function map_D2P(model : Element, name : String):
+                            Element destinations
+                            String pick
+
+                            destinations = allAssociationDestinations(model, name, "D2P_block")
+
+                            pick = name
+                            while (pick == name):
+                                pick = set_pop(destinations)
+
+                            return pick!
                      $
         }
     }

+ 59 - 0
models/dtcbd_merge.alc

@@ -0,0 +1,59 @@
+include "primitives.alh"
+include "modelling.alh"
+include "object_operations.alh"
+include "conformance_scd.alh"
+include "utils.alh"
+include "typing.alh"
+include "mini_modify.alh"
+
+String function map_P2F(model : Element, name : String):
+	Element destinations
+	String pick
+
+	destinations = allAssociationDestinations(model, name, "P2F_block")
+
+	pick = name
+	while (pick == name):
+		pick = set_pop(destinations)
+
+	return pick!
+
+Boolean function main(model : Element):
+	Element all_blocks
+	String element_name
+	Float current_time
+	String time_block
+
+	all_blocks = allInstances(model, "PartialRuntime/Block")
+	while (set_len(all_blocks) > 0):
+		element_name = set_pop(all_blocks)
+		if (set_len(allOutgoingAssociationInstances(model, element_name, "P2F_block")) > 0):
+			// Element already exists in full, so copy existing attributes
+            if (is_nominal_instance(model, element_name, "PartialRuntime/ICBlock")):
+                instantiate_attribute(model, element_name, "last_in", read_attribute(model, map_P2F(model, element_name), "last_in"))
+            // instantiate_attribute(model, element_name, "signal", read_attribute(model, map_P2F(model, element_name), "signal"))
+		else:
+			// Element doesn't exist, so initialize with 0.0
+            instantiate_attribute(model, element_name, "signal", 0.0)
+			instantiate_link(model, "P2F_block", "", element_name, element_name)
+
+	if (set_len(allInstances(model, "FullRuntime/Time")) > 0):
+		// Time already exists, so copy the value
+		current_time = read_attribute(model, set_pop(allInstances(model, "FullRuntime/Time")), "current_time")
+	else:
+		// No time yet, so initialize
+		current_time = 0.0
+
+	time_block = instantiate_node(model, "PartialRuntime/Time", "")
+	instantiate_attribute(model, time_block, "start_time", current_time)
+	instantiate_attribute(model, time_block, "current_time", current_time)
+
+	Element all_elements
+	String elem
+	all_elements = dict_keys(model["model"])
+	while (set_len(all_elements) > 0):
+		elem = set_pop(all_elements)
+		if (string_startswith(read_type(model, elem), "PartialRuntime/")):
+			retype(model, elem, "NewFullRuntime/" + cast_string(list_read(string_split_nr(read_type(model, elem), "/", 1), 1)))
+
+	return True!

+ 76 - 0
models/dtcbd_runtime.mvc

@@ -0,0 +1,76 @@
+include "primitives.alh"
+
+Class Float {}
+Class String {}
+
+Class Block{
+    signal : Float {
+        target_lower_cardinality = 1
+        target_upper_cardinality = 1
+    }
+}
+Class ICBlock{
+    last_in : Float {
+        target_lower_cardinality = 0
+        target_upper_cardinality = 1
+    }
+}
+
+Class ConstantBlock{
+    value : Float {
+        target_lower_cardinality = 1
+        target_upper_cardinality = 1
+    }
+}
+
+Class ProbeBlock{
+    name : String {
+        target_lower_cardinality = 1
+        target_upper_cardinality = 1
+    }
+}
+
+Class AdditionBlock{}
+Class NegatorBlock{}
+Class MultiplyBlock{}
+Class InverseBlock{}
+Class DelayBlock{}
+Class IntegratorBlock{
+    last_out : Float {
+        target_lower_cardinality = 0
+        target_upper_cardinality = 1
+    }
+}
+
+Class DerivatorBlock{}
+Class Time{
+    lower_cardinality = 1
+    upper_cardinality = 1
+
+    start_time : Float {
+        target_lower_cardinality = 1
+        target_upper_cardinality = 1
+    }
+
+    current_time : Float {
+        target_lower_cardinality = 1
+        target_upper_cardinality = 1
+    }
+}
+
+Association Link(Block, Block){}
+Association InitialCondition(Block, ICBlock){
+    source_lower_cardinality = 0
+    source_upper_cardinality = 1
+}
+
+Inheritance (ConstantBlock, Block){}
+Inheritance (AdditionBlock, Block){}
+Inheritance (NegatorBlock, Block){}
+Inheritance (MultiplyBlock, Block){}
+Inheritance (InverseBlock, Block){}
+Inheritance (ICBlock, Block){}
+Inheritance (DelayBlock, ICBlock){}
+Inheritance (DerivatorBlock, ICBlock){}
+Inheritance (IntegratorBlock, ICBlock){}
+Inheritance (ProbeBlock, Block){}

models/cbd_simple.mvc → models/dtcbd_simple.mvc


+ 467 - 0
models/dtcbd_simulate.alc

@@ -0,0 +1,467 @@
+include "primitives.alh"
+include "modelling.alh"
+include "object_operations.alh"
+include "conformance_scd.alh"
+include "io.alh"
+include "metamodels.alh"
+include "mini_modify.alh"
+
+Boolean function main(model : Element):
+	String cmd
+	Boolean running
+	Element schedule_init
+	Element schedule_run
+	Element schedule
+	Float current_time
+
+	String time
+	time = set_pop(allInstances(model, "FullRuntime/Time"))
+	current_time = read_attribute(model, time, "current_time")
+
+	schedule_init = create_schedule(model)
+	schedule_run = read_root()
+
+	Element nodes
+	Element inputs
+	String node
+	nodes = allInstances(model, "FullRuntime/Block")
+	inputs = dict_create()
+	while (set_len(nodes) > 0):
+		node = set_pop(nodes)
+		dict_add(inputs, node, allAssociationOrigins(model, node, "FullRuntime/Link"))
+
+	while (bool_not(has_input())):
+		if (read_attribute(model, time, "start_time") == read_attribute(model, time, "current_time")):
+			schedule = schedule_init
+		else:
+			if (element_eq(schedule_run, read_root())):
+				schedule_run = create_schedule(model)
+			schedule = schedule_run
+		current_time = step_simulation(model, schedule, current_time, inputs)
+
+	instantiate_attribute(model, time, "current_time", current_time)
+	output("CLOSE")
+	return True!
+
+Element function create_schedule(model : Element):
+	// Create nice graph first
+	Element nodes
+	Element successors
+	Element predecessors
+	String element_name
+	Element incoming_links
+	Element all_blocks
+
+	nodes = allInstances(model, "FullRuntime/Block")
+	successors = dict_create()
+	predecessors = dict_create()
+	while (set_len(nodes) > 0):
+		element_name = set_pop(nodes)
+		if (bool_not(dict_in(successors, element_name))):
+			dict_add(successors, element_name, create_node())
+		if (bool_not(dict_in(predecessors, element_name))):
+			dict_add(predecessors, element_name, create_node())
+
+		if (is_nominal_instance(model, element_name, "FullRuntime/ICBlock")):
+			if (bool_not(is_physical_float(read_attribute(model, element_name, "last_in")))):
+				incoming_links = allIncomingAssociationInstances(model, element_name, "FullRuntime/InitialCondition")
+			else:
+				incoming_links = create_node()
+			if (is_nominal_instance(model, element_name, "FullRuntime/DerivatorBlock")):
+				Element new_incoming_links
+				new_incoming_links = allIncomingAssociationInstances(model, element_name, "FullRuntime/Link")
+				while (read_nr_out(new_incoming_links) > 0):
+					list_append(incoming_links, set_pop(new_incoming_links))
+		else:
+			incoming_links = allIncomingAssociationInstances(model, element_name, "FullRuntime/Link")
+
+		while (set_len(incoming_links) > 0):
+			String source
+			source = readAssociationSource(model, set_pop(incoming_links))
+			if (bool_not(dict_in(successors, source))):
+				dict_add(successors, source, create_node())
+			set_add(successors[source], element_name)
+			set_add(predecessors[element_name], source)
+	
+	Element values
+	values = create_node()
+	dict_add(values, "model", model)
+	dict_add(values, "S", create_node())
+	dict_add(values, "index", 0)
+	dict_add(values, "indices", create_node())
+	dict_add(values, "lowlink", create_node())
+	dict_add(values, "onStack", create_node())
+	dict_add(values, "successors", successors)
+	dict_add(values, "predecessors", predecessors)
+	dict_add(values, "SCC", create_node())
+
+	nodes = get_topolist(values)
+	while (list_len(nodes) > 0):
+		strongconnect(list_pop_final(nodes), values)
+
+	return values["SCC"]!
+
+Element function get_topolist(values : Element):
+	Element result
+	Element predecessors
+	Element remaining
+	String current_element
+	Element cur_predecessors
+
+	result = list_create()
+	predecessors = dict_copy(values["predecessors"])
+
+	while (dict_len(predecessors) > 0):
+		remaining = dict_keys(predecessors)
+		while (set_len(remaining) > 0):
+			current_element = set_pop(remaining)
+			cur_predecessors = predecessors[current_element]
+			if (set_len(set_overlap(list_to_set(result), cur_predecessors)) == set_len(cur_predecessors)):
+				// All predecessors of this node have already been visited
+				dict_delete(predecessors, current_element)
+				remaining = dict_keys(predecessors)
+				list_append(result, current_element)
+
+	return result!
+
+Integer function min(a : Integer, b : Integer):
+	if (a < b):
+		return a!
+	else:
+		return b!
+
+Void function strongconnect(v : String, values : Element):
+	if (dict_in(values["indices"], v)):
+		return!
+
+	dict_overwrite(values["indices"], v, values["index"])
+	dict_overwrite(values["lowlink"], v, values["index"])
+	dict_overwrite(values, "index", cast_integer(values["index"]) + 1)
+
+	list_append(values["S"], v)
+	dict_overwrite(values["onStack"], v, True)
+	
+	Element successors
+	String w
+	successors = values["successors"][v]
+	while (set_len(successors) > 0):
+		w = set_pop(successors)
+		if (bool_not(dict_in(values["indices"], w))):
+			strongconnect(w, values)
+			dict_overwrite(values["lowlink"], v, min(values["lowlink"][v], values["lowlink"][w]))
+		elif (dict_in(values["onStack"], w)):
+			if (values["onStack"][w]):
+				dict_overwrite(values["lowlink"], v, min(values["lowlink"][v], values["indices"][w]))
+	
+	if (value_eq(values["lowlink"][v], values["indices"][v])):
+		Element scc
+		scc = create_node()
+		// It will always differ now
+		w = list_pop_final(values["S"])
+		list_append(scc, w)
+		dict_overwrite(values["onStack"], w, False)
+		while (w != v):
+			w = list_pop_final(values["S"])
+			list_append(scc, w)
+			dict_overwrite(values["onStack"], w, False)
+		list_insert(values["SCC"], scc, 0)
+
+	return!
+
+Boolean function solve_scc(model : Element, scc : Element):
+	Element m
+	Integer i
+	Integer j
+	String block
+	String blocktype
+	Element incoming
+	String selected
+	Float constant
+	Element t
+
+	// Construct the matrix first, with as many rows as there are variables
+	// Number of columns is 1 higher
+	i = 0
+	m = create_node()
+	while (i < read_nr_out(scc)):
+		j = 0
+		t = create_node()
+		while (j < (read_nr_out(scc) + 1)):
+			list_append(t, 0.0)
+			j = j + 1
+		list_append(m, t)
+		i = i + 1
+
+	// Matrix initialized to 0.0
+	i = 0
+	while (i < read_nr_out(scc)):
+		// First element of scc
+		block = scc[i]
+		blocktype = read_type(model, block)
+
+		// First write 1 in the current block
+		dict_overwrite(m[i], i, 1.0)
+
+		// Now check all blocks that are incoming
+		if (blocktype == "FullRuntime/AdditionBlock"):
+			constant = 0.0
+		elif (blocktype == "FullRuntime/MultiplyBlock"):
+			constant = 1.0
+
+		incoming = allIncomingAssociationInstances(model, block, "Link")
+
+		Integer index_to_write_constant
+		index_to_write_constant = -1
+		while (read_nr_out(incoming) > 0):
+			selected = readAssociationSource(model, set_pop(incoming))
+
+			if (set_in(scc, selected)):
+				// Part of the loop, so in the index of selected in scc
+				// Five options:
+				if (blocktype == "FullRuntime/AdditionBlock"):
+					// 1) AdditionBlock
+					// Add the negative of this signal, which is as of yet unknown
+					// x = y + z --> x - y - z = 0
+					dict_overwrite(m[i], list_index_of(scc, selected), -1.0)
+				elif (blocktype == "FullRuntime/MultiplyBlock"):
+					// 2) MultiplyBlock
+					if (index_to_write_constant != -1):
+						return False!
+					index_to_write_constant = list_index_of(scc, selected)
+				elif (blocktype == "FullRuntime/NegatorBlock"):
+					// 3) NegatorBlock
+					// Add the positive of the signal, which is as of yet unknown
+					dict_overwrite(m[i], list_index_of(scc, selected), 1.0)
+				elif (blocktype == "FullRuntime/DelayBlock"):
+					// 5) DelayBlock
+					// Just copies a single value
+					dict_overwrite(m[i], list_index_of(scc, selected), -1.0)
+				else:
+					// Block that cannot be handled
+					return False!
+			else:
+				// A constant, which we can assume is already computed and thus usable
+				if (blocktype == "FullRuntime/AdditionBlock"):
+					constant = constant + cast_float(read_attribute(model, selected, "signal"))
+					dict_overwrite(m[i], read_nr_out(scc), constant)
+				elif (blocktype == "FullRuntime/MultiplyBlock"):
+					constant = constant * cast_float(read_attribute(model, selected, "signal"))
+					// Not written to constant part, as multiplies a variable
+
+				// Any other block is impossible:
+				// * Constant would never be part of a SCC
+				// * Delay would never get an incoming constant
+				// * Negation and Inverse only get 1 input, which is a variable in a loop
+				// * Integrator and Derivator never get an incoming constant
+
+		if (index_to_write_constant != -1):
+			dict_overwrite(m[i], index_to_write_constant, -constant)
+
+		i = i + 1
+
+	// Constructed a complete matrix, so we can start!
+	log(matrix2string(m))
+
+	// Solve matrix now
+	eliminateGaussJordan(m)
+
+	// Now go over m and set signals for each element
+	// Assume that everything worked out...
+	i = 0
+	while (i < read_nr_out(m)):
+		block = scc[i]
+		instantiate_attribute(model, block, "signal", m[i][read_nr_out(scc)])
+		log((("Solved " + block) + " to ") + cast_string(m[i][read_nr_out(scc)]))
+		i = i + 1
+
+	return True!
+
+Integer function list_index_of(lst : Element, elem : Element):
+	Integer i
+	i = 0
+	while (i < read_nr_out(lst)):
+		if (value_eq(list_read(lst, i), elem)):
+			return i!
+		else:
+			i = i + 1
+	return -1!
+
+Float function step_simulation(model : Element, schedule : Element, time : Float, inputs : Element):
+	Float signal
+	Element incoming
+	String selected
+	String block
+	String elem
+	String blocktype
+	Element memory_blocks
+	Integer i
+	Float delta_t
+	Element scc
+
+	delta_t = 0.1
+
+	memory_blocks = set_create()
+	i = 0
+	while (i < list_len(schedule)):
+		scc = list_read(schedule, i)
+		i = i + 1
+
+		if (list_len(scc) > 1):
+			if (bool_not(solve_scc(model, scc))):
+				output("ALGEBRAIC_LOOP")
+				return time!
+		else:
+			block = list_read(scc, 0)
+
+			// Execute "block"
+			blocktype = read_type(model, block)
+			incoming = set_copy(inputs[block])
+			if (blocktype == "FullRuntime/ConstantBlock"):
+				signal = read_attribute(model, block, "value")
+			elif (blocktype == "FullRuntime/AdditionBlock"):
+				signal = 0.0
+				while (set_len(incoming) > 0):
+					selected = set_pop(incoming)
+					signal = signal + cast_float(read_attribute(model, selected, "signal"))
+			elif (blocktype == "FullRuntime/MultiplyBlock"):
+				signal = 1.0
+				while (set_len(incoming) > 0):
+					selected = set_pop(incoming)
+					signal = signal * cast_float(read_attribute(model, selected, "signal"))
+			elif (blocktype == "FullRuntime/NegatorBlock"):
+				signal = 0.0
+				while (set_len(incoming) > 0):
+					selected = set_pop(incoming)
+					signal = float_neg(cast_float(read_attribute(model, selected, "signal")))
+			elif (blocktype == "FullRuntime/InverseBlock"):
+				signal = 0.0
+				while (set_len(incoming) > 0):
+					selected = set_pop(incoming)
+					signal = float_division(1.0, cast_float(read_attribute(model, selected, "signal")))
+			elif (blocktype == "FullRuntime/DelayBlock"):
+				signal = 0.0
+				if (bool_not(is_physical_float(read_attribute(model, block, "last_in")))):
+					// No memory yet, so use initial condition
+					incoming = allAssociationOrigins(model, block, "FullRuntime/InitialCondition")
+					while (set_len(incoming) > 0):
+						selected = set_pop(incoming)
+						signal = cast_float(read_attribute(model, selected, "signal"))
+				else:
+					signal = read_attribute(model, block, "last_in")
+				set_add(memory_blocks, block)
+			elif (blocktype == "FullRuntime/IntegratorBlock"):
+				if (bool_not(is_physical_float(read_attribute(model, block, "last_in")))):
+					// No history yet, so use initial values
+					incoming = allAssociationOrigins(model, block, "FullRuntime/InitialCondition")
+					while (set_len(incoming) > 0):
+						selected = set_pop(incoming)
+						signal = cast_float(read_attribute(model, selected, "signal"))
+				else:
+					signal = cast_float(read_attribute(model, block, "last_out")) + (delta_t * cast_float(read_attribute(model, block, "last_in")))
+				instantiate_attribute(model, block, "last_out", signal)
+				set_add(memory_blocks, block)
+			elif (blocktype == "FullRuntime/DerivatorBlock"):
+				if (bool_not(is_physical_float(read_attribute(model, block, "last_in")))):
+					// No history yet, so use initial values
+					incoming = allAssociationOrigins(model, block, "FullRuntime/InitialCondition")
+					while (set_len(incoming) > 0):
+						selected = set_pop(incoming)
+						signal = cast_float(read_attribute(model, selected, "signal"))
+				else:
+					while (set_len(incoming) > 0):
+						selected = set_pop(incoming)
+						signal = (cast_float(read_attribute(model, selected, "signal")) - cast_float(read_attribute(model, block, "last_in"))) / delta_t
+				set_add(memory_blocks, block)
+			elif (blocktype == "FullRuntime/ProbeBlock"):
+				while (set_len(incoming) > 0):
+					signal = cast_float(read_attribute(model, set_pop(incoming), "signal"))
+					output(cast_string(time) + " " + cast_string(read_attribute(model, block, "name")) + " " + cast_string(signal))
+
+			instantiate_attribute(model, block, "signal", signal)
+	
+	while (set_len(memory_blocks) > 0):
+		block = set_pop(memory_blocks)
+		// Update memory
+		incoming = set_copy(inputs[block])
+		while (set_len(incoming) > 0):
+			selected = set_pop(incoming)
+			instantiate_attribute(model, block, "last_in", cast_float(read_attribute(model, selected, "signal")))
+
+	// Increase simulation time
+	return time + delta_t!
+
+Void function eliminateGaussJordan(m : Element):
+	Integer i
+	Integer j
+	Integer f
+	Integer g
+	Boolean searching
+	Element t
+	Float divisor
+
+	i = 0
+	j = 0
+
+	while (i < read_nr_out(m)):
+		// Make sure pivot m[i][j] != 0, swapping if necessary
+		while (cast_float(m[i][j]) == 0.0):
+			// Is zero, so find row which is not zero
+			f = i + 1
+			searching = True
+			while (searching):
+				if (f >= read_nr_out(m)):
+					// No longer any rows left, so just increase column counter
+					searching = False
+					j = j + 1
+				else:
+					if (cast_float(m[f][j]) == 0.0):
+						// Also zero, so continue
+						f = f + 1
+					else:
+						// Found non-zero, so swap row
+						t = cast_float(m[f])
+						dict_overwrite(m, f, cast_float(m[i]))
+						dict_overwrite(m, i, t)
+						searching = False
+			// If we have increased j, we will just start the loop again (possibly), as m[i][j] might be zero again
+
+		// Pivot in m[i][j] guaranteed to not be 0
+		// Now divide complete row by value of m[i][j] to make it equal 1
+		f = j
+		divisor = cast_float(m[i][j])
+		while (f < read_nr_out(m[i])):
+			dict_overwrite(m[i], f, float_division(cast_float(m[i][f]), divisor))
+			f = f + 1
+
+		// Eliminate all rows in the j-th column, except the i-th row
+		f = 0
+		while (f < read_nr_out(m)):
+			if (bool_not(f == i)):
+				g = j
+				divisor = cast_float(m[f][j])
+				while (g < read_nr_out(m[f])):
+					dict_overwrite(m[f], g, cast_float(m[f][g]) - (divisor * cast_float(m[i][g])))
+					g = g + 1
+			f = f + 1
+
+		// Increase row and column
+		i = i + 1
+		j = j + 1
+
+	return !
+
+String function matrix2string(m : Element):
+	Integer i
+	Integer j
+	String result
+
+	result = ""
+	i = 0
+	while (i < read_nr_out(m)):
+		j = 0
+		while (j < read_nr_out(m[i])):
+			result = result + cast_string(m[i][j]) + ", "
+			j = j + 1
+		i = i + 1
+		result = result + "\n"
+	return result!

+ 69 - 0
models/dtcbd_toRuntime.alc

@@ -0,0 +1,69 @@
+include "primitives.alh"
+include "modelling.alh"
+include "object_operations.alh"
+
+String function map_D2P(model : Element, name : String):
+	Element destinations
+	String pick
+
+	destinations = allAssociationDestinations(model, name, "D2P_block")
+
+	pick = name
+	while (pick == name):
+		pick = set_pop(destinations)
+
+	return pick!
+
+Boolean function main(model : Element):
+	Element all_blocks
+	String element_name
+	String new_element_name
+	String mm_type_name
+	Element all_links
+
+	all_blocks = allInstances(model, "Design/Block")
+	while (set_len(all_blocks) > 0):
+		element_name = set_pop(all_blocks)
+		mm_type_name = "PartialRuntime/" + cast_string(list_read(string_split(read_type(model, element_name), "/"), 1))
+
+		if (set_len(allOutgoingAssociationInstances(model, element_name, "D2P_block")) == 0):
+			// New design element, so create in partial runtime model as well
+			new_element_name = instantiate_node(model, mm_type_name, "")
+			instantiate_link(model, "D2P_block", "", element_name, new_element_name)
+
+		// Always update the value of attributes of PartialRuntime
+		new_element_name = map_D2P(model, element_name)
+		if (mm_type_name == "PartialRuntime/ConstantBlock"):
+            instantiate_attribute(model, new_element_name, "value", read_attribute(model, element_name, "value"))
+		elif (mm_type_name == "PartialRuntime/ProbeBlock"):
+            instantiate_attribute(model, new_element_name, "name", read_attribute(model, element_name, "name"))
+
+	all_blocks = allInstances(model, "PartialRuntime/Block")
+	while (set_len(all_blocks) > 0):
+		element_name = set_pop(all_blocks)
+		if (set_len(allIncomingAssociationInstances(model, element_name, "D2P_block")) == 0):
+			// Old partial runtime element, so remove
+			model_delete_element(model, element_name)
+
+	// Delete all existing links
+	all_links = allInstances(model, "PartialRuntime/Link")
+	while (set_len(all_links) > 0):
+		model_delete_element(model, set_pop(all_links))
+
+	all_links = allInstances(model, "PartialRuntime/InitialCondition")
+	while (set_len(all_links) > 0):
+		model_delete_element(model, set_pop(all_links))
+
+	// Recreate all of them
+    all_links = allInstances(model, "Design/Link")
+    while (set_len(all_links) > 0):
+        element_name = set_pop(all_links)
+        instantiate_link(model, "PartialRuntime/Link", "", map_D2P(model, readAssociationSource(model, element_name)), map_D2P(model, readAssociationDestination(model, element_name)))
+
+    all_links = allInstances(model, "Design/InitialCondition")
+    while (set_len(all_links) > 0):
+        element_name = set_pop(all_links)
+        instantiate_link(model, "PartialRuntime/InitialCondition", "", map_D2P(model, readAssociationSource(model, element_name)), map_D2P(model, readAssociationDestination(model, element_name)))
+
+
+	return True!

+ 3 - 3
models/fsa_merge.alc

@@ -47,14 +47,14 @@ Boolean function main(model : Element):
 
 	String new_state
 	if (found_current == False):
-		if (True):
+		if (False):
 			// Prompt for new state
 			output("FIX_NEW_STATE")
 			new_state = input()
 			all_states = allInstances(model, "PartialRuntime/State")
 			while (set_len(all_states) > 0):
 				element_name = set_pop(all_states)
-				if (value_eq(read_attribute(model, element_name, "name"), new_state):
+				if (value_eq(read_attribute(model, element_name, "name"), new_state)):
 					instantiate_attribute(model, element_name, "current", True)
 					break!
 		else:
@@ -62,7 +62,7 @@ Boolean function main(model : Element):
 			all_states = allInstances(model, "PartialRuntime/State")
 			while (set_len(all_states) > 0):
 				element_name = set_pop(all_states)
-				if (value_eq(read_attribute(model, element_name, "initial"), True):
+				if (value_eq(read_attribute(model, element_name, "initial"), True)):
 					instantiate_attribute(model, element_name, "current", True)
 					break!
 	return True!

+ 79 - 0
models/live_modelling.py

@@ -0,0 +1,79 @@
+import sys
+sys.path.append("wrappers")
+from modelverse import *
+
+init()
+login("admin", "admin")
+
+### live modelling DTCBD
+
+model_add("formalisms/DTCBD/Design_MM", "formalisms/SimpleClassDiagrams", open("models/dtcbd_design.mvc", 'r').read())
+model_add("formalisms/DTCBD/PartialRuntime_MM", "formalisms/SimpleClassDiagrams", open("models/dtcbd_partial_runtime.mvc", 'r').read())
+model_add("formalisms/DTCBD/FullRuntime_MM", "formalisms/SimpleClassDiagrams", open("models/dtcbd_runtime.mvc", 'r').read())
+
+model_add("models/DTCBD_model", "formalisms/DTCBD/Design_MM", open("models/dtcbd_simple.mvc", 'r').read())
+
+transformation_add_MANUAL({"Design": "formalisms/DTCBD/Design_MM"}, {"Design": "formalisms/DTCBD/Design_MM"}, "models/DTCBD/edit")
+
+def trace_D2P(model):
+    instantiate(model, "Association", ("Design/Block", "PartialRuntime/Block"), ID="D2P_block")
+
+transformation_add_AL({"Design": "formalisms/DTCBD/Design_MM", "PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM"}, {"PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM"}, "models/DTCBD/toRuntime", open("models/dtcbd_toRuntime.alc", 'r').read(), trace_D2P)
+
+def trace_P2F(model):
+    instantiate(model, "Association", ("PartialRuntime/Block", "FullRuntime/Block"), ID="P2F_block")
+
+transformation_add_AL({"PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM", "FullRuntime": "formalisms/DTCBD/FullRuntime_MM"}, {"NewFullRuntime": "formalisms/DTCBD/FullRuntime_MM"}, "models/DTCBD/merge", open("models/dtcbd_merge.alc", 'r').read(), trace_P2F)
+transformation_add_AL({"FullRuntime": "formalisms/DTCBD/FullRuntime_MM"}, {"FullRuntime": "formalisms/DTCBD/FullRuntime_MM"}, "models/DTCBD/simulate", open("models/dtcbd_simulate.alc", 'r').read())
+transformation_add_AL({}, {}, "models/DTCBD/restartSim", open("models/cbd_restartSim.alc", 'r').read())
+
+model_add("models/live_modelling_DTCBD", "formalisms/ProcessModel", open("models/pm_live_DTCBD.mvc", 'r').read())
+
+### live modelling CTCBD
+
+model_add("formalisms/CTCBD/Design_MM", "formalisms/SimpleClassDiagrams", open("models/ctcbd_design.mvc", 'r').read())
+#model_add("formalisms/DTCBD/PartialRuntime_MM", "formalisms/SimpleClassDiagrams", open("models/dtcbd_partial_runtime.mvc", 'r').read())
+#model_add("formalisms/DTCBD/FullRuntime_MM", "formalisms/SimpleClassDiagrams", open("models/dtcbd_runtime.mvc", 'r').read())
+
+model_add("models/CTCBD_model", "formalisms/CTCBD/Design_MM", open("models/ctcbd_spring.mvc", 'r').read())
+
+transformation_add_MANUAL({"Design": "formalisms/CTCBD/Design_MM"}, {"Design": "formalisms/CTCBD/Design_MM"}, "models/CTCBD/edit")
+
+def trace_D2P(model):
+    instantiate(model, "Association", ("Design/Block", "PartialRuntime/Block"), ID="D2P_block")
+
+transformation_add_MT({"Design": "formalisms/CTCBD/Design_MM", "PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM"}, {"PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM"}, "models/CTCBD/toRuntime", open("models/ctcbd_toPartialRuntime.mvc", 'r').read(), trace_D2P)
+
+#def trace_P2F(model):
+#    instantiate(model, "Association", ("PartialRuntime/Block", "FullRuntime/Block"), ID="P2F_block")
+#
+#transformation_add_AL({"PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM", "FullRuntime": "formalisms/DTCBD/FullRuntime_MM"}, {"NewFullRuntime": "formalisms/DTCBD/FullRuntime_MM"}, "models/DTCBD/merge", open("models/dtcbd_merge.alc", 'r').read(), trace_P2F)
+#transformation_add_AL({"FullRuntime": "formalisms/DTCBD/FullRuntime_MM"}, {"FullRuntime": "formalisms/DTCBD/FullRuntime_MM"}, "models/DTCBD/simulate", open("models/dtcbd_simulate.alc", 'r').read())
+#transformation_add_AL({}, {}, "models/DTCBD/restartSim", open("models/cbd_restartSim.alc", 'r').read())
+
+model_add("models/live_modelling_CTCBD", "formalisms/ProcessModel", open("models/pm_live_CTCBD.mvc", 'r').read())
+
+### live modelling FSA
+
+model_add("formalisms/FSA/Design_MM", "formalisms/SimpleClassDiagrams", open("models/fsa_design.mvc", 'r').read())
+model_add("formalisms/FSA/PartialRuntime_MM", "formalisms/SimpleClassDiagrams", open("models/fsa_partial_runtime.mvc", 'r').read())
+model_add("formalisms/FSA/FullRuntime_MM", "formalisms/SimpleClassDiagrams", open("models/fsa_full_runtime.mvc", 'r').read())
+
+model_add("models/FSA_model", "formalisms/FSA/Design_MM", open("models/fsa_model.mvc", 'r').read())
+
+transformation_add_MANUAL({"Design": "formalisms/FSA/Design_MM"}, {"Design": "formalisms/FSA/Design_MM"}, "models/FSA/edit")
+
+def trace_D2P(model):
+    instantiate(model, "Association", ("Design/State", "PartialRuntime/State"), ID="D2P_state")
+
+transformation_add_AL({"Design": "formalisms/FSA/Design_MM", "PartialRuntime": "formalisms/FSA/PartialRuntime_MM"}, {"PartialRuntime": "formalisms/FSA/PartialRuntime_MM"}, "models/FSA/toRuntime", open("models/fsa_toRuntime.alc", 'r').read(), trace_D2P)
+
+def trace_P2F(model):
+    instantiate(model, "Association", ("PartialRuntime/State", "FullRuntime/State"), ID="P2F_state")
+
+transformation_add_AL({"PartialRuntime": "formalisms/FSA/PartialRuntime_MM", "FullRuntime": "formalisms/FSA/FullRuntime_MM"}, {"NewFullRuntime": "formalisms/FSA/FullRuntime_MM"}, "models/FSA/merge", open("models/fsa_merge.alc", 'r').read(), trace_P2F)
+transformation_add_AL({"FullRuntime": "formalisms/FSA/FullRuntime_MM"}, {"FullRuntime": "formalisms/FSA/FullRuntime_MM"}, "models/FSA/simulate", open("models/cbd_simulate.alc", 'r').read())
+transformation_add_AL({}, {}, "models/FSA/restartSim", open("models/cbd_restartSim.alc", 'r').read())
+
+model_add("models/live_modelling_FSA", "formalisms/ProcessModel", open("models/pm_live_FSA.mvc", 'r').read())
+

+ 1 - 1
models/upload_models.py

@@ -14,7 +14,6 @@ def add_trace_trace(model):
     instantiate(model, "Association", ("abstract/Signal", "rendered/Dataset"), ID="TracabilityLink")
 
 transformation_add_MT({"abstract": "formalisms/Trace", "rendered": "formalisms/MM_render/plot"}, {"rendered": "formalisms/MM_render/plot"}, "models/trace_mapper", open("models/trace_mapper.mvc", 'r').read(), add_trace_trace)
-"""
 
 model_add("formalisms/MM_render/graphical", "formalisms/SimpleClassDiagrams", open("models/MM_render.mvc", 'r').read())
 
@@ -23,6 +22,7 @@ def scd_tracability(model):
     instantiate(model, "Association", ("abstract/Association", "rendered/ConnectingLine"), ID="TracabilityAssociation")
 
 transformation_add_AL({"rendered": "formalisms/MM_render/graphical", "abstract": "formalisms/SimpleClassDiagrams"}, {"rendered": "formalisms/MM_render/graphical"}, "models/render_SCD", open("models/render_SCD.alc", 'r').read(), callback=scd_tracability)
+"""
 
 model_add("formalisms/CBD/Design_MM", "formalisms/SimpleClassDiagrams", open("models/cbd_design.mvc", 'r').read())
 model_add("formalisms/CBD/PartialRuntime_MM", "formalisms/SimpleClassDiagrams", open("models/cbd_partial_runtime.mvc", 'r').read())