1
--------------------------------------------------------------------------------
3
Copyright : (c) Daan Leijen 2002
6
Maintainer : daan@cs.uu.nl
7
Stability : provisional
10
An efficient implementation of bags of integers on top of the "IntMap" module.
12
Many operations have a worst-case complexity of /O(min(n,W))/. This means that the
13
operation can become linear in the number of elements with a maximum of /W/
14
-- the number of bits in an 'Int' (32 or 64). For more information, see
15
the references in the "IntMap" module.
17
---------------------------------------------------------------------------------}
18
module UU.DData.IntBag (
20
IntBag -- instance Eq,Show
69
-- ** Occurrence lists
85
import Prelude hiding (map,filter)
86
import qualified Prelude (map,filter)
88
import qualified UU.DData.IntMap as M
90
{--------------------------------------------------------------------
92
--------------------------------------------------------------------}
95
(\\) :: IntBag -> IntBag -> IntBag
96
b1 \\ b2 = difference b1 b2
98
{--------------------------------------------------------------------
99
IntBags are a simple wrapper around Maps, 'Map.Map'
100
--------------------------------------------------------------------}
101
newtype IntBag = IntBag (M.IntMap Int)
103
{--------------------------------------------------------------------
105
--------------------------------------------------------------------}
106
isEmpty :: IntBag -> Bool
110
distinctSize :: IntBag -> Int
111
distinctSize (IntBag m)
114
size :: IntBag -> Int
116
= foldOccur (\x n m -> n+m) 0 b
118
member :: Int -> IntBag -> Bool
122
occur :: Int -> IntBag -> Int
124
= case M.lookup x m of
128
subset :: IntBag -> IntBag -> Bool
129
subset (IntBag m1) (IntBag m2)
130
= M.subsetBy (<=) m1 m2
132
properSubset :: IntBag -> IntBag -> Bool
134
= subset b1 b2 && (b1 /= b2)
136
{--------------------------------------------------------------------
138
--------------------------------------------------------------------}
143
single :: Int -> IntBag
145
= IntBag (M.single x 0)
147
{--------------------------------------------------------------------
149
--------------------------------------------------------------------}
150
insert :: Int -> IntBag -> IntBag
152
= IntBag (M.insertWith (+) x 1 m)
154
insertMany :: Int -> Int -> IntBag -> IntBag
155
insertMany x count (IntBag m)
156
= IntBag (M.insertWith (+) x count m)
158
delete :: Int -> IntBag -> IntBag
160
= IntBag (M.updateWithKey f x m)
162
f x n | n > 0 = Just (n-1)
163
| otherwise = Nothing
165
deleteAll :: Int -> IntBag -> IntBag
166
deleteAll x (IntBag m)
167
= IntBag (M.delete x m)
169
{--------------------------------------------------------------------
171
--------------------------------------------------------------------}
173
union :: IntBag -> IntBag -> IntBag
174
union (IntBag t1) (IntBag t2)
175
= IntBag (M.unionWith (+) t1 t2)
178
intersection :: IntBag -> IntBag -> IntBag
179
intersection (IntBag t1) (IntBag t2)
180
= IntBag (M.intersectionWith min t1 t2)
183
difference :: IntBag -> IntBag -> IntBag
184
difference (IntBag t1) (IntBag t2)
185
= IntBag (M.differenceWithKey f t1 t2)
187
f x n m | n-m > 0 = Just (n-m)
188
| otherwise = Nothing
190
unions :: [IntBag] -> IntBag
192
= IntBag (M.unions [m | IntBag m <- bags])
194
{--------------------------------------------------------------------
196
--------------------------------------------------------------------}
197
filter :: (Int -> Bool) -> IntBag -> IntBag
199
= IntBag (M.filterWithKey (\x n -> p x) m)
201
partition :: (Int -> Bool) -> IntBag -> (IntBag,IntBag)
202
partition p (IntBag m)
203
= (IntBag l,IntBag r)
205
(l,r) = M.partitionWithKey (\x n -> p x) m
207
{--------------------------------------------------------------------
209
--------------------------------------------------------------------}
210
fold :: (Int -> b -> b) -> b -> IntBag -> b
212
= M.foldWithKey apply z m
214
apply x n z | n > 0 = apply x (n-1) (f x z)
217
foldOccur :: (Int -> Int -> b -> b) -> b -> IntBag -> b
218
foldOccur f z (IntBag m)
219
= M.foldWithKey f z m
221
{--------------------------------------------------------------------
223
--------------------------------------------------------------------}
224
elems :: IntBag -> [Int]
228
{--------------------------------------------------------------------
230
--------------------------------------------------------------------}
231
toList :: IntBag -> [Int]
235
toAscList :: IntBag -> [Int]
237
= [y | (x,n) <- M.toAscList m, y <- replicate n x]
240
fromList :: [Int] -> IntBag
242
= IntBag (M.fromListWith (+) [(x,1) | x <- xs])
244
fromAscList :: [Int] -> IntBag
246
= IntBag (M.fromAscListWith (+) [(x,1) | x <- xs])
248
fromDistinctAscList :: [Int] -> IntBag
249
fromDistinctAscList xs
250
= IntBag (M.fromDistinctAscList [(x,1) | x <- xs])
252
toOccurList :: IntBag -> [(Int,Int)]
256
toAscOccurList :: IntBag -> [(Int,Int)]
257
toAscOccurList (IntBag m)
260
fromOccurList :: [(Int,Int)] -> IntBag
262
= IntBag (M.fromListWith (+) (Prelude.filter (\(x,i) -> i > 0) xs))
264
fromAscOccurList :: [(Int,Int)] -> IntBag
266
= IntBag (M.fromAscListWith (+) (Prelude.filter (\(x,i) -> i > 0) xs))
268
{--------------------------------------------------------------------
270
--------------------------------------------------------------------}
271
toMap :: IntBag -> M.IntMap Int
275
fromMap :: M.IntMap Int -> IntBag
277
= IntBag (M.filter (>0) m)
279
fromOccurMap :: M.IntMap Int -> IntBag
283
{--------------------------------------------------------------------
285
--------------------------------------------------------------------}
286
instance Eq (IntBag) where
287
(IntBag m1) == (IntBag m2) = (m1==m2)
288
(IntBag m1) /= (IntBag m2) = (m1/=m2)
290
{--------------------------------------------------------------------
292
--------------------------------------------------------------------}
293
instance Show (IntBag) where
294
showsPrec d b = showSet (toAscList b)
296
showSet :: Show a => [a] -> ShowS
300
= showChar '{' . shows x . showTail xs
302
showTail [] = showChar '}'
303
showTail (x:xs) = showChar ',' . shows x . showTail xs
306
{--------------------------------------------------------------------
308
--------------------------------------------------------------------}
309
showTree :: IntBag -> String
311
= showTreeWith True False bag
313
showTreeWith :: Bool -> Bool -> IntBag -> String
314
showTreeWith hang wide (IntBag m)
315
= M.showTreeWith hang wide m