2 % (c) The GRASP Project, Glasgow University, 1994-1995
4 \section[BitSet]{An implementation of very small sets}
6 Bit sets are a fast implementation of sets of integers ranging from 0
7 to one less than the number of bits in a machine word (typically 31).
8 If any element exceeds the maximum value for a particular machine
9 architecture, the results of these operations are undefined. You have
10 been warned. If you put any safety checks in this code, I will have
13 Note: the Yale Haskell implementation won't provide a full 32 bits.
14 However, if you can handle the performance loss, you could change to
15 Integer and get virtually unlimited sets.
20 BitSet, -- abstract type
21 mkBS, listBS, emptyBS, singletonBS,
23 #if ! defined(COMPILING_GHC)
24 , elementBS, intersectBS, isEmptyBS
28 #ifdef __GLASGOW_HASKELL__
30 #elif defined(__YALE_HASKELL__)
31 {-hide import from mkdependHS-}
35 {-hide import from mkdependHS-}
40 #ifdef __GLASGOW_HASKELL__
42 data BitSet = MkBS Word#
45 emptyBS = MkBS (int2Word# 0#)
47 mkBS :: [Int] -> BitSet
48 mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
50 singletonBS :: Int -> BitSet
51 singletonBS x = case x of
52 I# i# -> MkBS ((int2Word# 1#) `shiftL#` i#)
54 unionBS :: BitSet -> BitSet -> BitSet
55 unionBS (MkBS x#) (MkBS y#) = MkBS (x# `or#` y#)
57 minusBS :: BitSet -> BitSet -> BitSet
58 minusBS (MkBS x#) (MkBS y#) = MkBS (x# `and#` (not# y#))
60 #if ! defined(COMPILING_GHC)
62 isEmptyBS :: BitSet -> Bool
68 intersectBS :: BitSet -> BitSet -> BitSet
69 intersectBS (MkBS x#) (MkBS y#) = MkBS (x# `and#` y#)
71 elementBS :: Int -> BitSet -> Bool
72 elementBS x (MkBS s#) = case x of
73 I# i# -> case word2Int# (((int2Word# 1#) `shiftL#` i#) `and#` s#) of
78 listBS :: BitSet -> [Int]
79 listBS s = listify s 0
80 where listify (MkBS s#) n =
83 _ -> let s' = (MkBS (s# `shiftr` 1#))
84 more = listify s' (n + 1)
85 in case word2Int# (s# `and#` (int2Word# 1#)) of
88 # if __GLASGOW_HASKELL__ >= 23
89 shiftr x y = shiftRL# x y
91 shiftr x y = shiftR# x y
94 #elif defined(__YALE_HASKELL__)
96 data BitSet = MkBS Int
101 mkBS :: [Int] -> BitSet
102 mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
104 singletonBS :: Int -> BitSet
105 singletonBS x = MkBS (1 `ashInt` x)
107 unionBS :: BitSet -> BitSet -> BitSet
108 unionBS (MkBS x) (MkBS y) = MkBS (x `logiorInt` y)
110 #if ! defined(COMPILING_GHC)
112 isEmptyBS :: BitSet -> Bool
118 intersectBS :: BitSet -> BitSet -> BitSet
119 intersectBS (MkBS x) (MkBS y) = MkBS (x `logandInt` y)
121 elementBS :: Int -> BitSet -> Bool
122 elementBS x (MkBS s) =
123 case logbitpInt x s of
128 minusBS :: BitSet -> BitSet -> BitSet
129 minusBS (MkBS x) (MkBS y) = MkBS (x `logandc2Int` y)
131 -- rewritten to avoid right shifts (which would give nonsense on negative
133 listBS :: BitSet -> [Int]
134 listBS (MkBS s) = listify s 0 1
135 where listify s n m =
138 _ -> let n' = n+1; m' = m+m in
139 case logbitpInt s m of
141 _ -> n : listify (s `logandc2Int` m) n' m'
143 #else /* HBC, perhaps? */
145 data BitSet = MkBS Word
150 mkBS :: [Int] -> BitSet
151 mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
153 singletonBS :: Int -> BitSet
154 singletonBS x = MkBS (1 `bitLsh` x)
156 unionBS :: BitSet -> BitSet -> BitSet
157 unionBS (MkBS x) (MkBS y) = MkBS (x `bitOr` y)
159 #if ! defined(COMPILING_GHC)
161 isEmptyBS :: BitSet -> Bool
167 intersectBS :: BitSet -> BitSet -> BitSet
168 intersectBS (MkBS x) (MkBS y) = MkBS (x `bitAnd` y)
170 elementBS :: Int -> BitSet -> Bool
171 elementBS x (MkBS s) =
172 case (1 `bitLsh` x) `bitAnd` s of
177 minusBS :: BitSet -> BitSet -> BitSet
178 minusBS (MkBS x) (MkBS y) = MkBS (x `bitAnd` (bitCompl y))
180 listBS :: BitSet -> [Int]
181 listBS (MkBS s) = listify s 0
185 _ -> let s' = s `bitRsh` 1
186 more = listify s' (n + 1)
187 in case (s `bitAnd` 1) of