2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,14 +1,19 @@
|
|||
Given a mapping between items, and items they depend on, a [[wp:Topological sorting|topological sort]] orders items so that no item precedes an item it depends upon.
|
||||
|
||||
The compiling of a library in the [[wp:VHDL|VHDL]] language has the constraint that a library must be compiled after any library it depends on.
|
||||
|
||||
A tool exists that extracts library dependencies.
|
||||
The task is to '''write a function that will return a valid compile order of VHDL libraries from their dependencies.'''
|
||||
|
||||
|
||||
;Task;
|
||||
Write a function that will return a valid compile order of VHDL libraries from their dependencies.
|
||||
|
||||
* Assume library names are single words.
|
||||
* Items mentioned as only dependants, (sic), have no dependants of their own, but their order of compiling must be given.
|
||||
* Items mentioned as only dependents, (sic), have no dependents of their own, but their order of compiling must be given.
|
||||
* Any self dependencies should be ignored.
|
||||
* Any un-orderable dependencies should be flagged.
|
||||
|
||||
<br>
|
||||
Use the following data as an example:
|
||||
<pre>
|
||||
LIBRARY LIBRARY DEPENDENCIES
|
||||
|
|
@ -25,12 +30,17 @@ dware ieee dware
|
|||
gtech ieee gtech
|
||||
ramlib std ieee
|
||||
std_cell_lib ieee std_cell_lib
|
||||
synopsys </pre>
|
||||
synopsys
|
||||
</pre>
|
||||
|
||||
<br>
|
||||
<small>Note: the above data would be un-orderable if, for example, <code>dw04</code> is added to the list of dependencies of <code>dw01</code>.</small>
|
||||
|
||||
C.f: [[Topological sort/Extracted top item]].
|
||||
|
||||
;C.f.:
|
||||
* [[Topological sort/Extracted top item]].
|
||||
|
||||
<br>
|
||||
There are two popular algorithms for topological sorting:
|
||||
Kahn's 1962 topological sort, and depth-first search.
|
||||
<ref>
|
||||
|
|
@ -39,3 +49,4 @@ Kahn's 1962 topological sort, and depth-first search.
|
|||
Jason Sachs
|
||||
[http://www.embeddedrelated.com/showarticle/799.php "Ten little algorithms, part 4: topological sort"].
|
||||
</ref>
|
||||
<br><br>
|
||||
|
|
|
|||
46
Task/Topological-sort/Elixir/topological-sort.elixir
Normal file
46
Task/Topological-sort/Elixir/topological-sort.elixir
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
defmodule Topological do
|
||||
def sort(library) do
|
||||
g = :digraph.new
|
||||
Enum.each(library, fn {l,deps} ->
|
||||
:digraph.add_vertex(g,l) # noop if library already added
|
||||
Enum.each(deps, fn d -> add_dependency(g,l,d) end)
|
||||
end)
|
||||
if t = :digraph_utils.topsort(g) do
|
||||
print_path(t)
|
||||
else
|
||||
IO.puts "Unsortable contains circular dependencies:"
|
||||
Enum.each(:digraph.vertices(g), fn v ->
|
||||
if vs = :digraph.get_short_cycle(g,v), do: print_path(vs)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
defp print_path(l), do: IO.puts Enum.join(l, " -> ")
|
||||
|
||||
defp add_dependency(_g,l,l), do: :ok
|
||||
defp add_dependency(g,l,d) do
|
||||
:digraph.add_vertex(g,d) # noop if dependency already added
|
||||
:digraph.add_edge(g,d,l) # Dependencies represented as an edge d -> l
|
||||
end
|
||||
end
|
||||
|
||||
libraries = [
|
||||
des_system_lib: ~w[std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee]a,
|
||||
dw01: ~w[ieee dw01 dware gtech]a,
|
||||
dw02: ~w[ieee dw02 dware]a,
|
||||
dw03: ~w[std synopsys dware dw03 dw02 dw01 ieee gtech]a,
|
||||
dw04: ~w[dw04 ieee dw01 dware gtech]a,
|
||||
dw05: ~w[dw05 ieee dware]a,
|
||||
dw06: ~w[dw06 ieee dware]a,
|
||||
dw07: ~w[ieee dware]a,
|
||||
dware: ~w[ieee dware]a,
|
||||
gtech: ~w[ieee gtech]a,
|
||||
ramlib: ~w[std ieee]a,
|
||||
std_cell_lib: ~w[ieee std_cell_lib]a,
|
||||
synopsys: []
|
||||
]
|
||||
Topological.sort(libraries)
|
||||
|
||||
IO.puts ""
|
||||
bad_libraries = Keyword.update!(libraries, :dw01, &[:dw04 | &1])
|
||||
Topological.sort(bad_libraries)
|
||||
71
Task/Topological-sort/Forth/topological-sort.fth
Normal file
71
Task/Topological-sort/Forth/topological-sort.fth
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
variable nodes 0 nodes ! \ linked list of nodes
|
||||
|
||||
: node. ( body -- )
|
||||
body> >name name>string type ;
|
||||
|
||||
: nodeps ( body -- )
|
||||
\ the word referenced by body has no (more) dependencies to resolve
|
||||
['] drop over ! node. space ;
|
||||
|
||||
: processing ( body1 ... bodyn body -- body1 ... bodyn )
|
||||
\ the word referenced by body is in the middle of resolving dependencies
|
||||
2dup <> if \ unless it is a self-reference (see task description)
|
||||
['] drop over !
|
||||
." (cycle: " dup node. >r 1 begin \ print the cycle
|
||||
dup pick dup r@ <> while
|
||||
space node. 1+ repeat
|
||||
." ) " 2drop r>
|
||||
then drop ;
|
||||
|
||||
: >processing ( body -- body )
|
||||
['] processing over ! ;
|
||||
|
||||
: node ( "name" -- )
|
||||
\ define node "name" and initialize it to having no dependences
|
||||
create
|
||||
['] nodeps , \ on definition, a node has no dependencies
|
||||
nodes @ , lastxt nodes ! \ linked list of nodes
|
||||
does> ( -- )
|
||||
dup @ execute ; \ perform xt associated with node
|
||||
|
||||
: define-nodes ( "names" <newline> -- )
|
||||
\ define all the names that don't exist yet as nodes
|
||||
begin
|
||||
parse-name dup while
|
||||
2dup find-name 0= if
|
||||
2dup nextname node then
|
||||
2drop repeat
|
||||
2drop ;
|
||||
|
||||
: deps ( "name" "deps" <newline> -- )
|
||||
\ name is after deps. Implementation: Define missing nodes, then
|
||||
\ define a colon definition for
|
||||
>in @ define-nodes >in !
|
||||
' :noname ]] >processing [[ source >in @ /string evaluate ]] nodeps ; [[
|
||||
swap >body ! 0 parse 2drop ;
|
||||
|
||||
: all-nodes ( -- )
|
||||
\ call all nodes, and they then print their dependences and themselves
|
||||
nodes begin
|
||||
@ dup while
|
||||
dup execute
|
||||
>body cell+ repeat
|
||||
drop ;
|
||||
|
||||
deps des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
|
||||
deps dw01 ieee dw01 dware gtech
|
||||
deps dw02 ieee dw02 dware
|
||||
deps dw03 std synopsys dware dw03 dw02 dw01 ieee gtech
|
||||
deps dw04 dw04 ieee dw01 dware gtech
|
||||
deps dw05 dw05 ieee dware
|
||||
deps dw06 dw06 ieee dware
|
||||
deps dw07 ieee dware
|
||||
deps dware ieee dware
|
||||
deps gtech ieee gtech
|
||||
deps ramlib std ieee
|
||||
deps std_cell_lib ieee std_cell_lib
|
||||
deps synopsys
|
||||
\ to test the cycle recognition (overwrites dependences for dw1 above)
|
||||
deps dw01 ieee dw01 dware gtech dw04
|
||||
|
||||
all-nodes
|
||||
|
|
@ -1,26 +1,77 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.TreeMap;
|
||||
import java.util.*;
|
||||
|
||||
public class TopologicalSort {
|
||||
public static void main(String[] args) throws Exception {
|
||||
TreeMap<String, ArrayList<String>> mp = new TreeMap<String, ArrayList<String>>();
|
||||
String[] data, input = new String[] {
|
||||
"des_system_lib: std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee",
|
||||
"dw01: ieee dw01 dware gtech", "dw02: ieee dw02 dware",
|
||||
"dw03: std synopsys dware dw03 dw02 dw01 ieee gtech",
|
||||
"dw04: dw04 ieee dw01 dware gtech", "dw05: dw05 ieee dware",
|
||||
"dw06: dw06 ieee dware", "dw07: ieee dware",
|
||||
"dware: ieee dware", "gtech: ieee gtech", "ramlib: std ieee",
|
||||
"std_cell_lib: ieee std_cell_lib", "synopsys:" };
|
||||
|
||||
for (String str : input)
|
||||
mp.put((data = str.split(":"))[0], Utils.aList(//
|
||||
data.length < 2 || data[1].trim().equals("")//
|
||||
? null : data[1].trim().split("\\s+")));
|
||||
public static void main(String[] args) {
|
||||
String s = "std, ieee, des_system_lib, dw01, dw02, dw03, dw04, dw05,"
|
||||
+ "dw06, dw07, dware, gtech, ramlib, std_cell_lib, synopsys";
|
||||
|
||||
Utils.tSortFix(mp);
|
||||
System.out.println(Utils.tSort(mp));
|
||||
mp.put("dw01", Utils.aList("dw04"));
|
||||
System.out.println(Utils.tSort(mp));
|
||||
}
|
||||
Graph g = new Graph(s, new int[][]{
|
||||
{2, 0}, {2, 14}, {2, 13}, {2, 4}, {2, 3}, {2, 12}, {2, 1},
|
||||
{3, 1}, {3, 10}, {3, 11},
|
||||
{4, 1}, {4, 10},
|
||||
{5, 0}, {5, 14}, {5, 10}, {5, 4}, {5, 3}, {5, 1}, {5, 11},
|
||||
{6, 1}, {6, 3}, {6, 10}, {6, 11},
|
||||
{7, 1}, {7, 10},
|
||||
{8, 1}, {8, 10},
|
||||
{9, 1}, {9, 10},
|
||||
{10, 1},
|
||||
{11, 1}, {11, 10},
|
||||
{12, 0}, {12, 1},
|
||||
{13, 1}
|
||||
});
|
||||
|
||||
System.out.println("Topologically sorted order: ");
|
||||
System.out.println(g.topoSort());
|
||||
}
|
||||
}
|
||||
|
||||
class Graph {
|
||||
String[] vertices;
|
||||
boolean[][] adjacency;
|
||||
int numVertices;
|
||||
|
||||
public Graph(String s, int[][] edges) {
|
||||
vertices = s.split(",");
|
||||
numVertices = vertices.length;
|
||||
adjacency = new boolean[numVertices][numVertices];
|
||||
|
||||
for (int[] edge : edges)
|
||||
adjacency[edge[0]][edge[1]] = true;
|
||||
}
|
||||
|
||||
List<String> topoSort() {
|
||||
List<String> result = new ArrayList<>();
|
||||
List<Integer> todo = new LinkedList<>();
|
||||
|
||||
for (int i = 0; i < numVertices; i++)
|
||||
todo.add(i);
|
||||
|
||||
try {
|
||||
outer:
|
||||
while (!todo.isEmpty()) {
|
||||
for (Integer r : todo) {
|
||||
if (!hasDependency(r, todo)) {
|
||||
todo.remove(r);
|
||||
result.add(vertices[r]);
|
||||
// no need to worry about concurrent modification
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
throw new Exception("Graph has cycles");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean hasDependency(Integer r, List<Integer> todo) {
|
||||
for (Integer c : todo) {
|
||||
if (adjacency[r][c])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,5 +33,5 @@ my %deps =
|
|||
synopsys => < >;
|
||||
|
||||
print_topo_sort(%deps);
|
||||
%deps<dw01>.push: 'dw04'; # Add unresolvable dependency
|
||||
%deps<dw01> = <ieee dw01 dware gtech dw04>; # Add unresolvable dependency
|
||||
print_topo_sort(%deps);
|
||||
|
|
|
|||
62
Task/Topological-sort/REXX/topological-sort.rexx
Normal file
62
Task/Topological-sort/REXX/topological-sort.rexx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*REXX pgm does a topological sort (orders such that no item precedes a dependent item).*/
|
||||
idep.=0; ipos.=0; iord.=0 /*initialize some stemmed arrays to 0.*/
|
||||
label= 'DES_SYSTEM_LIB DW01 DW02 DW03 DW04 DW05 DW06 DW07 DWARE GTECH RAMLIB',
|
||||
'STD_CELL_LIB SYNOPSYS STD IEEE'
|
||||
|
||||
icode=1 14 13 12 1 3 2 11 15 0 2 15 2 9 10 0 3 15 3 9 0 4 14 213 9 4 3 2 15 10 0 5 5 15 2,
|
||||
9 10 0 6 6 15 9 0 7 7 15 9 0 8 15 9 0 39 15 9 0 10 15 10 0 11 14 15 0 12 15 12 0 0
|
||||
|
||||
idep.=0; ipos.=0; iord.=0 /*initialize some stemmed arrays to 0.*/
|
||||
nl=15; nd=44; nc=69; j=0; i=0 /* " " "parms" and indices.*/
|
||||
|
||||
10: i=i+1
|
||||
il=word(icode, i)
|
||||
if il==0 then signal 30
|
||||
20: i=i+1
|
||||
ir=word(icode, i)
|
||||
if ir==0 then signal 10
|
||||
j=j+1
|
||||
idep.j.1=il
|
||||
idep.j.2=ir
|
||||
signal 20
|
||||
30: call tsort
|
||||
say '═══compile order═══'
|
||||
q=0; do o=no by -1 for no; q=q+1
|
||||
say word(label, iord.o)
|
||||
end /*o*/
|
||||
if q==0 then q='no'
|
||||
say ' ('q "libraries found.)"
|
||||
say
|
||||
say '═══unordered libraries═══'
|
||||
q=0; do u=no+1 to nl; q=q+1
|
||||
say word(label, iord.u)
|
||||
end /*u*/
|
||||
if q==0 then q='no'
|
||||
say ' ('q "unordered libraries found.)"
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
tSort: procedure expose nl nd idep. iord. ipos. no
|
||||
do i=1 for nl
|
||||
iord.i=i
|
||||
ipos.i=i
|
||||
end /*i*/
|
||||
k=1
|
||||
do forever
|
||||
j=k
|
||||
k=nl+1
|
||||
do i=1 for nd
|
||||
il=idep.i.1
|
||||
ir=ipos.il
|
||||
ipl=ipos.il
|
||||
ipr=ipos.ir
|
||||
if il==ir | ipl>.k | ipl<j | ipr<j then iterate
|
||||
k=k-1
|
||||
_=iord.k; ipos._=ipl
|
||||
ipos.il=k
|
||||
iord.ipl=iord.k
|
||||
iord.k=il
|
||||
end /*i*/
|
||||
if k<=j then leave
|
||||
end /*forever*/
|
||||
no=j-1
|
||||
return
|
||||
Loading…
Add table
Add a link
Reference in a new issue