| 
									
										
										
										
											2008-07-15 18:16:08 -04:00
										 |  |  | ! Copyright (C) 2008 Daniel Ehrenberg. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: kernel sequences arrays accessors grouping math.order | 
					
						
							| 
									
										
										
										
											2008-09-10 21:07:00 -04:00
										 |  |  | sorting binary-search math assocs locals namespaces make ;
 | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  | IN: interval-maps | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: interval-map array ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-02 22:52:28 -04:00
										 |  |  | : find-interval ( key interval-map -- interval-node )
 | 
					
						
							| 
									
										
										
										
											2008-07-15 18:16:08 -04:00
										 |  |  |     [ first <=> ] with search nip ;
 | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-02 22:52:28 -04:00
										 |  |  | : interval-contains? ( key interval-node -- ? )
 | 
					
						
							|  |  |  |     first2 between? ;
 | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : all-intervals ( sequence -- intervals )
 | 
					
						
							| 
									
										
										
										
											2008-12-03 09:46:16 -05:00
										 |  |  |     [ [ dup number? [ dup 2array ] when ] dip ] { } assoc-map-as ;
 | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-06 17:26:20 -04:00
										 |  |  | : disjoint? ( node1 node2 -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-07-02 22:52:28 -04:00
										 |  |  |     [ second ] [ first ] bi* < ;
 | 
					
						
							| 
									
										
										
										
											2008-05-06 17:26:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  | : ensure-disjoint ( intervals -- intervals )
 | 
					
						
							| 
									
										
										
										
											2008-05-06 17:26:20 -04:00
										 |  |  |     dup [ disjoint? ] monotonic? | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  |     [ "Intervals are not disjoint" throw ] unless ;
 | 
					
						
							| 
									
										
										
										
											2008-05-05 20:52:56 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-09 16:42:02 -04:00
										 |  |  | : >intervals ( specification -- intervals )
 | 
					
						
							| 
									
										
										
										
											2008-07-02 22:52:28 -04:00
										 |  |  |     [ suffix ] { } assoc>map concat 3 <groups> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-at* ( key map -- value ? )
 | 
					
						
							| 
									
										
										
										
											2008-07-02 22:52:28 -04:00
										 |  |  |     [ drop ] [ array>> find-interval ] 2bi
 | 
					
						
							| 
									
										
										
										
											2009-01-23 19:20:47 -05:00
										 |  |  |     [ nip ] [ interval-contains? ] 2bi
 | 
					
						
							|  |  |  |     [ third t ] [ drop f f ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-at ( key map -- value ) interval-at* drop ;
 | 
					
						
							| 
									
										
										
										
											2008-07-02 22:52:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-05 18:38:44 -04:00
										 |  |  | : interval-key? ( key map -- ? ) interval-at* nip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : <interval-map> ( specification -- map )
 | 
					
						
							| 
									
										
										
										
											2008-05-09 16:42:02 -04:00
										 |  |  |     all-intervals [ [ first second ] compare ] sort | 
					
						
							| 
									
										
										
										
											2008-07-02 22:52:28 -04:00
										 |  |  |     >intervals ensure-disjoint interval-map boa ;
 | 
					
						
							| 
									
										
										
										
											2008-05-05 20:52:56 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-24 18:34:01 -04:00
										 |  |  | : <interval-set> ( specification -- map )
 | 
					
						
							|  |  |  |     [ dup 2array ] map <interval-map> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-06 00:46:51 -04:00
										 |  |  | :: coalesce ( alist -- specification )
 | 
					
						
							| 
									
										
										
										
											2008-05-05 20:52:56 -04:00
										 |  |  |     ! Only works with integer keys, because they're discrete | 
					
						
							|  |  |  |     ! Makes 2array keys | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-05-06 00:46:51 -04:00
										 |  |  |         alist sort-keys unclip first2 dupd roll | 
					
						
							| 
									
										
										
										
											2008-05-05 20:52:56 -04:00
										 |  |  |         [| oldkey oldval key val | ! Underneath is start | 
					
						
							|  |  |  |             oldkey 1+ key =
 | 
					
						
							|  |  |  |             oldval val = and
 | 
					
						
							|  |  |  |             [ oldkey 2array oldval 2array , key ] unless
 | 
					
						
							|  |  |  |             key val | 
					
						
							|  |  |  |         ] assoc-each [ 2array ] bi@ , | 
					
						
							|  |  |  |     ] { } make ;
 |