#if __GLASGOW_HASKELL__
#endif
#if !defined(TESTING) && __GLASGOW_HASKELL__ >= 703
#endif
module Data.IntSet.Base (
IntSet(..)
, (\\)
, null
, size
, member
, notMember
, lookupLT
, lookupGT
, lookupLE
, lookupGE
, isSubsetOf
, isProperSubsetOf
, empty
, singleton
, insert
, delete
, union
, unions
, difference
, intersection
, filter
, partition
, split
, splitMember
, map
, foldr
, foldl
, foldr'
, foldl'
, fold
, findMin
, findMax
, deleteMin
, deleteMax
, deleteFindMin
, deleteFindMax
, maxView
, minView
, elems
, toList
, fromList
, toAscList
, toDescList
, fromAscList
, fromDistinctAscList
, showTree
, showTreeWith
, match
, suffixBitMask
, prefixBitMask
, bitmapOf
) where
import Prelude hiding (filter,foldr,foldl,null,map)
import Data.Bits
import qualified Data.List as List
import Data.Monoid (Monoid(..))
import Data.Maybe (fromMaybe)
import Data.Typeable
import Control.DeepSeq (NFData)
#if __GLASGOW_HASKELL__
import Text.Read
import Data.Data (Data(..), mkNoRepType)
#endif
#if __GLASGOW_HASKELL__
import GHC.Exts ( Word(..), Int(..), build )
import GHC.Prim ( uncheckedShiftL#, uncheckedShiftRL#, indexInt8OffAddr# )
#else
import Data.Word
#endif
#if defined(__GLASGOW_HASKELL__)
#include "MachDeps.h"
#endif
#define STRICT_1_OF_2(fn) fn arg _ | arg `seq` False = undefined
#define STRICT_2_OF_2(fn) fn _ arg | arg `seq` False = undefined
#define STRICT_1_OF_3(fn) fn arg _ _ | arg `seq` False = undefined
#define STRICT_2_OF_3(fn) fn _ arg _ | arg `seq` False = undefined
infixl 9 \\
type Nat = Word
natFromInt :: Int -> Nat
natFromInt i = fromIntegral i
intFromNat :: Nat -> Int
intFromNat w = fromIntegral w
shiftRL, shiftLL :: Nat -> Int -> Nat
#if __GLASGOW_HASKELL__
shiftRL (W# x) (I# i) = W# (uncheckedShiftRL# x i)
shiftLL (W# x) (I# i) = W# (uncheckedShiftL# x i)
#else
shiftRL x i = shiftR x i
shiftLL x i = shiftL x i
#endif
(\\) :: IntSet -> IntSet -> IntSet
m1 \\ m2 = difference m1 m2
data IntSet = Bin !Prefix !Mask !IntSet !IntSet
| Tip !Prefix !BitMap
| Nil
type Prefix = Int
type Mask = Int
type BitMap = Word
instance Monoid IntSet where
mempty = empty
mappend = union
mconcat = unions
#if __GLASGOW_HASKELL__
instance Data IntSet where
gfoldl f z is = z fromList `f` (toList is)
toConstr _ = error "toConstr"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNoRepType "Data.IntSet.IntSet"
#endif
null :: IntSet -> Bool
null Nil = True
null _ = False
size :: IntSet -> Int
size t
= case t of
Bin _ _ l r -> size l + size r
Tip _ bm -> bitcount 0 bm
Nil -> 0
member :: Int -> IntSet -> Bool
member x = x `seq` go
where
go (Bin p m l r)
| nomatch x p m = False
| zero x m = go l
| otherwise = go r
go (Tip y bm) = prefixOf x == y && bitmapOf x .&. bm /= 0
go Nil = False
notMember :: Int -> IntSet -> Bool
notMember k = not . member k
lookupLT :: Int -> IntSet -> Maybe Int
lookupLT x t = x `seq` case t of
Bin _ m l r | m < 0 -> if x >= 0 then go r l else go Nil r
_ -> go Nil t
where
go def (Bin p m l r) | nomatch x p m = if x < p then unsafeFindMax def else unsafeFindMax r
| zero x m = go def l
| otherwise = go l r
go def (Tip kx bm) | prefixOf x > kx = Just $ kx + highestBitSet bm
| prefixOf x == kx && maskLT /= 0 = Just $ kx + highestBitSet maskLT
| otherwise = unsafeFindMax def
where maskLT = (bitmapOf x 1) .&. bm
go def Nil = unsafeFindMax def
lookupGT :: Int -> IntSet -> Maybe Int
lookupGT x t = x `seq` case t of
Bin _ m l r | m < 0 -> if x >= 0 then go Nil l else go l r
_ -> go Nil t
where
go def (Bin p m l r) | nomatch x p m = if x < p then unsafeFindMin l else unsafeFindMin def
| zero x m = go r l
| otherwise = go def r
go def (Tip kx bm) | prefixOf x < kx = Just $ kx + lowestBitSet bm
| prefixOf x == kx && maskGT /= 0 = Just $ kx + lowestBitSet maskGT
| otherwise = unsafeFindMin def
where maskGT = ( ((bitmapOf x) `shiftLL` 1)) .&. bm
go def Nil = unsafeFindMin def
lookupLE :: Int -> IntSet -> Maybe Int
lookupLE x t = x `seq` case t of
Bin _ m l r | m < 0 -> if x >= 0 then go r l else go Nil r
_ -> go Nil t
where
go def (Bin p m l r) | nomatch x p m = if x < p then unsafeFindMax def else unsafeFindMax r
| zero x m = go def l
| otherwise = go l r
go def (Tip kx bm) | prefixOf x > kx = Just $ kx + highestBitSet bm
| prefixOf x == kx && maskLE /= 0 = Just $ kx + highestBitSet maskLE
| otherwise = unsafeFindMax def
where maskLE = (((bitmapOf x) `shiftLL` 1) 1) .&. bm
go def Nil = unsafeFindMax def
lookupGE :: Int -> IntSet -> Maybe Int
lookupGE x t = x `seq` case t of
Bin _ m l r | m < 0 -> if x >= 0 then go Nil l else go l r
_ -> go Nil t
where
go def (Bin p m l r) | nomatch x p m = if x < p then unsafeFindMin l else unsafeFindMin def
| zero x m = go r l
| otherwise = go def r
go def (Tip kx bm) | prefixOf x < kx = Just $ kx + lowestBitSet bm
| prefixOf x == kx && maskGE /= 0 = Just $ kx + lowestBitSet maskGE
| otherwise = unsafeFindMin def
where maskGE = ( (bitmapOf x)) .&. bm
go def Nil = unsafeFindMin def
unsafeFindMin :: IntSet -> Maybe Int
unsafeFindMin Nil = Nothing
unsafeFindMin (Tip kx bm) = Just $ kx + lowestBitSet bm
unsafeFindMin (Bin _ _ l _) = unsafeFindMin l
unsafeFindMax :: IntSet -> Maybe Int
unsafeFindMax Nil = Nothing
unsafeFindMax (Tip kx bm) = Just $ kx + highestBitSet bm
unsafeFindMax (Bin _ _ _ r) = unsafeFindMax r
empty :: IntSet
empty
= Nil
singleton :: Int -> IntSet
singleton x
= Tip (prefixOf x) (bitmapOf x)
insert :: Int -> IntSet -> IntSet
insert x = x `seq` insertBM (prefixOf x) (bitmapOf x)
insertBM :: Prefix -> BitMap -> IntSet -> IntSet
insertBM kx bm t = kx `seq` bm `seq`
case t of
Bin p m l r
| nomatch kx p m -> join kx (Tip kx bm) p t
| zero kx m -> Bin p m (insertBM kx bm l) r
| otherwise -> Bin p m l (insertBM kx bm r)
Tip kx' bm'
| kx' == kx -> Tip kx' (bm .|. bm')
| otherwise -> join kx (Tip kx bm) kx' t
Nil -> Tip kx bm
delete :: Int -> IntSet -> IntSet
delete x = x `seq` deleteBM (prefixOf x) (bitmapOf x)
deleteBM :: Prefix -> BitMap -> IntSet -> IntSet
deleteBM kx bm t = kx `seq` bm `seq`
case t of
Bin p m l r
| nomatch kx p m -> t
| zero kx m -> bin p m (deleteBM kx bm l) r
| otherwise -> bin p m l (deleteBM kx bm r)
Tip kx' bm'
| kx' == kx -> tip kx (bm' .&. complement bm)
| otherwise -> t
Nil -> Nil
unions :: [IntSet] -> IntSet
unions xs
= foldlStrict union empty xs
union :: IntSet -> IntSet -> IntSet
union t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
| shorter m1 m2 = union1
| shorter m2 m1 = union2
| p1 == p2 = Bin p1 m1 (union l1 l2) (union r1 r2)
| otherwise = join p1 t1 p2 t2
where
union1 | nomatch p2 p1 m1 = join p1 t1 p2 t2
| zero p2 m1 = Bin p1 m1 (union l1 t2) r1
| otherwise = Bin p1 m1 l1 (union r1 t2)
union2 | nomatch p1 p2 m2 = join p1 t1 p2 t2
| zero p1 m2 = Bin p2 m2 (union t1 l2) r2
| otherwise = Bin p2 m2 l2 (union t1 r2)
union t@(Bin _ _ _ _) (Tip kx bm) = insertBM kx bm t
union t@(Bin _ _ _ _) Nil = t
union (Tip kx bm) t = insertBM kx bm t
union Nil t = t
difference :: IntSet -> IntSet -> IntSet
difference t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
| shorter m1 m2 = difference1
| shorter m2 m1 = difference2
| p1 == p2 = bin p1 m1 (difference l1 l2) (difference r1 r2)
| otherwise = t1
where
difference1 | nomatch p2 p1 m1 = t1
| zero p2 m1 = bin p1 m1 (difference l1 t2) r1
| otherwise = bin p1 m1 l1 (difference r1 t2)
difference2 | nomatch p1 p2 m2 = t1
| zero p1 m2 = difference t1 l2
| otherwise = difference t1 r2
difference t@(Bin _ _ _ _) (Tip kx bm) = deleteBM kx bm t
difference t@(Bin _ _ _ _) Nil = t
difference t1@(Tip kx bm) t2 = differenceTip t2
where differenceTip (Bin p2 m2 l2 r2) | nomatch kx p2 m2 = t1
| zero kx m2 = differenceTip l2
| otherwise = differenceTip r2
differenceTip (Tip kx2 bm2) | kx == kx2 = tip kx (bm .&. complement bm2)
| otherwise = t1
differenceTip Nil = t1
difference Nil _ = Nil
intersection :: IntSet -> IntSet -> IntSet
intersection t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
| shorter m1 m2 = intersection1
| shorter m2 m1 = intersection2
| p1 == p2 = bin p1 m1 (intersection l1 l2) (intersection r1 r2)
| otherwise = Nil
where
intersection1 | nomatch p2 p1 m1 = Nil
| zero p2 m1 = intersection l1 t2
| otherwise = intersection r1 t2
intersection2 | nomatch p1 p2 m2 = Nil
| zero p1 m2 = intersection t1 l2
| otherwise = intersection t1 r2
intersection t1@(Bin _ _ _ _) (Tip kx2 bm2) = intersectBM t1
where intersectBM (Bin p1 m1 l1 r1) | nomatch kx2 p1 m1 = Nil
| zero kx2 m1 = intersectBM l1
| otherwise = intersectBM r1
intersectBM (Tip kx1 bm1) | kx1 == kx2 = tip kx1 (bm1 .&. bm2)
| otherwise = Nil
intersectBM Nil = Nil
intersection (Bin _ _ _ _) Nil = Nil
intersection (Tip kx1 bm1) t2 = intersectBM t2
where intersectBM (Bin p2 m2 l2 r2) | nomatch kx1 p2 m2 = Nil
| zero kx1 m2 = intersectBM l2
| otherwise = intersectBM r2
intersectBM (Tip kx2 bm2) | kx1 == kx2 = tip kx1 (bm1 .&. bm2)
| otherwise = Nil
intersectBM Nil = Nil
intersection Nil _ = Nil
isProperSubsetOf :: IntSet -> IntSet -> Bool
isProperSubsetOf t1 t2
= case subsetCmp t1 t2 of
LT -> True
_ -> False
subsetCmp :: IntSet -> IntSet -> Ordering
subsetCmp t1@(Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)
| shorter m1 m2 = GT
| shorter m2 m1 = case subsetCmpLt of
GT -> GT
_ -> LT
| p1 == p2 = subsetCmpEq
| otherwise = GT
where
subsetCmpLt | nomatch p1 p2 m2 = GT
| zero p1 m2 = subsetCmp t1 l2
| otherwise = subsetCmp t1 r2
subsetCmpEq = case (subsetCmp l1 l2, subsetCmp r1 r2) of
(GT,_ ) -> GT
(_ ,GT) -> GT
(EQ,EQ) -> EQ
_ -> LT
subsetCmp (Bin _ _ _ _) _ = GT
subsetCmp (Tip kx1 bm1) (Tip kx2 bm2)
| kx1 /= kx2 = GT
| bm1 == bm2 = EQ
| bm1 .&. complement bm2 == 0 = LT
| otherwise = GT
subsetCmp t1@(Tip kx _) (Bin p m l r)
| nomatch kx p m = GT
| zero kx m = case subsetCmp t1 l of GT -> GT ; _ -> LT
| otherwise = case subsetCmp t1 r of GT -> GT ; _ -> LT
subsetCmp (Tip _ _) Nil = GT
subsetCmp Nil Nil = EQ
subsetCmp Nil _ = LT
isSubsetOf :: IntSet -> IntSet -> Bool
isSubsetOf t1@(Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)
| shorter m1 m2 = False
| shorter m2 m1 = match p1 p2 m2 && (if zero p1 m2 then isSubsetOf t1 l2
else isSubsetOf t1 r2)
| otherwise = (p1==p2) && isSubsetOf l1 l2 && isSubsetOf r1 r2
isSubsetOf (Bin _ _ _ _) _ = False
isSubsetOf (Tip kx1 bm1) (Tip kx2 bm2) = kx1 == kx2 && bm1 .&. complement bm2 == 0
isSubsetOf t1@(Tip kx _) (Bin p m l r)
| nomatch kx p m = False
| zero kx m = isSubsetOf t1 l
| otherwise = isSubsetOf t1 r
isSubsetOf (Tip _ _) Nil = False
isSubsetOf Nil _ = True
filter :: (Int -> Bool) -> IntSet -> IntSet
filter predicate t
= case t of
Bin p m l r
-> bin p m (filter predicate l) (filter predicate r)
Tip kx bm
-> tip kx (foldl'Bits 0 (bitPred kx) 0 bm)
Nil -> Nil
where bitPred kx bm bi | predicate (kx + bi) = bm .|. bitmapOfSuffix bi
| otherwise = bm
partition :: (Int -> Bool) -> IntSet -> (IntSet,IntSet)
partition predicate t
= case t of
Bin p m l r
-> let (l1,l2) = partition predicate l
(r1,r2) = partition predicate r
in (bin p m l1 r1, bin p m l2 r2)
Tip kx bm
-> let bm1 = foldl'Bits 0 (bitPred kx) 0 bm
in (tip kx bm1, tip kx (bm `xor` bm1))
Nil -> (Nil,Nil)
where bitPred kx bm bi | predicate (kx + bi) = bm .|. bitmapOfSuffix bi
| otherwise = bm
split :: Int -> IntSet -> (IntSet,IntSet)
split x t =
case t of Bin _ m l r | m < 0 -> if x >= 0 then case go x l of (lt, gt) -> (union lt r, gt)
else case go x r of (lt, gt) -> (lt, union gt l)
_ -> go x t
where
go x' t'@(Bin p m l r) | match x' p m = if zero x' m then case go x' l of (lt, gt) -> (lt, union gt r)
else case go x' r of (lt, gt) -> (union lt l, gt)
| otherwise = if x' < p then (Nil, t')
else (t', Nil)
go x' t'@(Tip kx' bm) | kx' > x' = (Nil, t')
| kx' < prefixOf x' = (t', Nil)
| otherwise = (tip kx' (bm .&. lowerBitmap), tip kx' (bm .&. higherBitmap))
where lowerBitmap = bitmapOf x' 1
higherBitmap = complement (lowerBitmap + bitmapOf x')
go _ Nil = (Nil, Nil)
splitMember :: Int -> IntSet -> (IntSet,Bool,IntSet)
splitMember x t =
case t of Bin _ m l r | m < 0 -> if x >= 0 then case go x l of (lt, fnd, gt) -> (union lt r, fnd, gt)
else case go x r of (lt, fnd, gt) -> (lt, fnd, union gt l)
_ -> go x t
where
go x' t'@(Bin p m l r) | match x' p m = if zero x' m then case go x' l of (lt, fnd, gt) -> (lt, fnd, union gt r)
else case go x' r of (lt, fnd, gt) -> (union lt l, fnd, gt)
| otherwise = if x' < p then (Nil, False, t')
else (t', False, Nil)
go x' t'@(Tip kx' bm) | kx' > x' = (Nil, False, t')
| kx' < prefixOf x' = (t', False, Nil)
| otherwise = (tip kx' (bm .&. lowerBitmap), (bm .&. bitmapOfx') /= 0, tip kx' (bm .&. higherBitmap))
where bitmapOfx' = bitmapOf x'
lowerBitmap = bitmapOfx' 1
higherBitmap = complement (lowerBitmap + bitmapOfx')
go _ Nil = (Nil, False, Nil)
maxView :: IntSet -> Maybe (Int, IntSet)
maxView t =
case t of Nil -> Nothing
Bin p m l r | m < 0 -> case go l of (result, l') -> Just (result, bin p m l' r)
_ -> Just (go t)
where
go (Bin p m l r) = case go r of (result, r') -> (result, bin p m l r')
go (Tip kx bm) = case highestBitSet bm of bi -> (kx + bi, tip kx (bm .&. complement (bitmapOfSuffix bi)))
go Nil = error "maxView Nil"
minView :: IntSet -> Maybe (Int, IntSet)
minView t =
case t of Nil -> Nothing
Bin p m l r | m < 0 -> case go r of (result, r') -> Just (result, bin p m l r')
_ -> Just (go t)
where
go (Bin p m l r) = case go l of (result, l') -> (result, bin p m l' r)
go (Tip kx bm) = case lowestBitSet bm of bi -> (kx + bi, tip kx (bm .&. complement (bitmapOfSuffix bi)))
go Nil = error "minView Nil"
deleteFindMin :: IntSet -> (Int, IntSet)
deleteFindMin = fromMaybe (error "deleteFindMin: empty set has no minimal element") . minView
deleteFindMax :: IntSet -> (Int, IntSet)
deleteFindMax = fromMaybe (error "deleteFindMax: empty set has no maximal element") . maxView
findMin :: IntSet -> Int
findMin Nil = error "findMin: empty set has no minimal element"
findMin (Tip kx bm) = kx + lowestBitSet bm
findMin (Bin _ m l r)
| m < 0 = find r
| otherwise = find l
where find (Tip kx bm) = kx + lowestBitSet bm
find (Bin _ _ l' _) = find l'
find Nil = error "findMin Nil"
findMax :: IntSet -> Int
findMax Nil = error "findMax: empty set has no maximal element"
findMax (Tip kx bm) = kx + highestBitSet bm
findMax (Bin _ m l r)
| m < 0 = find l
| otherwise = find r
where find (Tip kx bm) = kx + highestBitSet bm
find (Bin _ _ _ r') = find r'
find Nil = error "findMax Nil"
deleteMin :: IntSet -> IntSet
deleteMin = maybe Nil snd . minView
deleteMax :: IntSet -> IntSet
deleteMax = maybe Nil snd . maxView
map :: (Int->Int) -> IntSet -> IntSet
map f = fromList . List.map f . toList
fold :: (Int -> b -> b) -> b -> IntSet -> b
fold = foldr
foldr :: (Int -> b -> b) -> b -> IntSet -> b
foldr f z = \t ->
case t of Bin _ m l r | m < 0 -> go (go z l) r
| otherwise -> go (go z r) l
_ -> go z t
where
go z' Nil = z'
go z' (Tip kx bm) = foldrBits kx f z' bm
go z' (Bin _ _ l r) = go (go z' r) l
foldr' :: (Int -> b -> b) -> b -> IntSet -> b
foldr' f z = \t ->
case t of Bin _ m l r | m < 0 -> go (go z l) r
| otherwise -> go (go z r) l
_ -> go z t
where
STRICT_1_OF_2(go)
go z' Nil = z'
go z' (Tip kx bm) = foldr'Bits kx f z' bm
go z' (Bin _ _ l r) = go (go z' r) l
foldl :: (a -> Int -> a) -> a -> IntSet -> a
foldl f z = \t ->
case t of Bin _ m l r | m < 0 -> go (go z r) l
| otherwise -> go (go z l) r
_ -> go z t
where
STRICT_1_OF_2(go)
go z' Nil = z'
go z' (Tip kx bm) = foldlBits kx f z' bm
go z' (Bin _ _ l r) = go (go z' l) r
foldl' :: (a -> Int -> a) -> a -> IntSet -> a
foldl' f z = \t ->
case t of Bin _ m l r | m < 0 -> go (go z r) l
| otherwise -> go (go z l) r
_ -> go z t
where
STRICT_1_OF_2(go)
go z' Nil = z'
go z' (Tip kx bm) = foldl'Bits kx f z' bm
go z' (Bin _ _ l r) = go (go z' l) r
elems :: IntSet -> [Int]
elems
= toAscList
toList :: IntSet -> [Int]
toList
= toAscList
toAscList :: IntSet -> [Int]
toAscList = foldr (:) []
toDescList :: IntSet -> [Int]
toDescList = foldl (flip (:)) []
#if __GLASGOW_HASKELL__
foldrFB :: (Int -> b -> b) -> b -> IntSet -> b
foldrFB = foldr
foldlFB :: (a -> Int -> a) -> a -> IntSet -> a
foldlFB = foldl
#endif
fromList :: [Int] -> IntSet
fromList xs
= foldlStrict ins empty xs
where
ins t x = insert x t
fromAscList :: [Int] -> IntSet
fromAscList [] = Nil
fromAscList (x0 : xs0) = fromDistinctAscList (combineEq x0 xs0)
where
combineEq x' [] = [x']
combineEq x' (x:xs)
| x==x' = combineEq x' xs
| otherwise = x' : combineEq x xs
fromDistinctAscList :: [Int] -> IntSet
fromDistinctAscList [] = Nil
fromDistinctAscList (z0 : zs0) = work (prefixOf z0) (bitmapOf z0) zs0 Nada
where
work kx bm [] stk = finish kx (Tip kx bm) stk
work kx bm (z:zs) stk | kx == prefixOf z = work kx (bm .|. bitmapOf z) zs stk
work kx bm (z:zs) stk = reduce z zs (branchMask z kx) kx (Tip kx bm) stk
reduce z zs _ px tx Nada = work (prefixOf z) (bitmapOf z) zs (Push px tx Nada)
reduce z zs m px tx stk@(Push py ty stk') =
let mxy = branchMask px py
pxy = mask px mxy
in if shorter m mxy
then reduce z zs m pxy (Bin pxy mxy ty tx) stk'
else work (prefixOf z) (bitmapOf z) zs (Push px tx stk)
finish _ t Nada = t
finish px tx (Push py ty stk) = finish p (join py ty px tx) stk
where m = branchMask px py
p = mask px m
data Stack = Push !Prefix !IntSet !Stack | Nada
instance Eq IntSet where
t1 == t2 = equal t1 t2
t1 /= t2 = nequal t1 t2
equal :: IntSet -> IntSet -> Bool
equal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)
= (m1 == m2) && (p1 == p2) && (equal l1 l2) && (equal r1 r2)
equal (Tip kx1 bm1) (Tip kx2 bm2)
= kx1 == kx2 && bm1 == bm2
equal Nil Nil = True
equal _ _ = False
nequal :: IntSet -> IntSet -> Bool
nequal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)
= (m1 /= m2) || (p1 /= p2) || (nequal l1 l2) || (nequal r1 r2)
nequal (Tip kx1 bm1) (Tip kx2 bm2)
= kx1 /= kx2 || bm1 /= bm2
nequal Nil Nil = False
nequal _ _ = True
instance Ord IntSet where
compare s1 s2 = compare (toAscList s1) (toAscList s2)
instance Show IntSet where
showsPrec p xs = showParen (p > 10) $
showString "fromList " . shows (toList xs)
instance Read IntSet where
#ifdef __GLASGOW_HASKELL__
readPrec = parens $ prec 10 $ do
Ident "fromList" <- lexP
xs <- readPrec
return (fromList xs)
readListPrec = readListPrecDefault
#else
readsPrec p = readParen (p > 10) $ \ r -> do
("fromList",s) <- lex r
(xs,t) <- reads s
return (fromList xs,t)
#endif
#include "Typeable.h"
INSTANCE_TYPEABLE0(IntSet,intSetTc,"IntSet")
instance NFData IntSet
showTree :: IntSet -> String
showTree s
= showTreeWith True False s
showTreeWith :: Bool -> Bool -> IntSet -> String
showTreeWith hang wide t
| hang = (showsTreeHang wide [] t) ""
| otherwise = (showsTree wide [] [] t) ""
showsTree :: Bool -> [String] -> [String] -> IntSet -> ShowS
showsTree wide lbars rbars t
= case t of
Bin p m l r
-> showsTree wide (withBar rbars) (withEmpty rbars) r .
showWide wide rbars .
showsBars lbars . showString (showBin p m) . showString "\n" .
showWide wide lbars .
showsTree wide (withEmpty lbars) (withBar lbars) l
Tip kx bm
-> showsBars lbars . showString " " . shows kx . showString " + " .
showsBitMap bm . showString "\n"
Nil -> showsBars lbars . showString "|\n"
showsTreeHang :: Bool -> [String] -> IntSet -> ShowS
showsTreeHang wide bars t
= case t of
Bin p m l r
-> showsBars bars . showString (showBin p m) . showString "\n" .
showWide wide bars .
showsTreeHang wide (withBar bars) l .
showWide wide bars .
showsTreeHang wide (withEmpty bars) r
Tip kx bm
-> showsBars bars . showString " " . shows kx . showString " + " .
showsBitMap bm . showString "\n"
Nil -> showsBars bars . showString "|\n"
showBin :: Prefix -> Mask -> String
showBin _ _
= "*"
showWide :: Bool -> [String] -> String -> String
showWide wide bars
| wide = showString (concat (reverse bars)) . showString "|\n"
| otherwise = id
showsBars :: [String] -> ShowS
showsBars bars
= case bars of
[] -> id
_ -> showString (concat (reverse (tail bars))) . showString node
showsBitMap :: Word -> ShowS
showsBitMap = showString . showBitMap
showBitMap :: Word -> String
showBitMap w = show $ foldrBits 0 (:) [] w
node :: String
node = "+--"
withBar, withEmpty :: [String] -> [String]
withBar bars = "| ":bars
withEmpty bars = " ":bars
join :: Prefix -> IntSet -> Prefix -> IntSet -> IntSet
join p1 t1 p2 t2
| zero p1 m = Bin p m t1 t2
| otherwise = Bin p m t2 t1
where
m = branchMask p1 p2
p = mask p1 m
bin :: Prefix -> Mask -> IntSet -> IntSet -> IntSet
bin _ _ l Nil = l
bin _ _ Nil r = r
bin p m l r = Bin p m l r
tip :: Prefix -> BitMap -> IntSet
tip _ 0 = Nil
tip kx bm = Tip kx bm
suffixBitMask :: Int
suffixBitMask = bitSize (undefined::Word) 1
prefixBitMask :: Int
prefixBitMask = complement suffixBitMask
prefixOf :: Int -> Prefix
prefixOf x = x .&. prefixBitMask
suffixOf :: Int -> Int
suffixOf x = x .&. suffixBitMask
bitmapOfSuffix :: Int -> BitMap
bitmapOfSuffix s = 1 `shiftLL` s
bitmapOf :: Int -> BitMap
bitmapOf x = bitmapOfSuffix (suffixOf x)
zero :: Int -> Mask -> Bool
zero i m
= (natFromInt i) .&. (natFromInt m) == 0
nomatch,match :: Int -> Prefix -> Mask -> Bool
nomatch i p m
= (mask i m) /= p
match i p m
= (mask i m) == p
mask :: Int -> Mask -> Prefix
mask i m
= maskW (natFromInt i) (natFromInt m)
maskW :: Nat -> Nat -> Prefix
maskW i m
= intFromNat (i .&. (complement (m1) `xor` m))
shorter :: Mask -> Mask -> Bool
shorter m1 m2
= (natFromInt m1) > (natFromInt m2)
branchMask :: Prefix -> Prefix -> Mask
branchMask p1 p2
= intFromNat (highestBitMask (natFromInt p1 `xor` natFromInt p2))
highestBitMask :: Nat -> Nat
highestBitMask x0
= case (x0 .|. shiftRL x0 1) of
x1 -> case (x1 .|. shiftRL x1 2) of
x2 -> case (x2 .|. shiftRL x2 4) of
x3 -> case (x3 .|. shiftRL x3 8) of
x4 -> case (x4 .|. shiftRL x4 16) of
#if !(defined(__GLASGOW_HASKELL__) && WORD_SIZE_IN_BITS==32)
x5 -> case (x5 .|. shiftRL x5 32) of
#endif
x6 -> (x6 `xor` (shiftRL x6 1))
lowestBitSet :: Nat -> Int
highestBitSet :: Nat -> Int
foldlBits :: Int -> (a -> Int -> a) -> a -> Nat -> a
foldl'Bits :: Int -> (a -> Int -> a) -> a -> Nat -> a
foldrBits :: Int -> (Int -> a -> a) -> a -> Nat -> a
foldr'Bits :: Int -> (Int -> a -> a) -> a -> Nat -> a
#if defined(__GLASGOW_HASKELL__) && (WORD_SIZE_IN_BITS==32 || WORD_SIZE_IN_BITS==64)
indexOfTheOnlyBit :: Nat -> Int
indexOfTheOnlyBit bitmask =
I# (lsbArray `indexInt8OffAddr#` unboxInt (intFromNat ((bitmask * magic) `shiftRL` offset)))
where unboxInt (I# i) = i
#if WORD_SIZE_IN_BITS==32
magic = 0x077CB531
offset = 27
!lsbArray = "\0\1\28\2\29\14\24\3\30\22\20\15\25\17\4\8\31\27\13\23\21\19\16\7\26\12\18\6\11\5\10\9"#
#else
magic = 0x07EDD5E59A4E28C2
offset = 58
!lsbArray = "\63\0\58\1\59\47\53\2\60\39\48\27\54\33\42\3\61\51\37\40\49\18\28\20\55\30\34\11\43\14\22\4\62\57\46\52\38\26\32\41\50\36\17\19\29\10\13\21\56\45\25\31\35\16\9\12\44\24\15\8\23\7\6\5"#
#endif
lowestBitMask :: Nat -> Nat
lowestBitMask x = x .&. negate x
revNat :: Nat -> Nat
#if WORD_SIZE_IN_BITS==32
revNat x1 = case ((x1 `shiftRL` 1) .&. 0x55555555) .|. ((x1 .&. 0x55555555) `shiftLL` 1) of
x2 -> case ((x2 `shiftRL` 2) .&. 0x33333333) .|. ((x2 .&. 0x33333333) `shiftLL` 2) of
x3 -> case ((x3 `shiftRL` 4) .&. 0x0F0F0F0F) .|. ((x3 .&. 0x0F0F0F0F) `shiftLL` 4) of
x4 -> case ((x4 `shiftRL` 8) .&. 0x00FF00FF) .|. ((x4 .&. 0x00FF00FF) `shiftLL` 8) of
x5 -> ( x5 `shiftRL` 16 ) .|. ( x5 `shiftLL` 16);
#else
revNat x1 = case ((x1 `shiftRL` 1) .&. 0x5555555555555555) .|. ((x1 .&. 0x5555555555555555) `shiftLL` 1) of
x2 -> case ((x2 `shiftRL` 2) .&. 0x3333333333333333) .|. ((x2 .&. 0x3333333333333333) `shiftLL` 2) of
x3 -> case ((x3 `shiftRL` 4) .&. 0x0F0F0F0F0F0F0F0F) .|. ((x3 .&. 0x0F0F0F0F0F0F0F0F) `shiftLL` 4) of
x4 -> case ((x4 `shiftRL` 8) .&. 0x00FF00FF00FF00FF) .|. ((x4 .&. 0x00FF00FF00FF00FF) `shiftLL` 8) of
x5 -> case ((x5 `shiftRL` 16) .&. 0x0000FFFF0000FFFF) .|. ((x5 .&. 0x0000FFFF0000FFFF) `shiftLL` 16) of
x6 -> ( x6 `shiftRL` 32 ) .|. ( x6 `shiftLL` 32);
#endif
lowestBitSet x = indexOfTheOnlyBit (lowestBitMask x)
highestBitSet x = indexOfTheOnlyBit (highestBitMask x)
foldlBits prefix f z bitmap = go bitmap z
where go bm acc | bm == 0 = acc
| otherwise = case lowestBitMask bm of
bitmask -> bitmask `seq` case indexOfTheOnlyBit bitmask of
bi -> bi `seq` go (bm `xor` bitmask) ((f acc) $! (prefix+bi))
foldl'Bits prefix f z bitmap = go bitmap z
where STRICT_2_OF_2(go)
go bm acc | bm == 0 = acc
| otherwise = case lowestBitMask bm of
bitmask -> bitmask `seq` case indexOfTheOnlyBit bitmask of
bi -> bi `seq` go (bm `xor` bitmask) ((f acc) $! (prefix+bi))
foldrBits prefix f z bitmap = go (revNat bitmap) z
where go bm acc | bm == 0 = acc
| otherwise = case lowestBitMask bm of
bitmask -> bitmask `seq` case indexOfTheOnlyBit bitmask of
bi -> bi `seq` go (bm `xor` bitmask) ((f $! (prefix+(WORD_SIZE_IN_BITS1)bi)) acc)
foldr'Bits prefix f z bitmap = go (revNat bitmap) z
where STRICT_2_OF_2(go)
go bm acc | bm == 0 = acc
| otherwise = case lowestBitMask bm of
bitmask -> bitmask `seq` case indexOfTheOnlyBit bitmask of
bi -> bi `seq` go (bm `xor` bitmask) ((f $! (prefix+(WORD_SIZE_IN_BITS1)bi)) acc)
#else
lowestBitSet n0 =
let (n1,b1) = if n0 .&. 0xFFFFFFFF /= 0 then (n0,0) else (n0 `shiftRL` 32, 32)
(n2,b2) = if n1 .&. 0xFFFF /= 0 then (n1,b1) else (n1 `shiftRL` 16, 16+b1)
(n3,b3) = if n2 .&. 0xFF /= 0 then (n2,b2) else (n2 `shiftRL` 8, 8+b2)
(n4,b4) = if n3 .&. 0xF /= 0 then (n3,b3) else (n3 `shiftRL` 4, 4+b3)
(n5,b5) = if n4 .&. 0x3 /= 0 then (n4,b4) else (n4 `shiftRL` 2, 2+b4)
b6 = if n5 .&. 0x1 /= 0 then b5 else 1+b5
in b6
highestBitSet n0 =
let (n1,b1) = if n0 .&. 0xFFFFFFFF00000000 /= 0 then (n0 `shiftRL` 32, 32) else (n0,0)
(n2,b2) = if n1 .&. 0xFFFF0000 /= 0 then (n1 `shiftRL` 16, 16+b1) else (n1,b1)
(n3,b3) = if n2 .&. 0xFF00 /= 0 then (n2 `shiftRL` 8, 8+b2) else (n2,b2)
(n4,b4) = if n3 .&. 0xF0 /= 0 then (n3 `shiftRL` 4, 4+b3) else (n3,b3)
(n5,b5) = if n4 .&. 0xC /= 0 then (n4 `shiftRL` 2, 2+b4) else (n4,b4)
b6 = if n5 .&. 0x2 /= 0 then 1+b5 else b5
in b6
foldlBits prefix f z bm = let lb = lowestBitSet bm
in go (prefix+lb) z (bm `shiftRL` lb)
where STRICT_1_OF_3(go)
go _ acc 0 = acc
go bi acc n | n `testBit` 0 = go (bi + 1) (f acc bi) (n `shiftRL` 1)
| otherwise = go (bi + 1) acc (n `shiftRL` 1)
foldl'Bits prefix f z bm = let lb = lowestBitSet bm
in go (prefix+lb) z (bm `shiftRL` lb)
where STRICT_1_OF_3(go)
STRICT_2_OF_3(go)
go _ acc 0 = acc
go bi acc n | n `testBit` 0 = go (bi + 1) (f acc bi) (n `shiftRL` 1)
| otherwise = go (bi + 1) acc (n `shiftRL` 1)
foldrBits prefix f z bm = let lb = lowestBitSet bm
in go (prefix+lb) (bm `shiftRL` lb)
where STRICT_1_OF_2(go)
go _ 0 = z
go bi n | n `testBit` 0 = f bi (go (bi + 1) (n `shiftRL` 1))
| otherwise = go (bi + 1) (n `shiftRL` 1)
foldr'Bits prefix f z bm = let lb = lowestBitSet bm
in go (prefix+lb) (bm `shiftRL` lb)
where STRICT_1_OF_2(go)
go _ 0 = z
go bi n | n `testBit` 0 = f bi $! go (bi + 1) (n `shiftRL` 1)
| otherwise = go (bi + 1) (n `shiftRL` 1)
#endif
bitcount :: Int -> Word -> Int
bitcount a0 x0 = go a0 x0
where go a 0 = a
go a x = go (a + 1) (x .&. (x1))
foldlStrict :: (a -> b -> a) -> a -> [b] -> a
foldlStrict f = go
where
go z [] = z
go z (x:xs) = let z' = f z x in z' `seq` go z' xs