| 
									
										
										
										
											2009-08-09 04:07:33 -04:00
										 |  |  | ! Copyright (C) 2007, 2009 Slava Pestov, Doug Coleman. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | ! Based on Slate's src/unfinished/interval.slate by Brian Rice. | 
					
						
							| 
									
										
										
										
											2008-06-30 02:44:58 -04:00
										 |  |  | USING: accessors kernel sequences arrays math math.order | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  | combinators combinators.short-circuit generic layouts memoize ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: math.intervals | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  | SYMBOL: empty-interval | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-28 20:02:59 -04:00
										 |  |  | SINGLETON: full-interval | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-30 02:44:58 -04:00
										 |  |  | TUPLE: interval { from read-only } { to read-only } ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-12 04:25:53 -04:00
										 |  |  | : closed-point? ( from to -- ? )
 | 
					
						
							|  |  |  |     2dup [ first ] bi@ number=
 | 
					
						
							|  |  |  |     [ [ second ] both? ] [ 2drop f ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-16 02:12:36 -05:00
										 |  |  | : <interval> ( from to -- interval )
 | 
					
						
							| 
									
										
										
										
											2009-08-12 04:25:53 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ 2dup [ first ] bi@ > ] [ 2drop empty-interval ] } | 
					
						
							|  |  |  |         { [ 2dup [ first ] bi@ number= ] [ | 
					
						
							|  |  |  |             2dup [ second ] both?
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |             [ interval boa ] [ 2drop empty-interval ] if
 | 
					
						
							|  |  |  |         ] } | 
					
						
							| 
									
										
										
										
											2009-08-12 04:25:53 -04:00
										 |  |  |         { [ 2dup [ { -1/0. t } = ] [ { 1/0. t } = ] bi* and ] [ | 
					
						
							|  |  |  |             2drop full-interval | 
					
						
							|  |  |  |         ] } | 
					
						
							|  |  |  |         [ interval boa ] | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-08 16:32:55 -04:00
										 |  |  | : open-point ( n -- endpoint ) f 2array ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-08 16:32:55 -04:00
										 |  |  | : closed-point ( n -- endpoint ) t 2array ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : [a,b] ( a b -- interval )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:20:56 -05:00
										 |  |  |     [ closed-point ] dip closed-point <interval> ; foldable
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (a,b) ( a b -- interval )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:20:56 -05:00
										 |  |  |     [ open-point ] dip open-point <interval> ; foldable
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : [a,b) ( a b -- interval )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:20:56 -05:00
										 |  |  |     [ closed-point ] dip open-point <interval> ; foldable
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (a,b] ( a b -- interval )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:20:56 -05:00
										 |  |  |     [ open-point ] dip closed-point <interval> ; foldable
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-30 02:44:58 -04:00
										 |  |  | : [a,a] ( a -- interval )
 | 
					
						
							|  |  |  |     closed-point dup <interval> ; foldable
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-13 15:47:39 -04:00
										 |  |  | : [-inf,a] ( a -- interval ) -1/0. swap [a,b] ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-13 15:47:39 -04:00
										 |  |  | : [-inf,a) ( a -- interval ) -1/0. swap [a,b) ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-13 15:47:39 -04:00
										 |  |  | : [a,inf] ( a -- interval ) 1/0. [a,b] ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-13 15:47:39 -04:00
										 |  |  | : (a,inf] ( a -- interval ) 1/0. (a,b] ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 02:16:49 -04:00
										 |  |  | MEMO: [0,inf] ( -- interval ) 0 [a,inf] ; foldable
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MEMO: fixnum-interval ( -- interval )
 | 
					
						
							|  |  |  |     most-negative-fixnum most-positive-fixnum [a,b] ; inline
 | 
					
						
							| 
									
										
										
										
											2009-05-07 13:33:31 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-12 04:25:53 -04:00
										 |  |  | MEMO: array-capacity-interval ( -- interval )
 | 
					
						
							|  |  |  |     0 max-array-capacity [a,b] ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  | : [-inf,inf] ( -- interval ) full-interval ; inline
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : compare-endpoints ( p1 p2 quot -- ? )
 | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  |     [ 2dup [ first ] bi@ 2dup ] dip call [ | 
					
						
							|  |  |  |         2drop 2drop t
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  |         number= [ [ second ] bi@ not or ] [ 2drop f ] if
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] if ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 04:07:33 -04:00
										 |  |  | : endpoint= ( p1 p2 -- ? )
 | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  |     { [ [ first ] bi@ number= ] [ [ second ] bi@ eq? ] } 2&& ;
 | 
					
						
							| 
									
										
										
										
											2009-08-09 04:07:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  | : endpoint< ( p1 p2 -- ? )
 | 
					
						
							|  |  |  |     [ < ] compare-endpoints ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  | : endpoint<= ( p1 p2 -- ? )
 | 
					
						
							|  |  |  |     { [ endpoint< ] [ endpoint= ] } 2|| ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  | : endpoint> ( p1 p2 -- ? )
 | 
					
						
							|  |  |  |     [ > ] compare-endpoints ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  | : endpoint>= ( p1 p2 -- ? )
 | 
					
						
							|  |  |  |     { [ endpoint> ] [ endpoint= ] } 2|| ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : endpoint-min ( p1 p2 -- p3 ) [ endpoint< ] most ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : endpoint-max ( p1 p2 -- p3 ) [ endpoint> ] most ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval>points ( int -- from to )
 | 
					
						
							| 
									
										
										
										
											2008-06-30 02:44:58 -04:00
										 |  |  |     [ from>> ] [ to>> ] bi ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  | : points>interval ( seq -- interval nan? )
 | 
					
						
							|  |  |  |     [ first fp-nan? not ] partition
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [ [ ] [ endpoint-min ] map-reduce ] | 
					
						
							|  |  |  |         [ [ ] [ endpoint-max ] map-reduce ] bi
 | 
					
						
							|  |  |  |         <interval> | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     [ empty? not ] | 
					
						
							|  |  |  |     bi* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : nan-ok ( interval nan? -- interval ) drop ; inline
 | 
					
						
							|  |  |  | : nan-not-ok ( interval nan? -- interval ) [ drop full-interval ] when ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (interval-op) ( p1 p2 quot -- p3 )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:20:56 -05:00
										 |  |  |     [ [ first ] [ first ] [ call ] tri* ] | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     [ drop [ second ] both? ] | 
					
						
							|  |  |  |     3bi 2array ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  | : interval-op ( i1 i2 quot -- i3 nan? )
 | 
					
						
							| 
									
										
										
										
											2008-06-30 02:44:58 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         [ [ from>> ] [ from>> ] [ ] tri* (interval-op) ] | 
					
						
							|  |  |  |         [ [ to>>   ] [ from>> ] [ ] tri* (interval-op) ] | 
					
						
							|  |  |  |         [ [ to>>   ] [ to>>   ] [ ] tri* (interval-op) ] | 
					
						
							|  |  |  |         [ [ from>> ] [ to>>   ] [ ] tri* (interval-op) ] | 
					
						
							|  |  |  |     } 3cleave 4array points>interval ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  | : do-empty-interval ( i1 i2 quot -- i3 )
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         { [ pick empty-interval eq? ] [ 2drop ] } | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         { [ over empty-interval eq? ] [ drop nip ] } | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         { [ pick full-interval eq? ] [ 2drop ] } | 
					
						
							|  |  |  |         { [ over full-interval eq? ] [ drop nip ] } | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         [ call ] | 
					
						
							|  |  |  |     } cond ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  | : interval+ ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |     [ [ + ] interval-op nan-ok ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  | : interval- ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |     [ [ - ] interval-op nan-ok ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-intersect ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ over empty-interval eq? ] [ drop ] } | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         { [ dup empty-interval eq? ] [ nip ] } | 
					
						
							|  |  |  |         { [ over full-interval eq? ] [ nip ] } | 
					
						
							|  |  |  |         { [ dup full-interval eq? ] [ drop ] } | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         [ | 
					
						
							| 
									
										
										
										
											2009-02-02 15:26:54 -05:00
										 |  |  |             [ interval>points ] bi@
 | 
					
						
							| 
									
										
										
										
											2008-11-06 12:57:31 -05:00
										 |  |  |             [ [ swap endpoint< ] most ] | 
					
						
							| 
									
										
										
										
											2009-02-02 15:26:54 -05:00
										 |  |  |             [ [ swap endpoint> ] most ] bi-curry* bi*
 | 
					
						
							| 
									
										
										
										
											2008-11-06 12:57:31 -05:00
										 |  |  |             <interval> | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-25 03:07:45 -04:00
										 |  |  | : intervals-intersect? ( i1 i2 -- ? )
 | 
					
						
							|  |  |  |     interval-intersect empty-interval eq? not ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : interval-union ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ over empty-interval eq? ] [ nip ] } | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         { [ dup empty-interval eq? ] [ drop ] } | 
					
						
							|  |  |  |         { [ over full-interval eq? ] [ drop ] } | 
					
						
							|  |  |  |         { [ dup full-interval eq? ] [ nip ] } | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |         [ [ interval>points 2array ] bi@ append points>interval nan-not-ok ] | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-subset? ( i1 i2 -- ? )
 | 
					
						
							|  |  |  |     dupd interval-intersect = ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-contains? ( x int -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-08-26 20:47:55 -04:00
										 |  |  |     dup empty-interval eq? [ 2drop f ] [ | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         dup full-interval eq? [ 2drop t ] [ | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  |             { | 
					
						
							|  |  |  |                 [ from>> first2 [ >= ] [ > ] if ] | 
					
						
							|  |  |  |                 [ to>>   first2 [ <= ] [ < ] if ] | 
					
						
							|  |  |  |             } 2&& | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         ] if
 | 
					
						
							| 
									
										
										
										
											2008-08-26 20:47:55 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-zero? ( int -- ? )
 | 
					
						
							|  |  |  |     0 swap interval-contains? ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-26 01:19:40 -04:00
										 |  |  | : interval* ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |     [ [ [ * ] interval-op nan-ok ] do-empty-interval ] | 
					
						
							| 
									
										
										
										
											2008-08-26 20:47:55 -04:00
										 |  |  |     [ [ interval-zero? ] either? ] | 
					
						
							|  |  |  |     2bi [ 0 [a,a] interval-union ] when ;
 | 
					
						
							| 
									
										
										
										
											2008-08-26 01:19:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-1+ ( i1 -- i2 ) 1 [a,a] interval+ ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-1- ( i1 -- i2 ) -1 [a,a] interval+ ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-neg ( i1 -- i2 ) -1 [a,a] interval* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-bitnot ( i1 -- i2 ) interval-neg interval-1- ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-sq ( i1 -- i2 ) dup interval* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  | : special-interval? ( interval -- ? )
 | 
					
						
							| 
									
										
										
										
											2009-10-28 16:02:00 -04:00
										 |  |  |     { empty-interval full-interval } member-eq? ;
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | : interval-singleton? ( int -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |     dup special-interval? [ | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         drop f
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         interval>points | 
					
						
							| 
									
										
										
										
											2008-11-17 17:20:56 -05:00
										 |  |  |         2dup [ second ] both?
 | 
					
						
							| 
									
										
										
										
											2009-08-09 04:07:33 -04:00
										 |  |  |         [ [ first ] bi@ number= ] | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         [ 2drop f ] if
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-length ( int -- n )
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ dup empty-interval eq? ] [ drop 0 ] } | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         { [ dup full-interval eq? ] [ drop 1/0. ] } | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         [ interval>points [ first ] bi@ swap - ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : interval-closure ( i1 -- i2 )
 | 
					
						
							| 
									
										
										
										
											2008-03-29 21:36:58 -04:00
										 |  |  |     dup [ interval>points [ first ] bi@ [a,b] ] when ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  | : interval-integer-op ( i1 i2 quot -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:20:56 -05:00
										 |  |  |     [ | 
					
						
							|  |  |  |         2dup [ interval>points [ first integer? ] both? ] both?
 | 
					
						
							|  |  |  |     ] dip [ 2drop [-inf,inf] ] if ; inline
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | : interval-shift ( i1 i2 -- i3 )
 | 
					
						
							|  |  |  |     #! Inaccurate; could be tighter | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             [ interval-closure ] bi@
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |             [ shift ] interval-op nan-not-ok | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         ] interval-integer-op | 
					
						
							|  |  |  |     ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-shift-safe ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         dup to>> first 100 > [ | 
					
						
							|  |  |  |             2drop [-inf,inf] | 
					
						
							|  |  |  |         ] [ | 
					
						
							|  |  |  |             interval-shift | 
					
						
							|  |  |  |         ] if
 | 
					
						
							|  |  |  |     ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-max ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2009-08-28 20:02:59 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ over empty-interval eq? ] [ drop ] } | 
					
						
							|  |  |  |         { [ dup empty-interval eq? ] [ nip ] } | 
					
						
							|  |  |  |         { [ 2dup [ full-interval eq? ] both? ] [ drop ] } | 
					
						
							|  |  |  |         { [ over full-interval eq? ] [ nip from>> first [a,inf] ] } | 
					
						
							|  |  |  |         { [ dup full-interval eq? ] [ drop from>> first [a,inf] ] } | 
					
						
							|  |  |  |         [ [ interval-closure ] bi@ [ max ] interval-op nan-not-ok ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-min ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2009-08-28 20:02:59 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ over empty-interval eq? ] [ drop ] } | 
					
						
							|  |  |  |         { [ dup empty-interval eq? ] [ nip ] } | 
					
						
							|  |  |  |         { [ 2dup [ full-interval eq? ] both? ] [ drop ] } | 
					
						
							|  |  |  |         { [ over full-interval eq? ] [ nip to>> first [-inf,a] ] } | 
					
						
							|  |  |  |         { [ dup full-interval eq? ] [ drop to>> first [-inf,a] ] } | 
					
						
							|  |  |  |         [ [ interval-closure ] bi@ [ min ] interval-op nan-not-ok ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-interior ( i1 -- i2 )
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |     dup special-interval? [ | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         interval>points [ first ] bi@ (a,b) | 
					
						
							|  |  |  |     ] unless ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : interval-division-op ( i1 i2 quot -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-08-26 01:19:40 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ 0 pick interval-closure interval-contains? ] [ 3drop [-inf,inf] ] } | 
					
						
							| 
									
										
										
										
											2008-08-26 20:47:55 -04:00
										 |  |  |         { [ pick interval-zero? ] [ call 0 [a,a] interval-union ] } | 
					
						
							| 
									
										
										
										
											2008-08-26 01:19:40 -04:00
										 |  |  |         [ call ] | 
					
						
							|  |  |  |     } cond ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval/ ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |     [ [ [ / ] interval-op nan-not-ok ] interval-division-op ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-06 19:21:34 -04:00
										 |  |  | : interval/-safe ( i1 i2 -- i3 )
 | 
					
						
							|  |  |  |     #! Just a hack to make the compiler work if bootstrap.math | 
					
						
							|  |  |  |     #! is not loaded. | 
					
						
							| 
									
										
										
										
											2011-10-03 18:49:49 -04:00
										 |  |  |     \ integer \ / ?lookup-method [ interval/ ] [ 2drop f ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-07-06 19:21:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : interval/i ( i1 i2 -- i3 )
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         [ | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 [ interval-closure ] bi@
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |                 [ /i ] interval-op nan-not-ok | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |             ] interval-integer-op | 
					
						
							|  |  |  |         ] interval-division-op | 
					
						
							|  |  |  |     ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | : interval/f ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |     [ [ [ /f ] interval-op nan-not-ok ] interval-division-op ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-23 21:11:43 -04:00
										 |  |  | : (interval-abs) ( i1 -- i2 )
 | 
					
						
							|  |  |  |     interval>points [ first2 [ abs ] dip 2array ] bi@ 2array ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | : interval-abs ( i1 -- i2 )
 | 
					
						
							| 
									
										
										
										
											2008-07-23 21:11:43 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ dup empty-interval eq? ] [ ] } | 
					
						
							| 
									
										
										
										
											2009-05-07 13:33:31 -04:00
										 |  |  |         { [ dup full-interval eq? ] [ drop [0,inf] ] } | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  |         { [ 0 over interval-contains? ] [ (interval-abs) { 0 t } suffix points>interval nan-not-ok ] } | 
					
						
							|  |  |  |         [ (interval-abs) points>interval nan-not-ok ] | 
					
						
							| 
									
										
										
										
											2008-07-23 21:11:43 -04:00
										 |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-19 03:32:18 -04:00
										 |  |  | : interval-absq ( i1 -- i2 )
 | 
					
						
							|  |  |  |     interval-abs interval-sq ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : interval-recip ( i1 -- i2 ) 1 [a,a] swap interval/ ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-2/ ( i1 -- i2 ) -1 [a,a] interval-shift ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: incomparable | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | : left-endpoint-< ( i1 i2 -- ? )
 | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         [ swap interval-subset? ] | 
					
						
							|  |  |  |         [ nip interval-singleton? ] | 
					
						
							|  |  |  |         [ [ from>> ] bi@ endpoint= ] | 
					
						
							|  |  |  |     } 2&& ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : right-endpoint-< ( i1 i2 -- ? )
 | 
					
						
							| 
									
										
										
										
											2012-07-17 23:08:12 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         [ interval-subset? ] | 
					
						
							|  |  |  |         [ drop interval-singleton? ] | 
					
						
							|  |  |  |         [ [ to>> ] bi@ endpoint= ] | 
					
						
							|  |  |  |     } 2&& ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-08 16:32:55 -04:00
										 |  |  | : (interval<) ( i1 i2 -- i1 i2 ? )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 17:20:56 -05:00
										 |  |  |     2dup [ from>> ] bi@ endpoint< ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval< ( i1 i2 -- ? )
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         { [ 2dup [ special-interval? ] either? ] [ incomparable ] } | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         { [ 2dup interval-intersect empty-interval eq? ] [ (interval<) ] } | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  |         { [ 2dup left-endpoint-< ] [ f ] } | 
					
						
							|  |  |  |         { [ 2dup right-endpoint-< ] [ f ] } | 
					
						
							| 
									
										
										
										
											2008-04-11 13:53:22 -04:00
										 |  |  |         [ incomparable ] | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  |     } cond 2nip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : left-endpoint-<= ( i1 i2 -- ? )
 | 
					
						
							| 
									
										
										
										
											2009-08-09 04:07:33 -04:00
										 |  |  |     [ from>> ] [ to>> ] bi* endpoint= ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : right-endpoint-<= ( i1 i2 -- ? )
 | 
					
						
							| 
									
										
										
										
											2009-08-09 04:07:33 -04:00
										 |  |  |     [ to>> ] [ from>> ] bi* endpoint= ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval<= ( i1 i2 -- ? )
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |         { [ 2dup [ special-interval? ] either? ] [ incomparable ] } | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         { [ 2dup interval-intersect empty-interval eq? ] [ (interval<) ] } | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  |         { [ 2dup right-endpoint-<= ] [ t ] } | 
					
						
							| 
									
										
										
										
											2008-04-11 13:53:22 -04:00
										 |  |  |         [ incomparable ] | 
					
						
							| 
									
										
										
										
											2008-03-07 22:27:00 -05:00
										 |  |  |     } cond 2nip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval> ( i1 i2 -- ? )
 | 
					
						
							|  |  |  |     swap interval< ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval>= ( i1 i2 -- ? )
 | 
					
						
							|  |  |  |     swap interval<= ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 00:03:45 -04:00
										 |  |  | : interval-mod ( i1 i2 -- i3 )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { [ over empty-interval eq? ] [ swap ] } | 
					
						
							|  |  |  |         { [ dup empty-interval eq? ] [ ] } | 
					
						
							|  |  |  |         { [ dup full-interval eq? ] [ ] } | 
					
						
							|  |  |  |         [ interval-abs to>> first [ neg ] keep (a,b) ] | 
					
						
							|  |  |  |     } cond
 | 
					
						
							|  |  |  |     swap 0 [a,a] interval>= t eq? [ [0,inf] interval-intersect ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 02:16:49 -04:00
										 |  |  | : (rem-range) ( i -- i' ) interval-abs to>> first 0 swap [a,b) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 00:03:45 -04:00
										 |  |  | : interval-rem ( i1 i2 -- i3 )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { [ over empty-interval eq? ] [ drop ] } | 
					
						
							|  |  |  |         { [ dup empty-interval eq? ] [ nip ] } | 
					
						
							| 
									
										
										
										
											2009-08-11 17:49:28 -04:00
										 |  |  |         { [ dup full-interval eq? ] [ 2drop [0,inf] ] } | 
					
						
							|  |  |  |         [ nip (rem-range) ] | 
					
						
							| 
									
										
										
										
											2009-08-10 02:16:49 -04:00
										 |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-23 21:11:43 -04:00
										 |  |  | : interval-bitand-pos ( i1 i2 -- ? )
 | 
					
						
							|  |  |  |     [ to>> first ] bi@ min 0 swap [a,b] ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-bitand-neg ( i1 i2 -- ? )
 | 
					
						
							|  |  |  |     dup from>> first 0 < [ drop ] [ nip ] if
 | 
					
						
							|  |  |  |     0 swap to>> first [a,b] ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interval-nonnegative? ( i -- ? )
 | 
					
						
							|  |  |  |     from>> first 0 >= ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | : interval-bitand ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-07-23 21:11:43 -04:00
										 |  |  |     #! Inaccurate. | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 [ 2dup [ interval-nonnegative? ] both? ] | 
					
						
							|  |  |  |                 [ interval-bitand-pos ] | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 [ 2dup [ interval-nonnegative? ] either? ] | 
					
						
							|  |  |  |                 [ interval-bitand-neg ] | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             [ 2drop [-inf,inf] ] | 
					
						
							|  |  |  |         } cond
 | 
					
						
							|  |  |  |     ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-bitor ( i1 i2 -- i3 )
 | 
					
						
							|  |  |  |     #! Inaccurate. | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-07-23 21:11:43 -04:00
										 |  |  |         2dup [ interval-nonnegative? ] both?
 | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             [ interval>points [ first ] bi@ ] bi@
 | 
					
						
							| 
									
										
										
										
											2008-12-07 20:44:49 -05:00
										 |  |  |             4array supremum 0 swap >integer next-power-of-2 [a,b] | 
					
						
							| 
									
										
										
										
											2008-07-23 21:11:43 -04:00
										 |  |  |         ] [ 2drop [-inf,inf] ] if
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |     ] do-empty-interval ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-bitxor ( i1 i2 -- i3 )
 | 
					
						
							|  |  |  |     #! Inaccurate. | 
					
						
							| 
									
										
										
										
											2008-07-23 21:11:43 -04:00
										 |  |  |     interval-bitor ;
 | 
					
						
							| 
									
										
										
										
											2008-07-22 02:27:39 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-07 20:44:49 -05:00
										 |  |  | : interval-log2 ( i1 -- i2 )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { empty-interval [ empty-interval ] } | 
					
						
							| 
									
										
										
										
											2009-05-07 13:33:31 -04:00
										 |  |  |         { full-interval [ [0,inf] ] } | 
					
						
							| 
									
										
										
										
											2008-12-07 20:44:49 -05:00
										 |  |  |         [ | 
					
						
							|  |  |  |             to>> first 1 max dup most-positive-fixnum >
 | 
					
						
							|  |  |  |             [ drop full-interval interval-log2 ] | 
					
						
							| 
									
										
										
										
											2009-05-06 00:32:23 -04:00
										 |  |  |             [ 1 + >integer log2 0 swap [a,b] ] | 
					
						
							| 
									
										
										
										
											2008-12-07 20:44:49 -05:00
										 |  |  |             if
 | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } case ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : assume< ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |     dup special-interval? [ drop ] [ | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         to>> first [-inf,a) interval-intersect | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : assume<= ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |     dup special-interval? [ drop ] [ | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         to>> first [-inf,a] interval-intersect | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : assume> ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |     dup special-interval? [ drop ] [ | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         from>> first (a,inf] interval-intersect | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : assume>= ( i1 i2 -- i3 )
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |     dup special-interval? [ drop ] [ | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         from>> first [a,inf] interval-intersect | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : integral-closure ( i1 -- i2 )
 | 
					
						
							| 
									
										
										
										
											2008-11-11 09:30:14 -05:00
										 |  |  |     dup special-interval? [ | 
					
						
							| 
									
										
										
										
											2009-05-06 00:32:23 -04:00
										 |  |  |         [ from>> first2 [ 1 + ] unless ] | 
					
						
							|  |  |  |         [ to>> first2 [ 1 - ] unless ] | 
					
						
							| 
									
										
										
										
											2008-07-22 22:04:22 -04:00
										 |  |  |         bi [a,b] | 
					
						
							|  |  |  |     ] unless ;
 |