{-# OPTIONS_GHC -Wunused-imports #-}
module Agda.Utils.SmallSet
( SmallSet()
, SmallSetElement
, Ix
, (\\)
, complement
, delete
, difference
, elems
, empty
, fromList, fromAscList, fromDistinctAscList
, insert
, intersection
, member
, notMember
, null
, singleton
, toList, toAscList
, total
, union
) where
import Prelude hiding (null)
import Control.DeepSeq
import Data.Word (Word64)
import Data.List (foldl')
import Data.Bits hiding (complement)
import qualified Data.Bits as Bits
import Data.Ix
import qualified Agda.Utils.Null as Null
class (Bounded a, Ix a) => SmallSetElement a where
newtype SmallSet a = SmallSet { forall a. SmallSet a -> Word64
theSmallSet :: Word64 }
deriving (SmallSet a -> SmallSet a -> Bool
(SmallSet a -> SmallSet a -> Bool)
-> (SmallSet a -> SmallSet a -> Bool) -> Eq (SmallSet a)
forall a. SmallSet a -> SmallSet a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. SmallSet a -> SmallSet a -> Bool
== :: SmallSet a -> SmallSet a -> Bool
$c/= :: forall a. SmallSet a -> SmallSet a -> Bool
/= :: SmallSet a -> SmallSet a -> Bool
Eq, Eq (SmallSet a)
Eq (SmallSet a) =>
(SmallSet a -> SmallSet a -> Ordering)
-> (SmallSet a -> SmallSet a -> Bool)
-> (SmallSet a -> SmallSet a -> Bool)
-> (SmallSet a -> SmallSet a -> Bool)
-> (SmallSet a -> SmallSet a -> Bool)
-> (SmallSet a -> SmallSet a -> SmallSet a)
-> (SmallSet a -> SmallSet a -> SmallSet a)
-> Ord (SmallSet a)
SmallSet a -> SmallSet a -> Bool
SmallSet a -> SmallSet a -> Ordering
SmallSet a -> SmallSet a -> SmallSet a
forall a. Eq (SmallSet a)
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. SmallSet a -> SmallSet a -> Bool
forall a. SmallSet a -> SmallSet a -> Ordering
forall a. SmallSet a -> SmallSet a -> SmallSet a
$ccompare :: forall a. SmallSet a -> SmallSet a -> Ordering
compare :: SmallSet a -> SmallSet a -> Ordering
$c< :: forall a. SmallSet a -> SmallSet a -> Bool
< :: SmallSet a -> SmallSet a -> Bool
$c<= :: forall a. SmallSet a -> SmallSet a -> Bool
<= :: SmallSet a -> SmallSet a -> Bool
$c> :: forall a. SmallSet a -> SmallSet a -> Bool
> :: SmallSet a -> SmallSet a -> Bool
$c>= :: forall a. SmallSet a -> SmallSet a -> Bool
>= :: SmallSet a -> SmallSet a -> Bool
$cmax :: forall a. SmallSet a -> SmallSet a -> SmallSet a
max :: SmallSet a -> SmallSet a -> SmallSet a
$cmin :: forall a. SmallSet a -> SmallSet a -> SmallSet a
min :: SmallSet a -> SmallSet a -> SmallSet a
Ord, Int -> SmallSet a -> ShowS
[SmallSet a] -> ShowS
SmallSet a -> String
(Int -> SmallSet a -> ShowS)
-> (SmallSet a -> String)
-> ([SmallSet a] -> ShowS)
-> Show (SmallSet a)
forall a. Int -> SmallSet a -> ShowS
forall a. [SmallSet a] -> ShowS
forall a. SmallSet a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> SmallSet a -> ShowS
showsPrec :: Int -> SmallSet a -> ShowS
$cshow :: forall a. SmallSet a -> String
show :: SmallSet a -> String
$cshowList :: forall a. [SmallSet a] -> ShowS
showList :: [SmallSet a] -> ShowS
Show, SmallSet a -> ()
(SmallSet a -> ()) -> NFData (SmallSet a)
forall a. SmallSet a -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall a. SmallSet a -> ()
rnf :: SmallSet a -> ()
NFData)
instance SmallSetElement a => Null.Null (SmallSet a) where
empty :: SmallSet a
empty = SmallSet a
forall a. SmallSetElement a => SmallSet a
empty
null :: SmallSet a -> Bool
null = SmallSet a -> Bool
forall a. SmallSetElement a => SmallSet a -> Bool
null
instance SmallSetElement a => Semigroup (SmallSet a) where
<> :: SmallSet a -> SmallSet a -> SmallSet a
(<>) = SmallSet a -> SmallSet a -> SmallSet a
forall a.
SmallSetElement a =>
SmallSet a -> SmallSet a -> SmallSet a
union
instance SmallSetElement a => Monoid (SmallSet a) where
mempty :: SmallSet a
mempty = SmallSet a
forall a. SmallSetElement a => SmallSet a
empty
null :: SmallSetElement a => SmallSet a -> Bool
null :: forall a. SmallSetElement a => SmallSet a -> Bool
null SmallSet a
s = SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
s Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0
member :: SmallSetElement a => a -> SmallSet a -> Bool
member :: forall a. SmallSetElement a => a -> SmallSet a -> Bool
member a
a SmallSet a
s = SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
s Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` a -> Int
forall a. SmallSetElement a => a -> Int
idx a
a
notMember :: SmallSetElement a => a -> SmallSet a -> Bool
notMember :: forall a. SmallSetElement a => a -> SmallSet a -> Bool
notMember a
a = Bool -> Bool
not (Bool -> Bool) -> (SmallSet a -> Bool) -> SmallSet a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SmallSet a -> Bool
forall a. SmallSetElement a => a -> SmallSet a -> Bool
member a
a
empty :: SmallSetElement a => SmallSet a
empty :: forall a. SmallSetElement a => SmallSet a
empty = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet Word64
0
total :: forall a. SmallSetElement a => SmallSet a
total :: forall a. SmallSetElement a => SmallSet a
total = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet (Word64 -> SmallSet a) -> Word64 -> SmallSet a
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64
forall a. Bits a => a -> a
Bits.complement Word64
0
singleton :: SmallSetElement a => a -> SmallSet a
singleton :: forall a. SmallSetElement a => a -> SmallSet a
singleton a
a = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet (Word64 -> SmallSet a) -> Word64 -> SmallSet a
forall a b. (a -> b) -> a -> b
$ Int -> Word64
forall a. Bits a => Int -> a
bit (a -> Int
forall a. SmallSetElement a => a -> Int
idx a
a)
insert :: SmallSetElement a => a -> SmallSet a -> SmallSet a
insert :: forall a. SmallSetElement a => a -> SmallSet a -> SmallSet a
insert a
a SmallSet a
s = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet (Word64 -> SmallSet a) -> Word64 -> SmallSet a
forall a b. (a -> b) -> a -> b
$ SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
s Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`setBit` a -> Int
forall a. SmallSetElement a => a -> Int
idx a
a
delete :: SmallSetElement a => a -> SmallSet a -> SmallSet a
delete :: forall a. SmallSetElement a => a -> SmallSet a -> SmallSet a
delete a
a SmallSet a
s = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet (Word64 -> SmallSet a) -> Word64 -> SmallSet a
forall a b. (a -> b) -> a -> b
$ SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
s Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`clearBit` a -> Int
forall a. SmallSetElement a => a -> Int
idx a
a
complement :: SmallSetElement a => SmallSet a -> SmallSet a
complement :: forall a. SmallSetElement a => SmallSet a -> SmallSet a
complement = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet (Word64 -> SmallSet a)
-> (SmallSet a -> Word64) -> SmallSet a -> SmallSet a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Word64
forall a. Bits a => a -> a
Bits.complement (Word64 -> Word64)
-> (SmallSet a -> Word64) -> SmallSet a -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet
difference, (\\) :: SmallSetElement a => SmallSet a -> SmallSet a -> SmallSet a
difference :: forall a.
SmallSetElement a =>
SmallSet a -> SmallSet a -> SmallSet a
difference SmallSet a
s SmallSet a
t = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet (Word64 -> SmallSet a) -> Word64 -> SmallSet a
forall a b. (a -> b) -> a -> b
$ SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
s Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64 -> Word64
forall a. Bits a => a -> a
Bits.complement (SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
t)
\\ :: forall a.
SmallSetElement a =>
SmallSet a -> SmallSet a -> SmallSet a
(\\) = SmallSet a -> SmallSet a -> SmallSet a
forall a.
SmallSetElement a =>
SmallSet a -> SmallSet a -> SmallSet a
difference
intersection :: SmallSetElement a => SmallSet a -> SmallSet a -> SmallSet a
intersection :: forall a.
SmallSetElement a =>
SmallSet a -> SmallSet a -> SmallSet a
intersection SmallSet a
s SmallSet a
t = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet (Word64 -> SmallSet a) -> Word64 -> SmallSet a
forall a b. (a -> b) -> a -> b
$ SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
s Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
t
union :: SmallSetElement a => SmallSet a -> SmallSet a -> SmallSet a
union :: forall a.
SmallSetElement a =>
SmallSet a -> SmallSet a -> SmallSet a
union SmallSet a
s SmallSet a
t = Word64 -> SmallSet a
forall a. Word64 -> SmallSet a
SmallSet (Word64 -> SmallSet a) -> Word64 -> SmallSet a
forall a b. (a -> b) -> a -> b
$ SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
s Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
t
elems, toList, toAscList :: SmallSetElement a => SmallSet a -> [a]
elems :: forall a. SmallSetElement a => SmallSet a -> [a]
elems SmallSet a
s = (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (\a
i -> SmallSet a -> Word64
forall a. SmallSet a -> Word64
theSmallSet SmallSet a
s Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
`testBit` a -> Int
forall a. SmallSetElement a => a -> Int
idx a
i) ((a, a) -> [a]
forall a. Ix a => (a, a) -> [a]
range (a, a)
forall a. SmallSetElement a => (a, a)
bounds)
toList :: forall a. SmallSetElement a => SmallSet a -> [a]
toList = SmallSet a -> [a]
forall a. SmallSetElement a => SmallSet a -> [a]
elems
toAscList :: forall a. SmallSetElement a => SmallSet a -> [a]
toAscList = SmallSet a -> [a]
forall a. SmallSetElement a => SmallSet a -> [a]
elems
fromList, fromAscList, fromDistinctAscList :: SmallSetElement a => [a] -> SmallSet a
fromList :: forall a. SmallSetElement a => [a] -> SmallSet a
fromList = (SmallSet a -> a -> SmallSet a) -> SmallSet a -> [a] -> SmallSet a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((a -> SmallSet a -> SmallSet a) -> SmallSet a -> a -> SmallSet a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> SmallSet a -> SmallSet a
forall a. SmallSetElement a => a -> SmallSet a -> SmallSet a
insert) SmallSet a
forall a. SmallSetElement a => SmallSet a
empty
fromAscList :: forall a. SmallSetElement a => [a] -> SmallSet a
fromAscList = [a] -> SmallSet a
forall a. SmallSetElement a => [a] -> SmallSet a
fromList
fromDistinctAscList :: forall a. SmallSetElement a => [a] -> SmallSet a
fromDistinctAscList = [a] -> SmallSet a
forall a. SmallSetElement a => [a] -> SmallSet a
fromList
bounds :: SmallSetElement a => (a, a)
bounds :: forall a. SmallSetElement a => (a, a)
bounds = (a
forall a. Bounded a => a
minBound, a
forall a. Bounded a => a
maxBound)
idx :: SmallSetElement a => a -> Int
idx :: forall a. SmallSetElement a => a -> Int
idx a
a = (a, a) -> a -> Int
forall a. Ix a => (a, a) -> a -> Int
index (a, a)
forall a. SmallSetElement a => (a, a)
bounds a
a