factor/unmaintained/graph-theory/graph-theory.factor

92 lines
2.5 KiB
Factor
Raw Normal View History

2008-06-20 22:52:44 -04:00
! Copyright (C) 2008 William Schlieper <schlieper@unc.edu>
! See http://factorcode.org/license.txt for BSD license.
2009-04-17 12:14:16 -04:00
USING: kernel combinators fry continuations sequences arrays
vectors assocs hashtables heaps namespaces ;
2008-06-20 22:52:44 -04:00
IN: graph-theory
MIXIN: graph
SYMBOL: visited?
ERROR: end-search ;
GENERIC: vertices ( graph -- seq ) flushable
GENERIC: num-vertices ( graph -- n ) flushable
GENERIC: num-edges ( graph -- n ) flushable
GENERIC: adjlist ( from graph -- seq ) flushable
GENERIC: adj? ( from to graph -- ? ) flushable
GENERIC: add-blank-vertex ( index graph -- )
GENERIC: delete-blank-vertex ( index graph -- )
GENERIC: add-edge* ( from to graph -- )
GENERIC: add-edge ( u v graph -- )
GENERIC: delete-edge* ( from to graph -- )
GENERIC: delete-edge ( u v graph -- )
M: graph num-vertices
vertices length ;
M: graph num-edges
2009-04-17 12:14:16 -04:00
[ vertices ] [ '[ _ adjlist length ] sigma ] bi ;
2008-06-20 22:52:44 -04:00
M: graph adjlist
2008-09-10 23:11:40 -04:00
[ vertices ] [ swapd '[ _ swap _ adj? ] filter ] bi ;
2008-06-20 22:52:44 -04:00
M: graph adj?
swapd adjlist index >boolean ;
M: graph add-edge
[ add-edge* ] [ swapd add-edge* ] 3bi ;
M: graph delete-edge
[ delete-edge* ] [ swapd delete-edge* ] 3bi ;
: add-blank-vertices ( seq graph -- )
2008-09-10 23:11:40 -04:00
'[ _ add-blank-vertex ] each ;
2008-06-20 22:52:44 -04:00
: delete-vertex ( index graph -- )
[ adjlist ]
2008-09-10 23:11:40 -04:00
[ '[ _ _ 3dup adj? [ delete-edge* ] [ 3drop ] if ] each ]
2008-06-20 22:52:44 -04:00
[ delete-blank-vertex ] 2tri ;
<PRIVATE
: search-wrap ( quot graph -- ? )
[ [ graph set ] [ vertices [ f 2array ] map >hashtable visited? set ] bi
[ t ] compose [ dup end-search? [ drop f ] [ rethrow ] if ] recover ] with-scope ; inline
: (depth-first) ( v pre post -- )
{ [ 2drop visited? get t -rot set-at ]
[ drop call ]
[ [ graph get adjlist ] 2dip
2008-09-10 23:11:40 -04:00
'[ dup visited? get at [ drop ] [ _ _ (depth-first) ] if ] each ]
2008-06-20 22:52:44 -04:00
[ nip call ] } 3cleave ; inline
PRIVATE>
: depth-first ( v graph pre post -- ?list ? )
2008-09-10 23:11:40 -04:00
'[ _ _ (depth-first) visited? get ] swap search-wrap ; inline
2008-06-20 22:52:44 -04:00
: full-depth-first ( graph pre post tail -- ? )
'[ [ visited? get [ nip not ] assoc-find ]
2008-09-10 23:11:40 -04:00
[ drop _ _ (depth-first) @ ]
while 2drop ] swap search-wrap ; inline
2008-06-20 22:52:44 -04:00
: dag? ( graph -- ? )
V{ } clone swap [ 2dup swap push dupd
2008-09-10 23:11:40 -04:00
'[ _ swap graph get adj? not ] all?
2008-06-20 22:52:44 -04:00
[ end-search ] unless ]
[ drop dup pop* ] [ ] full-depth-first nip ;
: topological-sort ( graph -- seq/f )
dup dag?
2009-04-17 12:14:16 -04:00
[ V{ } clone swap [ drop ] [ prefix ] [ ] full-depth-first drop ]
2008-06-20 22:52:44 -04:00
[ drop f ] if ;