#!/usr/bin/lua5.1 nodes = {} clusters = {} edges = {} args = {} function decompose(n) return n:match("^([^/]+)/([^%.]+)") end for l in io.lines() do local to, froms = l:match("^([^ :]+)[^:]*:(.*)") local cluster, module = decompose(to) clusters[cluster] = clusters[cluster] or {} clusters[cluster][module] = true nodes[module] = true for from in froms:gmatch("[^ ]+") do local cluster, module2 = decompose(from) nodes[module2] = true if module ~= module2 then clusters[cluster] = clusters[cluster] or {} clusters[cluster][module2] = true edges[#edges+1] = { from = module; to = module2 } end end end -- transitive reduction -- -- // reflexive reduction -- for (int i = 0; i < N; ++i) -- m[i][i] = false; -- -- // transitive reduction -- for (int j = 0; j < N; ++j) -- for (int i = 0; i < N; ++i) -- if (m[i][j]) -- for (int k = 0; k < N; ++k) -- if (m[j][k]) -- m[i][k] = false; -- function path_matrix(nodes,edges) local m = {} for j,_ in pairs(nodes) do m[j] = {} end for _,e in ipairs(edges) do m[e.from][e.to] = true end -- close for j,_ in pairs(nodes) do for i,_ in pairs(nodes) do for k,_ in pairs(nodes) do if m[i][j] == true and m[j][k] == true then m[i][k] = true end end end end return m end function tred(nodes,m) -- reduce for j,_ in pairs(nodes) do for i,_ in pairs(nodes) do if m[i][j] == true then for k,_ in pairs(nodes) do if m[j][k] then m[i][k] = false end end end end end end function matrix_to_list(nodes,m) local edges = {} for j,_ in pairs(nodes) do for i,_ in pairs(nodes) do if m[i][j] == true then edges[#edges+1] = { from = i; to = j } end end end return edges end m = path_matrix(nodes,edges) tred(nodes,m) edges = matrix_to_list(nodes,m) meta_edges = {} for c1,nodes1 in pairs(clusters) do for c2,nodes2 in pairs(clusters) do if (c1 ~= c2) then local connected = false for n1,_ in pairs(nodes1) do for n2,_ in pairs(nodes2) do if m[n1][n2] == true then connected = true end end end if connected then meta_edges[#meta_edges+1] = { from = c1; to = c2 } end end end end m = path_matrix(clusters,meta_edges) tred(clusters,m) meta_edges = matrix_to_list(clusters,m) function dot() print[[ digraph mathcomp { compound = true; ]] for c,nodes in pairs(clusters) do print("subgraph cluster_" .. c .. " {") for node,_ in pairs(nodes) do print('"'..node..'";') end print("}") end for _,edge in ipairs(edges) do print(string.format('"%s" -> "%s";',edge.from,edge.to)) end print[[ } ]] end function cytoscape() print[[ var depends = [ ]] for c,nodes in pairs(clusters) do print(string.format('{ data: { id: "cluster_%s", name: "%s" } },', c, c)) print(string.format('{ data: { id: "cluster_%s_plus", name: "+", parent: "cluster_%s" } },', c, c)) for node,_ in pairs(nodes) do local released = "no" if args[node] then released = "yes" end print(string.format('{ data: { id: "%s", name: "%s", parent: "cluster_%s", released: "%s" } },', node, node, c, released)) end end local i = 0 for _,edge in ipairs(edges) do print(string.format('{ data: { id: "edge%d", source: "%s", target: "%s" } },', i, edge.from,edge.to)) i=i+1 end for _,edge in ipairs(meta_edges) do print(string.format('{ data: { id: "edge%d", source: "cluster_%s", target: "cluster_%s" } },', i, edge.from,edge.to)) i=i+1 end print[[ ]; ]] end for i=2,#arg do args[arg[i]] = true end _G[arg[1]]() -- $COQBIN/coqdep -R . mathcomp */*.v | grep -v vio: | grep -v ssrtest > depend -- cat depend | ./graph.lua dot | tee depend.dot | dot -T png -o depend.png -- cat depend | ./graph.lua cytoscape `git show release/1.6:mathcomp/Make | grep 'v *$' | cut -d / -f 2 | cut -d . -f 1` > depend.js