September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -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>
:* &nbsp; Kahn's 1962 topological sort <ref> [[wp: topological sorting]] </ref>
:* &nbsp; 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>

View file

@ -0,0 +1 @@
--- {}

View file

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

View file

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

View 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]" )
}

View 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).

View 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")

View file

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