|
@@ -5,6 +5,7 @@ include "conformance_scd.alh"
|
|
|
include "io.alh"
|
|
|
include "metamodels.alh"
|
|
|
include "mini_modify.alh"
|
|
|
+include "utils.alh"
|
|
|
|
|
|
Boolean function main(model : Element):
|
|
|
log("Start DTCBD simulation!")
|
|
@@ -50,20 +51,15 @@ 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()
|
|
|
+ successors = set_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())
|
|
|
+ log("Block " + element_name + " : " + read_type(model, element_name))
|
|
|
|
|
|
if (is_nominal_instance(model, element_name, "FullRuntime/ICBlock")):
|
|
|
if (bool_not(is_physical_float(read_attribute(model, element_name, "last_in")))):
|
|
@@ -76,22 +72,27 @@ Element function create_schedule(model : Element):
|
|
|
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)
|
|
|
-
|
|
|
+ list_append(successors, create_tuple(source, element_name))
|
|
|
+ log("Found edge: " + source + " --> " + element_name)
|
|
|
+
|
|
|
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())
|
|
|
+ //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())
|
|
|
+
|
|
|
+ dict_add(values, "edges", successors)
|
|
|
+ dict_add(values, "nodes", allInstances(model, "FullRuntime/Block"))
|
|
|
+ dict_add(values, "dfsCounter", 0)
|
|
|
+ dict_add(values, "orderNumber", dict_create())
|
|
|
+ dict_add(values, "visited_topSort", set_create())
|
|
|
+ dict_add(values, "unvisited_strongComp", set_create())
|
|
|
|
|
|
log("Toposort")
|
|
|
//nodes = get_topolist(values)
|
|
@@ -99,14 +100,147 @@ Element function create_schedule(model : Element):
|
|
|
// log("Strong connect")
|
|
|
// strongconnect(list_pop_final(nodes), values)
|
|
|
|
|
|
- nodes = allInstances(model, "FullRuntime/Block")
|
|
|
- while (set_len(nodes) > 0):
|
|
|
- strongconnect(set_pop(nodes), values)
|
|
|
+ dict_overwrite(values, "SCC", strongComp(values))
|
|
|
+
|
|
|
+ //nodes = allInstances(model, "FullRuntime/Block")
|
|
|
+ //while (set_len(nodes) > 0):
|
|
|
+ // strongconnect(set_pop(nodes), values)
|
|
|
|
|
|
log("OK")
|
|
|
|
|
|
return values["SCC"]!
|
|
|
|
|
|
+Void function topSort(values : Element):
|
|
|
+ Element nodes_copy
|
|
|
+ String node
|
|
|
+
|
|
|
+ // for node in graph:
|
|
|
+ // node.visited = False
|
|
|
+ dict_overwrite(values, "visited_topSort", set_create())
|
|
|
+
|
|
|
+ // for node in graph:
|
|
|
+ // if not node.visited:
|
|
|
+ // dfsLabelling(node)
|
|
|
+ nodes_copy = set_copy(values["nodes"])
|
|
|
+ while (set_len(nodes_copy) > 0):
|
|
|
+ node = set_pop(nodes_copy)
|
|
|
+ if (bool_not(set_in(values["visited_topSort"], node))):
|
|
|
+ dfsLabelling(values, node)
|
|
|
+
|
|
|
+ return!
|
|
|
+
|
|
|
+Element function get_successors(values : Element, node : String, key : String):
|
|
|
+ Element edges
|
|
|
+ Element result
|
|
|
+ String edge
|
|
|
+
|
|
|
+ result = set_create()
|
|
|
+ edges = list_copy(values[key])
|
|
|
+ while (list_len(edges) > 0):
|
|
|
+ edge = list_pop_final(edges)
|
|
|
+ if (cast_string(edge[0]) == node):
|
|
|
+ set_add(result, edge[1])
|
|
|
+
|
|
|
+ return result!
|
|
|
+
|
|
|
+Void function dfsLabelling(values : Element, node : String):
|
|
|
+ Element successors
|
|
|
+ String successor
|
|
|
+
|
|
|
+ // if not node.visited
|
|
|
+ if (bool_not(set_in(values["visited_topSort"], node))):
|
|
|
+ // node.visited = True
|
|
|
+ set_add(values["visited_topSort"], node)
|
|
|
+
|
|
|
+ // for neighbour in node.out_neighbours:
|
|
|
+ // dfsLabelling(neighbour, graph)
|
|
|
+ successors = get_successors(values, node, "edges")
|
|
|
+ while (set_len(successors) > 0):
|
|
|
+ successor = set_pop(successors)
|
|
|
+ dfsLabelling(values, successor)
|
|
|
+
|
|
|
+ // node.orderNumber = dfsCounter
|
|
|
+ dict_overwrite(values["orderNumber"], node, values["dfsCounter"])
|
|
|
+
|
|
|
+ // dfsCounter += 1
|
|
|
+ dict_overwrite(values, "dfsCounter", cast_integer(values["dfsCounter"]) + 1)
|
|
|
+
|
|
|
+ return !
|
|
|
+
|
|
|
+Element function dfsCollect(values : Element, start_node : String):
|
|
|
+ Element result
|
|
|
+ String successor
|
|
|
+ Element successors
|
|
|
+
|
|
|
+ result = set_create()
|
|
|
+
|
|
|
+ // if not node.visited
|
|
|
+ if (set_in(values["unvisited_strongComp"], start_node)):
|
|
|
+ list_append(result, start_node)
|
|
|
+ // node.visited = True
|
|
|
+ set_remove(values["unvisited_strongComp"], start_node)
|
|
|
+
|
|
|
+ // for neighbour in node.out_neighbours:
|
|
|
+ // dfsLabelling(neighbour, graph)
|
|
|
+ successors = get_successors(values, start_node, "rev_edges")
|
|
|
+ while (set_len(successors) > 0):
|
|
|
+ successor = set_pop(successors)
|
|
|
+ list_extend(result, dfsCollect(values, successor))
|
|
|
+
|
|
|
+ return result!
|
|
|
+
|
|
|
+String function highest_orderNumber(values : Element):
|
|
|
+ Integer max
|
|
|
+ String max_element
|
|
|
+ Element search
|
|
|
+ String elem
|
|
|
+
|
|
|
+ max = -1
|
|
|
+ search = set_copy(values["unvisited_strongComp"])
|
|
|
+ while (set_len(search) > 0):
|
|
|
+ elem = set_pop(search)
|
|
|
+ if (cast_integer(values["orderNumber"][elem]) > max):
|
|
|
+ max = values["orderNumber"][elem]
|
|
|
+ max_element = elem
|
|
|
+
|
|
|
+ return max_element!
|
|
|
+
|
|
|
+Element function reverse_edges(edges : Element):
|
|
|
+ Element result
|
|
|
+ Element elem
|
|
|
+
|
|
|
+ result = list_create()
|
|
|
+ edges = list_copy(edges)
|
|
|
+ while (list_len(edges) > 0):
|
|
|
+ elem = list_pop_final(edges)
|
|
|
+ list_append(result, create_tuple(elem[1], elem[0]))
|
|
|
+ return result!
|
|
|
+
|
|
|
+Element function strongComp(values : Element):
|
|
|
+ Element graph
|
|
|
+ Element sccs
|
|
|
+ String start_node
|
|
|
+ Element strong_components
|
|
|
+ Element component
|
|
|
+
|
|
|
+ sccs = list_create()
|
|
|
+
|
|
|
+ topSort(values)
|
|
|
+
|
|
|
+ dict_overwrite(values, "unvisited_strongComp", set_copy(values["nodes"]))
|
|
|
+
|
|
|
+ dict_overwrite(values, "rev_edges", reverse_edges(values["edges"]))
|
|
|
+ strong_components = list_create()
|
|
|
+
|
|
|
+ while (set_len(values["unvisited_strongComp"]) > 0):
|
|
|
+ start_node = highest_orderNumber(values)
|
|
|
+
|
|
|
+ component = dfsCollect(values, start_node)
|
|
|
+ list_append(sccs, component)
|
|
|
+ log("Got strong component: " + list_to_string(component))
|
|
|
+
|
|
|
+ return sccs!
|
|
|
+
|
|
|
Element function get_topolist(values : Element):
|
|
|
Element result
|
|
|
Element predecessors
|
|
@@ -137,41 +271,64 @@ Integer function min(a : Integer, b : Integer):
|
|
|
return b!
|
|
|
|
|
|
Void function strongconnect(v : String, values : Element):
|
|
|
+ // if (v.index is undefined) then
|
|
|
+ // strongconnect(V)
|
|
|
if (dict_in(values["indices"], v)):
|
|
|
return!
|
|
|
|
|
|
+ // v.index := index
|
|
|
dict_overwrite(values["indices"], v, values["index"])
|
|
|
+ // v.lowlink := indwx
|
|
|
dict_overwrite(values["lowlink"], v, values["index"])
|
|
|
+ // index := index + 1
|
|
|
dict_overwrite(values, "index", cast_integer(values["index"]) + 1)
|
|
|
|
|
|
+ // S.push(v)
|
|
|
list_append(values["S"], v)
|
|
|
+ // v.onStack := true
|
|
|
dict_overwrite(values["onStack"], v, True)
|
|
|
|
|
|
Element successors
|
|
|
String w
|
|
|
successors = values["successors"][v]
|
|
|
while (set_len(successors) > 0):
|
|
|
+ // for each (v, w) in E do
|
|
|
w = set_pop(successors)
|
|
|
+ // if (w.index is undefined) then
|
|
|
if (bool_not(dict_in(values["indices"], w))):
|
|
|
+ // strongconnect(w)
|
|
|
strongconnect(w, values)
|
|
|
+ // v.lowlink := min(v.lowlink, w.lowlink)
|
|
|
dict_overwrite(values["lowlink"], v, min(values["lowlink"][v], values["lowlink"][w]))
|
|
|
elif (dict_in(values["onStack"], w)):
|
|
|
+ // else if (w.onStack)
|
|
|
if (values["onStack"][w]):
|
|
|
+ // v.lowlink := min(v.lowlink, w.index)
|
|
|
dict_overwrite(values["lowlink"], v, min(values["lowlink"][v], values["indices"][w]))
|
|
|
|
|
|
+ // if (v.lowlink == v.index) then
|
|
|
if (value_eq(values["lowlink"][v], values["indices"][v])):
|
|
|
Element scc
|
|
|
+ // Start a new strongly connected component
|
|
|
scc = create_node()
|
|
|
// It will always differ now
|
|
|
+ // w := S.pop()
|
|
|
w = list_pop_final(values["S"])
|
|
|
- list_append(scc, w)
|
|
|
+ // w.onStack = false
|
|
|
dict_overwrite(values["onStack"], w, False)
|
|
|
+ // add w to current strongly connected component
|
|
|
+ list_append(scc, w)
|
|
|
+ // while w != v
|
|
|
while (w != v):
|
|
|
+ // w := S.pop()
|
|
|
w = list_pop_final(values["S"])
|
|
|
- list_append(scc, w)
|
|
|
+ // w.onStack = false
|
|
|
dict_overwrite(values["onStack"], w, False)
|
|
|
+ // add w to current strongly connected component
|
|
|
+ list_append(scc, w)
|
|
|
+ // output the current strongly connected component
|
|
|
list_insert(values["SCC"], scc, 0)
|
|
|
-
|
|
|
+ log("Found new SCC: " + list_to_string(scc))
|
|
|
return!
|
|
|
|
|
|
Boolean function solve_scc(model : Element, scc : Element):
|
|
@@ -214,14 +371,14 @@ Boolean function solve_scc(model : Element, scc : Element):
|
|
|
elif (blocktype == "FullRuntime/MultiplyBlock"):
|
|
|
constant = 1.0
|
|
|
|
|
|
- incoming = allIncomingAssociationInstances(model, block, "Link")
|
|
|
+ incoming = allIncomingAssociationInstances(model, block, "FullRuntime/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)):
|
|
|
+ if (list_in(scc, selected)):
|
|
|
// Part of the loop, so in the index of selected in scc
|
|
|
// Five options:
|
|
|
if (blocktype == "FullRuntime/AdditionBlock"):
|