86 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Factor
		
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Factor
		
	
	
| ! Copyright (C) 2009 Slava Pestov.
 | |
| ! See http://factorcode.org/license.txt for BSD license.
 | |
| USING: accessors bit-arrays fry kernel math math.bitwise
 | |
| sequences sequences.private sets ;
 | |
| IN: bit-sets
 | |
| 
 | |
| TUPLE: bit-set { table bit-array read-only } ;
 | |
| 
 | |
| : <bit-set> ( capacity -- bit-set )
 | |
|     <bit-array> bit-set boa ; inline
 | |
| 
 | |
| INSTANCE: bit-set set
 | |
| 
 | |
| M: bit-set in?
 | |
|     over integer? [ table>> ?nth ] [ 2drop f ] if ; inline
 | |
| 
 | |
| M: bit-set adjoin
 | |
|     ! This is allowed to throw an error when the elt couldn't
 | |
|     ! go in the set
 | |
|     [ t ] 2dip table>> set-nth ;
 | |
| 
 | |
| M: bit-set delete
 | |
|     ! This isn't allowed to throw an error if the elt wasn't
 | |
|     ! in the set
 | |
|     over integer? [ [ f ] 2dip table>> ?set-nth ] [ 2drop ] if ;
 | |
| 
 | |
| ! If you do binary set operations with a bit-set, it's expected
 | |
| ! that the other thing can also be represented as a bit-set
 | |
| ! of the same length.
 | |
| <PRIVATE
 | |
| 
 | |
| ERROR: check-bit-set-failed ;
 | |
| 
 | |
| : check-bit-set ( bit-set -- bit-set )
 | |
|     dup bit-set? [ check-bit-set-failed ] unless ; inline
 | |
| 
 | |
| : bit-set-map ( seq1 seq2 quot -- seq )
 | |
|     [ drop [ length ] bi@ [ assert= ] keep ]
 | |
|     [ [ [ underlying>> ] bi@ ] dip 2map ] 3bi
 | |
|     bit-array boa ; inline
 | |
| 
 | |
| : (bit-set-op) ( set1 set2 -- table1 table2 )
 | |
|     [ set-like ] keep [ table>> ] bi@ ; inline
 | |
| 
 | |
| : bit-set-op ( set1 set2 quot: ( a b -- c ) -- bit-set )
 | |
|     [ (bit-set-op) ] dip bit-set-map bit-set boa ; inline
 | |
| 
 | |
| PRIVATE>
 | |
| 
 | |
| M: bit-set union
 | |
|     [ bitor ] bit-set-op ;
 | |
| 
 | |
| M: bit-set intersect
 | |
|     [ bitand ] bit-set-op ;
 | |
| 
 | |
| M: bit-set diff
 | |
|     [ bitnot bitand ] bit-set-op ;
 | |
| 
 | |
| M: bit-set subset?
 | |
|     [ intersect ] keep = ;
 | |
| 
 | |
| M: bit-set members
 | |
|     table>> [ length iota ] keep '[ _ nth-unsafe ] filter ;
 | |
| 
 | |
| <PRIVATE
 | |
| 
 | |
| : bit-set-like ( set bit-set -- bit-set' )
 | |
|     ! Throws an error if there are keys that can't be put
 | |
|     ! in the bit set
 | |
|     over bit-set? [ 2dup [ table>> length ] same? ] [ f ] if
 | |
|     [ drop ] [
 | |
|         [ members ] dip table>> length <bit-set>
 | |
|         [ adjoin-all ] keep
 | |
|     ] if ;
 | |
| 
 | |
| PRIVATE>
 | |
| 
 | |
| M: bit-set set-like
 | |
|     bit-set-like check-bit-set ; inline
 | |
| 
 | |
| M: bit-set clone
 | |
|     table>> clone bit-set boa ;
 | |
| 
 | |
| M: bit-set cardinality
 | |
|     table>> bit-count ;
 |