1 ! Copyright (C) 2008 Daniel Ehrenberg.
\r
2 ! See http://factorcode.org/license.txt for BSD license.
\r
3 USING: kernel sequences arrays accessors grouping math.order
\r
4 sorting binary-search math assocs locals namespaces make ;
\r
7 TUPLE: interval-map array ;
\r
11 : find-interval ( key interval-map -- interval-node )
\r
12 [ first <=> ] with search nip ;
\r
14 : interval-contains? ( key interval-node -- ? )
\r
17 : all-intervals ( sequence -- intervals )
\r
18 [ [ dup number? [ dup 2array ] when ] dip ] { } assoc-map-as ;
\r
20 : disjoint? ( node1 node2 -- ? )
\r
21 [ second ] [ first ] bi* < ;
\r
23 : ensure-disjoint ( intervals -- intervals )
\r
24 dup [ disjoint? ] monotonic?
\r
25 [ "Intervals are not disjoint" throw ] unless ;
\r
27 : >intervals ( specification -- intervals )
\r
28 [ suffix ] { } assoc>map concat 3 <groups> ;
\r
32 : interval-at* ( key map -- value ? )
\r
33 [ drop ] [ array>> find-interval ] 2bi
\r
34 [ nip ] [ interval-contains? ] 2bi
\r
35 [ third t ] [ drop f f ] if ;
\r
37 : interval-at ( key map -- value ) interval-at* drop ;
\r
39 : interval-key? ( key map -- ? ) interval-at* nip ;
\r
41 : <interval-map> ( specification -- map )
\r
42 all-intervals [ [ first second ] compare ] sort
\r
43 >intervals ensure-disjoint interval-map boa ;
\r
45 : <interval-set> ( specification -- map )
\r
46 [ dup 2array ] map <interval-map> ;
\r
48 :: coalesce ( alist -- specification )
\r
49 ! Only works with integer keys, because they're discrete
\r
52 alist sort-keys unclip first2 dupd roll
\r
53 [| oldkey oldval key val | ! Underneath is start
\r
56 [ oldkey 2array oldval 2array , key ] unless
\r
58 ] assoc-each [ 2array ] bi@ ,
\r