1 ! Copyright (C) 2010 Daniel Ehrenberg
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: assocs hashtables kernel math sequences vectors ;
4 FROM: assocs => change-at ;
9 GENERIC: adjoin ( elt set -- )
10 GENERIC: in? ( elt set -- ? )
11 GENERIC: delete ( elt set -- )
12 GENERIC: set-like ( set exemplar -- set' )
13 GENERIC: fast-set ( set -- set' )
14 GENERIC: members ( set -- seq )
15 GENERIC: union ( set1 set2 -- set )
16 GENERIC: intersect ( set1 set2 -- set )
17 GENERIC: intersects? ( set1 set2 -- ? )
18 GENERIC: diff ( set1 set2 -- set )
19 GENERIC: subset? ( set1 set2 -- ? )
20 GENERIC: set= ( set1 set2 -- ? )
21 GENERIC: duplicates ( set -- seq )
22 GENERIC: all-unique? ( set -- ? )
23 GENERIC: null? ( set -- ? )
24 GENERIC: cardinality ( set -- n )
26 M: f cardinality drop 0 ;
28 ! Defaults for some methods.
29 ! Override them for efficiency
31 M: set null? members null? ; inline
33 M: set cardinality members length ;
35 M: set set-like drop ; inline
39 : ?members ( set -- seq )
40 dup sequence? [ members ] unless ; inline
42 : (union) ( set1 set2 -- seq )
43 [ ?members ] bi@ append ; inline
48 [ (union) ] keep set-like ;
52 : tester ( set -- quot )
53 fast-set [ in? ] curry ; inline
55 : sequence/tester ( set1 set2 -- set1' quot )
56 [ members ] [ tester ] bi* ; inline
58 : small/large ( set1 set2 -- set1' set2' )
59 2dup [ cardinality ] bi@ > [ swap ] when ;
64 [ small/large sequence/tester filter ] keep set-like ;
67 [ sequence/tester [ not ] compose filter ] keep set-like ;
70 small/large sequence/tester any? ;
74 : (subset?) ( set1 set2 -- ? )
75 sequence/tester all? ; inline
80 2dup [ cardinality ] bi@ > [ 2drop f ] [ (subset?) ] if ;
83 2dup [ cardinality ] bi@ eq? [ (subset?) ] [ 2drop f ] if ;
87 M: set duplicates drop f ;
89 M: set all-unique? drop t ;
93 : (pruned) ( elt hash vec -- )
94 3dup drop in? [ 3drop ] [
95 [ drop adjoin ] [ nip push ] 3bi
98 : pruned ( seq -- newseq )
99 [ f fast-set ] [ length <vector> ] bi
100 [ [ (pruned) ] 2curry each ] keep ;
105 INSTANCE: sequence set
111 [ delete ] [ push ] 2bi ;
114 remove! drop ; inline
117 [ members ] dip like ;
120 [ pruned ] keep like ;
125 M: sequence cardinality
126 fast-set cardinality ;
128 : combine ( sets -- set/f )
130 [ [ [ ?members ] map concat ] [ first ] bi set-like ]
133 : gather ( ... seq quot: ( ... elt -- ... elt' ) -- ... newseq )
134 map concat members ; inline
136 : adjoin-at ( value key assoc -- )
137 [ [ f fast-set ] unless* [ adjoin ] keep ] change-at ;
139 : within ( seq set -- subseq )
142 : without ( seq set -- subseq )
143 tester [ not ] compose filter ;
145 : ?adjoin ( elt set -- ? )
146 2dup in? [ 2drop f ] [ adjoin t ] if ; inline
148 ! Temporarily for compatibility
150 : unique ( seq -- assoc )
151 [ dup ] H{ } map>assoc ;
152 : conjoin ( elt assoc -- )
154 : conjoin-at ( value key assoc -- )
155 [ dupd ?set-at ] change-at ;