1 ! Copyright (C) 2008 Alex Chapman
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs hashtables hashtables.private kernel sequences vectors ;
6 TUPLE: digraph < hashtable ;
8 : <digraph> ( -- digraph )
9 0 digraph new [ reset-hash ] keep ;
11 TUPLE: vertex value edges ;
13 : <vertex> ( value -- vertex )
14 V{ } clone vertex boa ;
16 : add-vertex ( key value digraph -- )
17 [ <vertex> swap ] dip set-at ;
19 : children ( key digraph -- seq )
22 : @edges ( from to digraph -- to edges ) swapd at edges>> ;
23 : add-edge ( from to digraph -- ) @edges push ;
24 : delete-edge ( from to digraph -- ) @edges delete ;
26 : delete-to-edges ( to digraph -- )
27 [ nip dupd edges>> delete ] assoc-each drop ;
29 : delete-vertex ( key digraph -- )
30 2dup delete-at delete-to-edges ;
32 : unvisited? ( unvisited key -- ? ) swap key? ;
33 : visited ( unvisited key -- ) swap delete-at ;
35 DEFER: (topological-sort)
36 : visit-children ( seq unvisited key -- seq unvisited )
37 over children [ (topological-sort) ] each ;
39 : (topological-sort) ( seq unvisited key -- seq unvisited )
41 [ visit-children ] keep 2dup visited pick push
46 : topological-sort ( digraph -- seq )
47 dup clone V{ } clone spin
48 [ drop (topological-sort) ] assoc-each drop reverse ;
50 : topological-sorted-values ( digraph -- seq )
51 dup topological-sort swap [ at value>> ] curry map ;