[Haskell-cafe] Collection of sets containing no sets which are a subset of another in the collection

Mark Wassell mwassell at bigpond.net.au
Sat Nov 14 02:21:59 EST 2009


I am looking for a data structure that will represent a collection of 
sets such that no element in the collection is a subset of another set. 
In other words, inserting an element that is already a subset of another 
element will return the original collection, and inserting an element 
that is a superset of any elements will result in a collection with the 
superset added and the subsets removed.

What I have so far is the below but I am wondering if there has been any 
prior work on this (particularly using Haskell but also conceptual 
work). Inserting a set that is a subset is easy to handle, inserting a 
superset and remove subsets of it is a little tricker.



module SetTrie where

-- A set of sets which does not contain elements which are subsets of 
any other element.
-- ie insert a element which is a proper subset of another set returns 
the same set of sets
--    insert a element which is a proper superset of one or more 
elements causes those elements to be removed
--     (and the first element to be added)

import Data.Set hiding (toList,singleton,map,insert)
import Data.Map hiding 
import qualified Data.Map as M (toList,fromList,lookup,insert)
import qualified Data.Set as S (toList,fromList)

-- Normally we would have a flag at a node to indicate a subset is 
there, but we
-- don't store subsets.

data SetTrie a = Leaf [a] | Node (Map a (SetTrie a)) deriving (Show,Eq)

singleton :: Ord a => Set a -> SetTrie a
singleton = Leaf . S.toList

toList' :: Ord a => SetTrie a -> [[a]]
toList' (Leaf xs) = [xs]
toList' (Node m) = concatMap (\(x,y) -> map (x:) (toList' y)) $ M.toList m

toList :: Ord a => SetTrie a -> [Set a]
toList x = map S.fromList $ toList' x

insert :: Ord a => SetTrie a -> Set a -> SetTrie a
insert t s = insert' t $ toAscList s

insert':: Ord a => SetTrie a -> [a] -> SetTrie a
insert' (Leaf (y:ys)) (x:xs) = Node (M.fromList [(y,Leaf ys),(x,Leaf xs)])
insert' (Node m) (x:xs) = case M.lookup x m of
                                 Nothing -> case xs of
                                               [] -> Node $ M.insert x 
(Leaf xs) m
                                               _ ->  Node $ M.insert x 
(Leaf xs) m
                                 Just t' -> case xs of
                                               [] -> Node m
                                               _ ->  Node $ M.insert x 
(insert' t' xs) m

-- removeSubsets ::

-- terminate (Node m) = Node mTrue m
-- terminate (Leaf (x:xs)) = Node True (M.fromList [(x,Leaf xs)])

s1 = fromList [1,2,3,5,2]
s2 = fromList [2,3,5]

t1 = Node (M.fromList [(1,Leaf [2]),(3,Leaf [5]),(2,Node (M.fromList 
[(4,Leaf [6])]))])

t2 = insert (singleton (S.fromList [1])) $ S.fromList [1,2,3]

t3 = insert t1 $ S.fromList [2,4,7]

t4 = insert t2 $ S.fromList [1]

t5 = insert t3 $ S.fromList [2,5]

t6 = insert t5 $ S.fromList [2,4]

-- Now add a superset of everything
t7 = insert (singleton (S.fromList [8])) $ S.fromList [1,2,3,4,5,6,7,8,9]


More information about the Haskell-Cafe mailing list