| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | ! Copyright (C) 2007, 2008 Ryan Murphy, Doug Coleman, | 
					
						
							|  |  |  | ! Slava Pestov. | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | USING: kernel math sequences arrays assocs sequences.private | 
					
						
							|  |  |  | growable ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | IN: heaps | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-20 00:34:30 -05:00
										 |  |  | MIXIN: priority-queue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | GENERIC: heap-push* ( value key heap -- entry )
 | 
					
						
							| 
									
										
										
										
											2007-12-20 00:34:30 -05:00
										 |  |  | GENERIC: heap-peek ( heap -- value key )
 | 
					
						
							|  |  |  | GENERIC: heap-pop* ( heap -- )
 | 
					
						
							|  |  |  | GENERIC: heap-pop ( heap -- value key )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  | GENERIC: heap-delete ( entry heap -- )
 | 
					
						
							| 
									
										
										
										
											2007-12-20 00:34:30 -05:00
										 |  |  | GENERIC: heap-empty? ( heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | GENERIC: heap-size ( heap -- n )
 | 
					
						
							| 
									
										
										
										
											2007-12-20 00:34:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : heap-data delegate ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:10:26 -05:00
										 |  |  | : <heap> ( class -- heap )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     >r V{ } clone r> construct-delegate ; inline
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-22 17:16:00 -05:00
										 |  |  | TUPLE: entry value key heap index ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-22 17:16:00 -05:00
										 |  |  | : <entry> ( value key heap -- entry ) f entry construct-boa ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: min-heap ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : <min-heap> ( -- min-heap ) min-heap <heap> ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | TUPLE: max-heap ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : <max-heap> ( -- max-heap ) max-heap <heap> ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-20 00:34:30 -05:00
										 |  |  | INSTANCE: min-heap priority-queue | 
					
						
							|  |  |  | INSTANCE: max-heap priority-queue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | M: priority-queue heap-empty? ( heap -- ? )
 | 
					
						
							|  |  |  |     heap-data empty? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: priority-queue heap-size ( heap -- n )
 | 
					
						
							|  |  |  |     heap-data length ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : left ( n -- m ) 1 shift 1 + ; inline
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : right ( n -- m ) 1 shift 2 + ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : up ( n -- m ) 1- 2/ ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : data-nth ( n heap -- entry )
 | 
					
						
							|  |  |  |     heap-data nth-unsafe ; inline
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : up-value ( n heap -- entry )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     >r up r> data-nth ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : left-value ( n heap -- entry )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     >r left r> data-nth ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : right-value ( n heap -- entry )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     >r right r> data-nth ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : data-set-nth ( entry n heap -- )
 | 
					
						
							|  |  |  |     >r [ swap set-entry-index ] 2keep r> | 
					
						
							|  |  |  |     heap-data set-nth-unsafe ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : data-push ( entry heap -- n )
 | 
					
						
							|  |  |  |     dup heap-size [ | 
					
						
							|  |  |  |         swap 2dup heap-data ensure 2drop data-set-nth | 
					
						
							|  |  |  |     ] keep ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : data-pop ( heap -- entry )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     heap-data pop ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : data-pop* ( heap -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     heap-data pop* ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : data-peek ( heap -- entry )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     heap-data peek ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : data-first ( heap -- entry )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     heap-data first ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : data-exchange ( m n heap -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     [ tuck data-nth >r data-nth r> ] 3keep
 | 
					
						
							|  |  |  |     tuck >r >r data-set-nth r> r> data-set-nth ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:10:26 -05:00
										 |  |  | GENERIC: heap-compare ( pair1 pair2 heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (heap-compare) drop [ entry-key ] compare 0 ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:10:26 -05:00
										 |  |  | M: min-heap heap-compare (heap-compare) > ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:10:26 -05:00
										 |  |  | M: max-heap heap-compare (heap-compare) < ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : heap-bounds-check? ( m heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     heap-size >= ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | : left-bounds-check? ( m heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     >r left r> heap-bounds-check? ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : right-bounds-check? ( m heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     >r right r> heap-bounds-check? ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : continue? ( m up[m] heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     [ data-nth swap ] keep [ data-nth ] keep
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     heap-compare ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | DEFER: up-heap | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (up-heap) ( n heap -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     >r dup up r> | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     3dup continue? [ | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |         [ data-exchange ] 2keep up-heap | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |         3drop
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : up-heap ( n heap -- )
 | 
					
						
							|  |  |  |     over 0 > [ (up-heap) ] [ 2drop ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : (child) ( m heap -- n )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     2dup right-value | 
					
						
							|  |  |  |     >r 2dup left-value r> | 
					
						
							|  |  |  |     rot heap-compare | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     [ right ] [ left ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : child ( m heap -- n )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     2dup right-bounds-check? | 
					
						
							|  |  |  |     [ drop left ] [ (child) ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : swap-down ( m heap -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  |     [ child ] 2keep data-exchange ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | DEFER: down-heap | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (down-heap) ( m heap -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     [ child ] 2keep swapd
 | 
					
						
							|  |  |  |     3dup continue? [ | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |         3drop
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     ] [ | 
					
						
							|  |  |  |         [ data-exchange ] 2keep down-heap | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : down-heap ( m heap -- )
 | 
					
						
							|  |  |  |     2dup left-bounds-check? [ 2drop ] [ (down-heap) ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | M: priority-queue heap-push* ( value key heap -- entry )
 | 
					
						
							| 
									
										
										
										
											2008-02-22 17:16:00 -05:00
										 |  |  |     [ <entry> dup ] keep [ data-push ] keep up-heap ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : heap-push ( value key heap -- ) heap-push* drop ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-20 01:06:36 -05:00
										 |  |  | : heap-push-all ( assoc heap -- )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:48:22 -05:00
										 |  |  |     [ swapd heap-push ] curry assoc-each ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | : >entry< ( entry -- key value )
 | 
					
						
							|  |  |  |     { entry-value entry-key } get-slots ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-20 00:34:30 -05:00
										 |  |  | M: priority-queue heap-peek ( heap -- value key )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     data-first >entry< ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-22 17:16:00 -05:00
										 |  |  | : entry>index ( entry heap -- n )
 | 
					
						
							|  |  |  |     over entry-heap eq? [ | 
					
						
							|  |  |  |         "Invalid entry passed to heap-delete" throw
 | 
					
						
							|  |  |  |     ] unless
 | 
					
						
							|  |  |  |     entry-index ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | M: priority-queue heap-delete ( entry heap -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-22 17:16:00 -05:00
										 |  |  |     [ entry>index ] keep
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     2dup heap-size 1- = [ | 
					
						
							|  |  |  |         nip data-pop* | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |         [ nip data-pop ] 2keep
 | 
					
						
							|  |  |  |         [ data-set-nth ] 2keep
 | 
					
						
							|  |  |  |         down-heap | 
					
						
							| 
									
										
										
										
											2007-12-20 00:34:30 -05:00
										 |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  | M: priority-queue heap-pop* ( heap -- )
 | 
					
						
							|  |  |  |     dup data-first swap heap-delete ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 15:16:22 -05:00
										 |  |  | M: priority-queue heap-pop ( heap -- value key )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 18:07:26 -05:00
										 |  |  |     dup data-first [ swap heap-delete ] keep >entry< ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : heap-pop-all ( heap -- alist )
 | 
					
						
							|  |  |  |     [ dup heap-empty? not ] | 
					
						
							|  |  |  |     [ dup heap-pop swap 2array ] | 
					
						
							|  |  |  |     [ ] unfold nip ;
 |