September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
|
|
@ -5,7 +5,7 @@ The compiling of a library in the [[wp:VHDL|VHDL]] language has the constraint t
|
|||
A tool exists that extracts library dependencies.
|
||||
|
||||
|
||||
;Task;
|
||||
;Task:
|
||||
Write a function that will return a valid compile order of VHDL libraries from their dependencies.
|
||||
|
||||
* Assume library names are single words.
|
||||
|
|
@ -38,15 +38,11 @@ synopsys
|
|||
|
||||
|
||||
;C.f.:
|
||||
* [[Topological sort/Extracted top item]].
|
||||
:* [[Topological sort/Extracted top item]].
|
||||
|
||||
<br>
|
||||
There are two popular algorithms for topological sorting:
|
||||
Kahn's 1962 topological sort, and depth-first search.
|
||||
<ref>
|
||||
[[wp: topological sorting]]
|
||||
</ref><ref>
|
||||
Jason Sachs
|
||||
[http://www.embeddedrelated.com/showarticle/799.php "Ten little algorithms, part 4: topological sort"].
|
||||
</ref>
|
||||
:* Kahn's 1962 topological sort <ref> [[wp: topological sorting]] </ref>
|
||||
:* depth-first search <ref> [[wp: topological sorting]] </ref> <ref> Jason Sachs
|
||||
[http://www.embeddedrelated.com/showarticle/799.php "Ten little algorithms, part 4: topological sort"] </ref>
|
||||
<br><br>
|
||||
|
|
|
|||
1
Task/Topological-sort/00META.yaml
Normal file
1
Task/Topological-sort/00META.yaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
--- {}
|
||||
|
|
@ -49,7 +49,8 @@ public:
|
|||
for(auto const& lookup : map)
|
||||
{
|
||||
auto const&
|
||||
goal = lookup.first,
|
||||
goal = lookup.first;
|
||||
auto const&
|
||||
relations = lookup.second;
|
||||
if(relations.dependencies == 0)
|
||||
sorted.push_back(goal);
|
||||
|
|
@ -61,7 +62,8 @@ public:
|
|||
for(auto const& lookup : map)
|
||||
{
|
||||
auto const&
|
||||
goal = lookup.first,
|
||||
goal = lookup.first;
|
||||
auto const&
|
||||
relations = lookup.second;
|
||||
if(relations.dependencies != 0)
|
||||
unsortable.push_back(goal);
|
||||
|
|
|
|||
|
|
@ -1,39 +1,44 @@
|
|||
import Data.List
|
||||
import Data.Maybe
|
||||
import Control.Arrow
|
||||
import System.Random
|
||||
import Control.Monad
|
||||
import Data.List ((\\), elemIndex, intersect, nub)
|
||||
import Control.Arrow ((***), first)
|
||||
|
||||
combs 0 _ = [[]]
|
||||
combs _ [] = []
|
||||
combs k (x:xs) = map (x:) (combs (k-1) xs) ++ combs k xs
|
||||
combs k (x:xs) = ((x :) <$> combs (k - 1) xs) ++ combs k xs
|
||||
|
||||
depLibs :: [(String, String)]
|
||||
depLibs = [("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",[])]
|
||||
|
||||
depLibs =
|
||||
[ ( "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", [])
|
||||
]
|
||||
|
||||
toposort :: [(String, String)] -> [String]
|
||||
toposort xs
|
||||
| (not.null) cycleDetect = error $ "Dependency cycle detected for libs " ++ show cycleDetect
|
||||
| otherwise = foldl makePrecede [] dB
|
||||
| (not . null) cycleDetect =
|
||||
error $ "Dependency cycle detected for libs " ++ show cycleDetect
|
||||
| otherwise = foldl makePrecede [] dB
|
||||
where
|
||||
dB = ((\(x, y) -> (x, y \\ x)) . (return *** words)) <$> xs
|
||||
makePrecede ts ([x], xs) =
|
||||
nub $
|
||||
case elemIndex x ts of
|
||||
Just i -> uncurry (++) $ first (++ xs) $ splitAt i ts
|
||||
_ -> ts ++ xs ++ [x]
|
||||
cycleDetect =
|
||||
filter ((> 1) . length) $
|
||||
(\[(a, as), (b, bs)] -> (a `intersect` bs) ++ (b `intersect` as)) <$>
|
||||
combs 2 dB
|
||||
|
||||
where dB = map ((\(x,y) -> (x,y \\ x)). (return *** words)) xs
|
||||
|
||||
makePrecede ts ([x],xs) = nub $ case elemIndex x ts of
|
||||
Just i -> uncurry(++) $ first(++xs) $ splitAt i ts
|
||||
_ -> ts ++ xs ++ [x]
|
||||
|
||||
cycleDetect = filter ((>1).length)
|
||||
$ map (\[(a,as), (b,bs)] -> (a `intersect` bs) ++ (b `intersect`as))
|
||||
$ combs 2 dB
|
||||
main :: IO ()
|
||||
main = print $ toposort depLibs
|
||||
|
|
|
|||
51
Task/Topological-sort/Kotlin/topological-sort-2.kotlin
Normal file
51
Task/Topological-sort/Kotlin/topological-sort-2.kotlin
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
val graph = mapOf(
|
||||
"des_system_lib" to "std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee".split(" ").toSet(),
|
||||
"dw01" to "ieee dw01 dware gtech".split(" ").toSet(),
|
||||
"dw02" to "ieee dw02 dware".split(" ").toSet(),
|
||||
"dw03" to "std synopsys dware dw03 dw02 dw01 ieee gtech".split(" ").toSet(),
|
||||
"dw04" to "dw04 ieee dw01 dware gtech".split(" ").toSet(),
|
||||
"dw05" to "dw05 ieee dware".split(" ").toSet(),
|
||||
"dw06" to "dw06 ieee dware".split(" ").toSet(),
|
||||
"dw07" to "ieee dware".split(" ").toSet(),
|
||||
"dware" to "ieee dware".split(" ").toSet(),
|
||||
"gtech" to "ieee gtech".split(" ").toSet(),
|
||||
"ramlib" to "std ieee".split(" ").toSet(),
|
||||
"std_cell_lib" to "ieee std_cell_lib".split(" ").toSet(),
|
||||
"synopsys" to setOf()
|
||||
)
|
||||
|
||||
fun toposort( graph: Map<String,Set<String>> ): List<List<String>> {
|
||||
var data = graph.map { (k,v) -> k to v.toMutableSet() }.toMap().toMutableMap()
|
||||
|
||||
// ignore self dependancies
|
||||
data = data.map { (k,v) -> v.remove(k); k to v }.toMap().toMutableMap()
|
||||
|
||||
val extraItemsInDeps = data.values.reduce { a,b -> a.union( b ).toMutableSet() } - data.keys.toSet()
|
||||
|
||||
data.putAll( extraItemsInDeps.map { it to mutableSetOf<String>() }.toMap() )
|
||||
|
||||
val res = mutableListOf<List<String>>()
|
||||
mainloop@ while( true ) {
|
||||
innerloop@ while( true ) {
|
||||
val ordered = data.filter{ (_,v) -> v.isEmpty() }.map { (k,_) -> k }
|
||||
if( ordered.isEmpty() )
|
||||
break@innerloop
|
||||
|
||||
res.add( ordered )
|
||||
data = data.filter { (k,_) -> !ordered.contains(k) }.map { (k,v) -> v.removeAll(ordered); k to v }.toMap().toMutableMap()
|
||||
}
|
||||
|
||||
if( data.isNotEmpty() )
|
||||
throw Exception( "A cyclic dependency exists amongst: ${data.toList().joinToString { "," }}" )
|
||||
else
|
||||
break@mainloop
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
fun main( args: Array<String> ) {
|
||||
val result = toposort( graph )
|
||||
println( "sorted dependencies:[\n${result.joinToString( ",\n")}\n]" )
|
||||
}
|
||||
76
Task/Topological-sort/Mercury/topological-sort.mercury
Normal file
76
Task/Topological-sort/Mercury/topological-sort.mercury
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
:- module topological_sort.
|
||||
|
||||
:- interface.
|
||||
|
||||
:- import_module io.
|
||||
:- pred main(io::di,io::uo) is det.
|
||||
|
||||
|
||||
:- implementation.
|
||||
:- import_module string, solutions, list, set, require.
|
||||
|
||||
:- pred min_element(set(T),pred(T,T),T).
|
||||
:- mode min_element(in,pred(in,in) is semidet,out) is nondet.
|
||||
min_element(_,_,_):-fail.
|
||||
min_element(S,P,X):-
|
||||
member(X,S),
|
||||
filter((pred(Y::in) is semidet :- P(Y,X)),S,LowerThanX),
|
||||
is_empty(LowerThanX).
|
||||
|
||||
|
||||
|
||||
:- pred topological_sort(set(T),pred(T,T),list(T),list(T)).
|
||||
:- mode topological_sort(in,(pred((ground >> ground), (ground >> ground)) is semidet),in,out) is nondet.
|
||||
:- pred topological_sort(set(T),pred(T,T),list(T)).
|
||||
:- mode topological_sort(in,(pred((ground >> ground), (ground >> ground)) is semidet),out) is nondet.
|
||||
|
||||
topological_sort(S,P,Ac,L) :-
|
||||
(
|
||||
is_empty(S) -> L is Ac
|
||||
; solutions(
|
||||
pred(X::out) is nondet:-
|
||||
min_element(S,P,X)
|
||||
, Solutions
|
||||
),
|
||||
(
|
||||
is_empty(Solutions) -> error("No solution detected.\n")
|
||||
; delete_list(Solutions,S,Sprime),
|
||||
append(Solutions,Ac,AcPrime),
|
||||
topological_sort(Sprime,P,AcPrime,L)
|
||||
)
|
||||
).
|
||||
|
||||
topological_sort(S,P,L) :- topological_sort(S,P,[],L).
|
||||
|
||||
|
||||
:- pred distribute(list(T)::in,{T,list(T)}::out) is det.
|
||||
distribute([],_):-error("Error in distribute").
|
||||
distribute([H|T],Z) :- Z = {H,T}.
|
||||
|
||||
:- pred db_compare({string,list(string)}::in,{string,list(string)}::in) is semidet.
|
||||
db_compare({X1,L1},{X2,_}) :- not(X1=X2),list.member(X2,L1).
|
||||
|
||||
|
||||
main(!IO) :-
|
||||
Input = [
|
||||
"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"],
|
||||
Words=list.map(string.words,Input),
|
||||
list.map(distribute,Words,Db),
|
||||
solutions(pred(X::out) is nondet :- topological_sort(set.from_list(Db),db_compare,X),SortedWordLists),
|
||||
list.map(
|
||||
pred({X,Y}::in,Z::out) is det:- X=Z,
|
||||
list.det_head(SortedWordLists),
|
||||
CompileOrder),
|
||||
print(CompileOrder,!IO).
|
||||
90
Task/Topological-sort/Phix/topological-sort.phix
Normal file
90
Task/Topological-sort/Phix/topological-sort.phix
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
sequence names
|
||||
enum RANK, NAME, DEP -- content of names
|
||||
-- rank is 1 for items to compile first, then 2, etc,
|
||||
-- or 0 if cyclic dependencies prevent compilation.
|
||||
-- name is handy, and makes the result order alphabetic!
|
||||
-- dep is a list of dependencies (indexes to other names)
|
||||
|
||||
function add_dependency(string name)
|
||||
integer k = find(name,vslice(names,NAME))
|
||||
if k=0 then
|
||||
names = append(names,{0,name,{}})
|
||||
k = length(names)
|
||||
end if
|
||||
return k
|
||||
end function
|
||||
|
||||
procedure topsort(string input)
|
||||
names = {}
|
||||
sequence lines = split(input,'\n')
|
||||
for i=1 to length(lines) do
|
||||
sequence line = split(lines[i],no_empty:=true),
|
||||
dependencies = {}
|
||||
integer k = add_dependency(line[1])
|
||||
for j=2 to length(line) do
|
||||
integer l = add_dependency(line[j])
|
||||
if l!=k then -- ignore self-references
|
||||
dependencies &= l
|
||||
end if
|
||||
end for
|
||||
names[k][DEP] = dependencies
|
||||
end for
|
||||
|
||||
-- Now populate names[RANK] iteratively:
|
||||
bool more = true
|
||||
integer rank = 0
|
||||
while more do
|
||||
more = false
|
||||
rank += 1
|
||||
for i=1 to length(names) do
|
||||
if names[i][RANK]=0 then
|
||||
bool ok = true
|
||||
for j=1 to length(names[i][DEP]) do
|
||||
integer ji = names[i][DEP][j],
|
||||
nr = names[ji][RANK]
|
||||
if nr=0 or nr=rank then
|
||||
-- not yet compiled, or same pass
|
||||
ok = false
|
||||
exit
|
||||
end if
|
||||
end for
|
||||
if ok then
|
||||
names[i][RANK] = rank
|
||||
more = true
|
||||
end if
|
||||
end if
|
||||
end for
|
||||
end while
|
||||
|
||||
names = sort(names) -- (ie by [RANK=1] then [NAME=2])
|
||||
integer prank = names[1][RANK]
|
||||
if prank=0 then puts(1,"** CYCLIC **:") end if
|
||||
for i=1 to length(names) do
|
||||
rank = names[i][RANK]
|
||||
if i>1 then
|
||||
puts(1,iff(rank=prank?" ":"\n"))
|
||||
end if
|
||||
puts(1,names[i][NAME])
|
||||
prank = rank
|
||||
end for
|
||||
puts(1,"\n")
|
||||
end procedure
|
||||
|
||||
constant input = """
|
||||
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"""
|
||||
|
||||
topsort(input)
|
||||
puts(1,"\nbad input:\n")
|
||||
topsort(input&"\ndw01 dw04")
|
||||
|
|
@ -1,46 +1,43 @@
|
|||
/*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.*/
|
||||
nL=15; nd=44; nc=69 /* " " "parms" and indices.*/
|
||||
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
|
||||
j=0
|
||||
do i=1
|
||||
iL=word(iCode, i); if iL==0 then leave
|
||||
do forever; i=i + 1
|
||||
iR=word(iCode, i); if iR==0 then leave
|
||||
j=j + 1
|
||||
iDep.j.1= iL
|
||||
iDep.j.2= iR
|
||||
end /*forever*/
|
||||
end /*i*/
|
||||
call tsort
|
||||
iDep.= 0; iPos.= 0; iOrd.= 0 /*initialize some stemmed arrays to 0.*/
|
||||
nL= 15; nd= 44; nc= 69 /* " " "parms" and indices.*/
|
||||
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
|
||||
j= 0
|
||||
do i=1
|
||||
iL= word(iCode, i); if iL==0 then leave
|
||||
do forever; i= i+1
|
||||
iR= word(iCode, i); if iR==0 then leave
|
||||
j= j+1; iDep.j.1= iL
|
||||
iDep.j.2= iR
|
||||
end /*forever*/
|
||||
end /*i*/
|
||||
call tSort
|
||||
say '═══compile order═══'
|
||||
@= 'libraries found.)'
|
||||
#=0; do o=nO by -1 for nO; #= #+1; say word(label, iOrd.o)
|
||||
end /*o*/; if #==0 then #= 'no'
|
||||
#=0; do o=nO by -1 for nO; #= #+1; say word(label, iOrd.o)
|
||||
end /*o*/; if #==0 then #= 'no'
|
||||
say ' ('# @; say
|
||||
say '═══unordered libraries═══'
|
||||
#=0; do u=nO+1 to nL; #= #+1; say word(label, iOrd.u)
|
||||
end /*u*/; if #==0 then #= 'no'
|
||||
#=0; do u=nO+1 to nL; #= #+1; say word(label, iOrd.u)
|
||||
end /*u*/; if #==0 then #= 'no'
|
||||
say ' ('# "unordered" @
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
tSort: procedure expose iDep. iOrd. iPos. nd nL nO
|
||||
do i=1 for nL; iOrd.i=i; iPos.i=i
|
||||
end /*i*/
|
||||
k=1
|
||||
do until k<=j; 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*/
|
||||
end /*until*/
|
||||
nO=j - 1; return
|
||||
do i=1 for nL; iOrd.i= i; iPos.i= i
|
||||
end /*i*/
|
||||
k= 1
|
||||
do until k<=j; 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*/
|
||||
end /*until*/
|
||||
nO= j-1; return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue