1
--------------------------------------------------------------------------------
3
Copyright : (c) Daan Leijen 2002
6
Maintainer : daan@cs.uu.nl
7
Stability : provisional
10
An implementation of multi sets on top of the "Map" module. A multi set
11
differs from a /bag/ in the sense that it is represented as a map from elements
12
to occurrence counts instead of retaining all elements. This means that equality
13
on elements should be defined as a /structural/ equality instead of an
14
equivalence relation. If this is not the case, operations that observe the
15
elements, like 'filter' and 'fold', should be used with care.
17
---------------------------------------------------------------------------------}
18
module UU.DData.MultiSet (
20
MultiSet -- instance Eq,Show
77
-- ** Occurrence lists
94
import Prelude hiding (map,filter)
95
import qualified Prelude (map,filter)
97
import qualified UU.DData.Map as M
99
{--------------------------------------------------------------------
101
--------------------------------------------------------------------}
104
-- | /O(n+m)/. See 'difference'.
105
(\\) :: Ord a => MultiSet a -> MultiSet a -> MultiSet a
106
b1 \\ b2 = difference b1 b2
108
{--------------------------------------------------------------------
109
MultiSets are a simple wrapper around Maps, 'Map.Map'
110
--------------------------------------------------------------------}
111
-- | A multi set of values @a@.
112
newtype MultiSet a = MultiSet (M.Map a Int)
114
{--------------------------------------------------------------------
116
--------------------------------------------------------------------}
117
-- | /O(1)/. Is the multi set empty?
118
isEmpty :: MultiSet a -> Bool
122
-- | /O(1)/. Returns the number of distinct elements in the multi set, ie. (@distinctSize mset == Set.size ('toSet' mset)@).
123
distinctSize :: MultiSet a -> Int
124
distinctSize (MultiSet m)
127
-- | /O(n)/. The number of elements in the multi set.
128
size :: MultiSet a -> Int
130
= foldOccur (\x n m -> n+m) 0 b
132
-- | /O(log n)/. Is the element in the multi set?
133
member :: Ord a => a -> MultiSet a -> Bool
137
-- | /O(log n)/. The number of occurrences of an element in the multi set.
138
occur :: Ord a => a -> MultiSet a -> Int
140
= case M.lookup x m of
144
-- | /O(n+m)/. Is this a subset of the multi set?
145
subset :: Ord a => MultiSet a -> MultiSet a -> Bool
146
subset (MultiSet m1) (MultiSet m2)
147
= M.subsetBy (<=) m1 m2
149
-- | /O(n+m)/. Is this a proper subset? (ie. a subset and not equal)
150
properSubset :: Ord a => MultiSet a -> MultiSet a -> Bool
152
| distinctSize b1 == distinctSize b2 = (subset b1 b2) && (b1 /= b2)
153
| distinctSize b1 < distinctSize b2 = (subset b1 b2)
156
{--------------------------------------------------------------------
158
--------------------------------------------------------------------}
159
-- | /O(1)/. Create an empty multi set.
164
-- | /O(1)/. Create a singleton multi set.
165
single :: a -> MultiSet a
167
= MultiSet (M.single x 0)
169
{--------------------------------------------------------------------
171
--------------------------------------------------------------------}
172
-- | /O(log n)/. Insert an element in the multi set.
173
insert :: Ord a => a -> MultiSet a -> MultiSet a
174
insert x (MultiSet m)
175
= MultiSet (M.insertWith (+) x 1 m)
177
-- | /O(min(n,W))/. The expression (@insertMany x count mset@)
178
-- inserts @count@ instances of @x@ in the multi set @mset@.
179
insertMany :: Ord a => a -> Int -> MultiSet a -> MultiSet a
180
insertMany x count (MultiSet m)
181
= MultiSet (M.insertWith (+) x count m)
183
-- | /O(log n)/. Delete a single element.
184
delete :: Ord a => a -> MultiSet a -> MultiSet a
185
delete x (MultiSet m)
186
= MultiSet (M.updateWithKey f x m)
188
f x n | n > 0 = Just (n-1)
189
| otherwise = Nothing
191
-- | /O(log n)/. Delete all occurrences of an element.
192
deleteAll :: Ord a => a -> MultiSet a -> MultiSet a
193
deleteAll x (MultiSet m)
194
= MultiSet (M.delete x m)
196
{--------------------------------------------------------------------
198
--------------------------------------------------------------------}
199
-- | /O(n+m)/. Union of two multisets. The union adds the elements together.
201
-- > MultiSet\> union (fromList [1,1,2]) (fromList [1,2,2,3])
203
union :: Ord a => MultiSet a -> MultiSet a -> MultiSet a
204
union (MultiSet t1) (MultiSet t2)
205
= MultiSet (M.unionWith (+) t1 t2)
207
-- | /O(n+m)/. Intersection of two multisets.
209
-- > MultiSet\> intersection (fromList [1,1,2]) (fromList [1,2,2,3])
211
intersection :: Ord a => MultiSet a -> MultiSet a -> MultiSet a
212
intersection (MultiSet t1) (MultiSet t2)
213
= MultiSet (M.intersectionWith min t1 t2)
215
-- | /O(n+m)/. Difference between two multisets.
217
-- > MultiSet\> difference (fromList [1,1,2]) (fromList [1,2,2,3])
219
difference :: Ord a => MultiSet a -> MultiSet a -> MultiSet a
220
difference (MultiSet t1) (MultiSet t2)
221
= MultiSet (M.differenceWithKey f t1 t2)
223
f x n m | n-m > 0 = Just (n-m)
224
| otherwise = Nothing
226
-- | The union of a list of multisets.
227
unions :: Ord a => [MultiSet a] -> MultiSet a
229
= MultiSet (M.unions [m | MultiSet m <- multisets])
231
{--------------------------------------------------------------------
233
--------------------------------------------------------------------}
234
-- | /O(n)/. Filter all elements that satisfy some predicate.
235
filter :: Ord a => (a -> Bool) -> MultiSet a -> MultiSet a
236
filter p (MultiSet m)
237
= MultiSet (M.filterWithKey (\x n -> p x) m)
239
-- | /O(n)/. Partition the multi set according to some predicate.
240
partition :: Ord a => (a -> Bool) -> MultiSet a -> (MultiSet a,MultiSet a)
241
partition p (MultiSet m)
242
= (MultiSet l,MultiSet r)
244
(l,r) = M.partitionWithKey (\x n -> p x) m
246
{--------------------------------------------------------------------
248
--------------------------------------------------------------------}
249
-- | /O(n)/. Fold over each element in the multi set.
250
fold :: (a -> b -> b) -> b -> MultiSet a -> b
251
fold f z (MultiSet m)
252
= M.foldWithKey apply z m
254
apply x n z | n > 0 = apply x (n-1) (f x z)
257
-- | /O(n)/. Fold over all occurrences of an element at once.
258
foldOccur :: (a -> Int -> b -> b) -> b -> MultiSet a -> b
259
foldOccur f z (MultiSet m)
260
= M.foldWithKey f z m
262
{--------------------------------------------------------------------
264
--------------------------------------------------------------------}
265
-- | /O(log n)/. The minimal element of a multi set.
266
findMin :: MultiSet a -> a
270
-- | /O(log n)/. The maximal element of a multi set.
271
findMax :: MultiSet a -> a
275
-- | /O(log n)/. Delete the minimal element.
276
deleteMin :: MultiSet a -> MultiSet a
277
deleteMin (MultiSet m)
278
= MultiSet (M.updateMin f m)
280
f n | n > 0 = Just (n-1)
281
| otherwise = Nothing
283
-- | /O(log n)/. Delete the maximal element.
284
deleteMax :: MultiSet a -> MultiSet a
285
deleteMax (MultiSet m)
286
= MultiSet (M.updateMax f m)
288
f n | n > 0 = Just (n-1)
289
| otherwise = Nothing
291
-- | /O(log n)/. Delete all occurrences of the minimal element.
292
deleteMinAll :: MultiSet a -> MultiSet a
293
deleteMinAll (MultiSet m)
294
= MultiSet (M.deleteMin m)
296
-- | /O(log n)/. Delete all occurrences of the maximal element.
297
deleteMaxAll :: MultiSet a -> MultiSet a
298
deleteMaxAll (MultiSet m)
299
= MultiSet (M.deleteMax m)
302
{--------------------------------------------------------------------
304
--------------------------------------------------------------------}
305
-- | /O(n)/. The list of elements.
306
elems :: MultiSet a -> [a]
310
{--------------------------------------------------------------------
312
--------------------------------------------------------------------}
313
-- | /O(n)/. Create a list with all elements.
314
toList :: MultiSet a -> [a]
318
-- | /O(n)/. Create an ascending list of all elements.
319
toAscList :: MultiSet a -> [a]
320
toAscList (MultiSet m)
321
= [y | (x,n) <- M.toAscList m, y <- replicate n x]
324
-- | /O(n*log n)/. Create a multi set from a list of elements.
325
fromList :: Ord a => [a] -> MultiSet a
327
= MultiSet (M.fromListWith (+) [(x,1) | x <- xs])
329
-- | /O(n)/. Create a multi set from an ascending list in linear time.
330
fromAscList :: Eq a => [a] -> MultiSet a
332
= MultiSet (M.fromAscListWith (+) [(x,1) | x <- xs])
334
-- | /O(n)/. Create a multi set from an ascending list of distinct elements in linear time.
335
fromDistinctAscList :: [a] -> MultiSet a
336
fromDistinctAscList xs
337
= MultiSet (M.fromDistinctAscList [(x,1) | x <- xs])
339
-- | /O(n)/. Create a list of element\/occurrence pairs.
340
toOccurList :: MultiSet a -> [(a,Int)]
344
-- | /O(n)/. Create an ascending list of element\/occurrence pairs.
345
toAscOccurList :: MultiSet a -> [(a,Int)]
346
toAscOccurList (MultiSet m)
349
-- | /O(n*log n)/. Create a multi set from a list of element\/occurrence pairs.
350
fromOccurList :: Ord a => [(a,Int)] -> MultiSet a
352
= MultiSet (M.fromListWith (+) (Prelude.filter (\(x,i) -> i > 0) xs))
354
-- | /O(n)/. Create a multi set from an ascending list of element\/occurrence pairs.
355
fromAscOccurList :: Ord a => [(a,Int)] -> MultiSet a
357
= MultiSet (M.fromAscListWith (+) (Prelude.filter (\(x,i) -> i > 0) xs))
359
{--------------------------------------------------------------------
361
--------------------------------------------------------------------}
362
-- | /O(1)/. Convert to a 'Map.Map' from elements to number of occurrences.
363
toMap :: MultiSet a -> M.Map a Int
367
-- | /O(n)/. Convert a 'Map.Map' from elements to occurrences into a multi set.
368
fromMap :: Ord a => M.Map a Int -> MultiSet a
370
= MultiSet (M.filter (>0) m)
372
-- | /O(1)/. Convert a 'Map.Map' from elements to occurrences into a multi set.
373
-- Assumes that the 'Map.Map' contains only elements that occur at least once.
374
fromOccurMap :: M.Map a Int -> MultiSet a
378
{--------------------------------------------------------------------
380
--------------------------------------------------------------------}
381
instance Eq a => Eq (MultiSet a) where
382
(MultiSet m1) == (MultiSet m2) = (m1==m2)
384
{--------------------------------------------------------------------
386
--------------------------------------------------------------------}
387
instance Show a => Show (MultiSet a) where
388
showsPrec d b = showSet (toAscList b)
390
showSet :: Show a => [a] -> ShowS
394
= showChar '{' . shows x . showTail xs
396
showTail [] = showChar '}'
397
showTail (x:xs) = showChar ',' . shows x . showTail xs
400
{--------------------------------------------------------------------
402
--------------------------------------------------------------------}
403
-- | /O(n)/. Show the tree structure that implements the 'MultiSet'. The tree
404
-- is shown as a compressed and /hanging/.
405
showTree :: (Show a) => MultiSet a -> String
407
= showTreeWith True False mset
409
-- | /O(n)/. The expression (@showTreeWith hang wide map@) shows
410
-- the tree that implements the multi set. The tree is shown /hanging/ when @hang@ is @True@
411
-- and otherwise as a /rotated/ tree. When @wide@ is @True@ an extra wide version
413
showTreeWith :: Show a => Bool -> Bool -> MultiSet a -> String
414
showTreeWith hang wide (MultiSet m)
415
= M.showTreeWith (\x n -> show x ++ " (" ++ show n ++ ")") hang wide m
418
-- | /O(n)/. Is this a valid multi set?
419
valid :: Ord a => MultiSet a -> Bool
421
= M.valid m && (M.isEmpty (M.filter (<=0) m))