---------------------------------------------------------------------------- --- Library with an implementation of sets as red-black trees. ---
--- All the operations on sets are generic, i.e., one has to provide
--- an explicit order predicate ("cmp
" below) on elements.
---
--- @author Johannes Koj, Michael Hanus, Bernd Braßel
--- @version May 2003
----------------------------------------------------------------------------
module SetRBT where
import qualified RedBlackTree as RBT
import Maybe (isJust)
----------------------------------------------------------------------------
-- the main interface:
type SetRBT a = RBT.RedBlackTree a
--- Returns an empty set, i.e., an empty red-black tree
--- augmented with an order predicate.
emptySetRBT = RBT.empty (==) (==)
--- Returns true if an element is contained in a (red-black tree) set.
--- @param e - an element to be checked for containment
--- @param s - a set (represented as a red-black tree)
--- @return True if e is contained in s
elemRBT :: a -> SetRBT a -> Bool
elemRBT e = isJust . (RBT.lookup e)
--- Inserts an element into a set if it is not already there.
insertRBT :: a -> SetRBT a -> SetRBT a
insertRBT = RBT.update
--- Inserts an element into a multiset.
--- Thus, the same element can have several occurrences in the multiset.
insertMultiRBT :: a -> SetRBT a -> SetRBT a
insertMultiRBT e = RBT.setInsertEquivalence (==) .
RBT.update e .
RBT.setInsertEquivalence (\ _ _ -> False)
--- delete an element from a set.
--- Deletes only a single element from a multi set
deleteRBT :: a -> SetRBT a -> SetRBT a
deleteRBT = RBT.delete
--- Transforms a (red-black tree) set into an ordered list of its elements.
setRBT2list :: SetRBT a -> [a]
setRBT2list = RBT.tree2list
--- Computes the union of two (red-black tree) sets.
--- This is done by inserting all elements of the first set into the
--- second set.
unionRBT :: SetRBT a -> SetRBT a -> SetRBT a
unionRBT s1 s2 = foldr insertRBT s2 (setRBT2list s1)
--- Computes the intersection of two (red-black tree) sets.
--- This is done by inserting all elements of the first set
--- contained in the second set into a new set, which order
--- is taken from the first set.
intersectRBT :: SetRBT a -> SetRBT a -> SetRBT a
intersectRBT s1 s2 = foldr insertRBT (RBT.newTreeLike s1)
(filter (\e->elemRBT e s2) (setRBT2list s1))
--- Generic sort based on insertion into red-black trees.
--- The first argument is the order for the elements.
sortRBT :: (a->a->Bool) -> [a] -> [a]
sortRBT = RBT.sort