| I've pushed a tiny graph library to anarki: http://github.com/nex3/arc/tree/master/lib/graph.arc. It uses adjacency-list representation, and vertices can be any datatype that can go into a table, though they shouldn't be mutated while any graphs involving them are in use. The library is currently very small, implementing only transposition, topological sorting, and Tarjan's algorithm for finding SCCs. I encourage anyone to add algorithms to it. It also uses lib/util.arc, a file I added to anarki a while ago, which I also encourage people to use and improve. In making it, however, I encountered something I formerly found merely annoying, but am now confident enough to label a misfeature: Arc does not distinguish between a key mapping to nil in a table and the same key being absent entirely. pg's justification for this is that "in most cases", it isn't a problem; be that as it may, in this case it is a major pain in the ass, as for a vertex in a graph to have no outgoing edges is emphatically not the same as for the vertex to not exist at all. Instead of using lists, I use tconc-cells, from almkglor's lib/tconc.arc; although their primary purpose is to allow fast appending to and catenation of lists, they serve well here since an empty tconc-cell is non-nil. (The performance boost doesn't hurt either, though it doesn't change the asymptotic complexity.) As an example of what the library can do, suppose we have the following dependency relations among files, such as one might find in a Makefile: bar.h: bar.h.m4
foo.o: foo.c foo.h bar.h
bar.o: bar.c bar.h
foo: foo.o bar.o
To calculate the order in which to check the files for changes and possibly rebuild them, we build a graph representing the dependencies, add any files mentioned on the RHS of a make rule but not on the LHS, then transpose and topologically sort the graph: (= deps (mlist-graph '((bar.h bar.h.m4) (foo.o foo.c foo.h bar.h) (bar.o bar.c bar.h) (foo foo.o bar.o))))
(add-implied-leaves deps)
(top-sort:transpose deps)
=> (foo.c foo.h bar.h.m4 bar.c bar.h foo.o bar.o foo)
|