2 % (c) The GRASP Project, Glasgow University, 1994-1998
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, unitBS,
22 unionBS, minusBS, intBS
25 #ifdef __GLASGOW_HASKELL__
28 #elif defined(__YALE_HASKELL__)
29 {-hide import from mkdependHS-}
33 {-hide import from mkdependHS-}
38 #ifdef __GLASGOW_HASKELL__
40 data BitSet = MkBS Word#
43 emptyBS = MkBS (int2Word# 0#)
45 mkBS :: [Int] -> BitSet
46 mkBS xs = foldr (unionBS . unitBS) emptyBS xs
48 unitBS :: Int -> BitSet
50 I# i# -> MkBS ((int2Word# 1#) `shiftL#` i#)
52 unionBS :: BitSet -> BitSet -> BitSet
53 unionBS (MkBS x#) (MkBS y#) = MkBS (x# `or#` y#)
55 minusBS :: BitSet -> BitSet -> BitSet
56 minusBS (MkBS x#) (MkBS y#) = MkBS (x# `and#` (not# y#))
60 isEmptyBS :: BitSet -> Bool
62 = case word2Int# s# of
66 intersectBS :: BitSet -> BitSet -> BitSet
67 intersectBS (MkBS x#) (MkBS y#) = MkBS (x# `and#` y#)
69 elementBS :: Int -> BitSet -> Bool
70 elementBS x (MkBS s#) = case x of
71 I# i# -> case word2Int# (((int2Word# 1#) `shiftL#` i#) `and#` s#) of
76 listBS :: BitSet -> [Int]
77 listBS s = listify s 0
78 where listify (MkBS s#) n =
81 _ -> let s' = (MkBS (s# `shiftr` 1#))
82 more = listify s' (n + 1)
83 in case word2Int# (s# `and#` (int2Word# 1#)) of
86 shiftr x y = shiftRL# x y
88 -- intBS is a bit naughty.
89 intBS :: BitSet -> Int
90 intBS (MkBS w#) = I# (word2Int# w#)
92 #elif defined(__YALE_HASKELL__)
94 data BitSet = MkBS Int
99 mkBS :: [Int] -> BitSet
100 mkBS xs = foldr (unionBS . unitBS) emptyBS xs
102 unitBS :: Int -> BitSet
103 unitBS x = MkBS (1 `ashInt` x)
105 unionBS :: BitSet -> BitSet -> BitSet
106 unionBS (MkBS x) (MkBS y) = MkBS (x `logiorInt` y)
110 isEmptyBS :: BitSet -> Bool
116 intersectBS :: BitSet -> BitSet -> BitSet
117 intersectBS (MkBS x) (MkBS y) = MkBS (x `logandInt` y)
119 elementBS :: Int -> BitSet -> Bool
121 = case logbitpInt x s of
126 minusBS :: BitSet -> BitSet -> BitSet
127 minusBS (MkBS x) (MkBS y) = MkBS (x `logandc2Int` y)
129 -- rewritten to avoid right shifts (which would give nonsense on negative
131 listBS :: BitSet -> [Int]
132 listBS (MkBS s) = listify s 0 1
133 where listify s n m =
136 _ -> let n' = n+1; m' = m+m in
137 case logbitpInt s m of
139 _ -> n : listify (s `logandc2Int` m) n' m'
141 #else /* HBC, perhaps? */
143 data BitSet = MkBS Word
148 mkBS :: [Int] -> BitSet
149 mkBS xs = foldr (unionBS . unitBS) emptyBS xs
151 unitBS :: Int -> BitSet
152 unitBS x = MkBS (1 `bitLsh` x)
154 unionBS :: BitSet -> BitSet -> BitSet
155 unionBS (MkBS x) (MkBS y) = MkBS (x `bitOr` y)
159 isEmptyBS :: BitSet -> Bool
165 intersectBS :: BitSet -> BitSet -> BitSet
166 intersectBS (MkBS x) (MkBS y) = MkBS (x `bitAnd` y)
168 elementBS :: Int -> BitSet -> Bool
170 = case (1 `bitLsh` x) `bitAnd` s of
175 minusBS :: BitSet -> BitSet -> BitSet
176 minusBS (MkBS x) (MkBS y) = MkBS (x `bitAnd` (bitCompl y))
178 listBS :: BitSet -> [Int]
179 listBS (MkBS s) = listify s 0
183 _ -> let s' = s `bitRsh` 1
184 more = listify s' (n + 1)
185 in case (s `bitAnd` 1) of