{-# LANGUAGE MagicHash #-}
{-# LANGUAGE CPP #-}
module Agda.Utils.VarSet
(
VarSet(..)
, empty
, singleton
, fromList
, fromDescList
, full
, range
, insert
, inserts
, insertsDesc
, delete
, null
, member
, lookupMin
, lookupMax
, size
, disjoint
, isSubsetOf
, inRange
, union
, unions
, intersection
, difference
, (\\)
, complement
, split
, filterLT
, filterLE
, filterGT
, filterGE
, foldr
, foldl
, foldr'
, foldl'
, minView
, maxView
, strengthen
, weaken
, toDescList
, toAscList
)
where
#include "MachDeps.h"
import Control.DeepSeq
import Control.Monad
import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import qualified Data.ByteString as BS
import qualified Data.Foldable as Fold
import Data.Hashable
import GHC.Base hiding (empty, foldr)
import GHC.Num.BigNat
import GHC.Num.WordArray
import Debug.Trace
import Prelude (Num(..), Show(..))
import qualified Prelude as P
import Agda.Utils.ByteArray
import Agda.Utils.Word
data VarSet
= VB# ByteArray#
| VS# Word#
byteArrayToVarSet# :: ByteArray# -> VarSet
byteArrayToVarSet# :: ByteArray# -> VarSet
byteArrayToVarSet# ByteArray#
bs =
case ByteArray# -> Int#
bigNatSize# ByteArray#
bs of
Int#
0# -> VarSet
empty
Int#
1# -> Word# -> VarSet
VS# (ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs Int#
0#)
Int#
_ -> ByteArray# -> VarSet
VB# ByteArray#
bs
instance Eq VarSet where
(VS# Word#
xs) == :: VarSet -> VarSet -> Bool
== (VS# Word#
ys) = Int# -> Bool
isTrue# (Word#
xs Word# -> Word# -> Int#
`eqWord#` Word#
ys)
(VB# ByteArray#
_) == (VS# Word#
_) = Bool
False
(VS# Word#
_) == (VB# ByteArray#
_) = Bool
False
(VB# ByteArray#
xs) == (VB# ByteArray#
ys) = ByteArray# -> ByteArray# -> Bool
bigNatEq ByteArray#
xs ByteArray#
ys
instance Ord VarSet where
compare :: VarSet -> VarSet -> Ordering
compare (VS# Word#
xs) (VS# Word#
ys) = Word# -> Word# -> Ordering
compareWord# Word#
xs Word#
ys
compare (VB# ByteArray#
_) (VS# Word#
_) = Ordering
GT
compare (VS# Word#
_) (VB# ByteArray#
_) = Ordering
LT
compare (VB# ByteArray#
xs) (VB# ByteArray#
ys) = ByteArray# -> ByteArray# -> Ordering
bigNatCompare ByteArray#
xs ByteArray#
ys
instance P.Show VarSet where
showsPrec :: Int -> VarSet -> ShowS
showsPrec Int
d VarSet
vs =
Bool -> ShowS -> ShowS
P.showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> ShowS
P.showString String
"fromList " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> ShowS
forall a. Show a => a -> ShowS
P.shows (VarSet -> [Int]
toAscList VarSet
vs)
instance NFData VarSet where
rnf :: VarSet -> ()
rnf (VS# Word#
_) = ()
rnf (VB# ByteArray#
_) = ()
instance Semigroup VarSet where
<> :: VarSet -> VarSet -> VarSet
(<>) = VarSet -> VarSet -> VarSet
union
instance Monoid VarSet where
mempty :: VarSet
mempty = VarSet
empty
instance Hashable VarSet where
hash :: VarSet -> Int
hash (VS# Word#
w) = Int# -> Int
I# (Word# -> Int#
word2Int# Word#
w)
hash (VB# ByteArray#
bs) = ByteArray# -> Int -> Int -> Int
hashByteArray ByteArray#
bs Int
0 (Int# -> Int
I# (ByteArray# -> Int#
sizeofByteArray# ByteArray#
bs))
hashWithSalt :: Int -> VarSet -> Int
hashWithSalt Int
salt (VS# Word#
w) = Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt (Int# -> Int
I# (Word# -> Int#
word2Int# Word#
w)) Int
salt
hashWithSalt Int
salt (VB# ByteArray#
bs) = ByteArray# -> Int -> Int -> Int -> Int
hashByteArrayWithSalt ByteArray#
bs Int
0 (Int# -> Int
I# (ByteArray# -> Int#
sizeofByteArray# ByteArray#
bs)) Int
salt
instance Binary VarSet where
put :: VarSet -> Put
put (VS# Word#
w) = Word8 -> Put
putWord8 Word8
0 Put -> Put -> Put
forall a. Semigroup a => a -> a -> a
<> Word -> Put
forall t. Binary t => t -> Put
put (Word# -> Word
W# Word#
w)
put (VB# ByteArray#
bs) = Word8 -> Put
putWord8 Word8
1 Put -> Put -> Put
forall a. Semigroup a => a -> a -> a
<> Int -> Put
forall t. Binary t => t -> Put
put (Int# -> Int
I# Int#
len) Put -> Put -> Put
forall a. Semigroup a => a -> a -> a
<> Int# -> Put
loop (Int#
len Int# -> Int# -> Int#
-# Int#
1#)
where
len :: Int#
len = ByteArray# -> Int#
bigNatSize# ByteArray#
bs
loop :: Int# -> Put
loop :: Int# -> Put
loop Int#
i =
if Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
>=# Int#
0#) then
Word -> Put
forall t. Binary t => t -> Put
put (Word# -> Word
W# (ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs Int#
i)) Put -> Put -> Put
forall a. Semigroup a => a -> a -> a
<> Int# -> Put
loop (Int#
i Int# -> Int# -> Int#
-# Int#
1#)
else
Put
forall a. Monoid a => a
mempty
get :: Get VarSet
get = do
tag <- forall t. Binary t => Get t
get @Word8
case tag of
Word8
0 -> do
W# w <- forall t. Binary t => Get t
get @Word
pure (VS# w)
Word8
_ -> do
len <- forall t. Binary t => Get t
get @Int
words <- replicateM len (get @Word)
pure (VB# (bigNatFromWordList words))
empty :: VarSet
empty :: VarSet
empty = Word# -> VarSet
VS# Word#
0##
{-# INLINE CONLIKE empty #-}
singleton :: Int -> VarSet
singleton :: Int -> VarSet
singleton (I# Int#
i) =
if Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# WORD_SIZE_IN_BITS#) then
Word# -> VarSet
VS# (Int# -> Word#
uncheckedBitWord# Int#
i)
else
ByteArray# -> VarSet
VB# (Word# -> ByteArray#
bigNatBit# (Int# -> Word#
int2Word# Int#
i))
{-# INLINABLE singleton #-}
fromList :: [Int] -> VarSet
fromList :: [Int] -> VarSet
fromList [Int]
is = [Int] -> VarSet -> VarSet
inserts [Int]
is VarSet
empty
{-# INLINE fromList #-}
fromDescList :: [Int] -> VarSet
fromDescList :: [Int] -> VarSet
fromDescList [Int]
is = [Int] -> VarSet -> VarSet
insertsDesc [Int]
is VarSet
empty
full :: Int -> VarSet
full :: Int -> VarSet
full (I# Int#
n) =
if Int# -> Bool
isTrue# (Int#
n Int# -> Int# -> Int#
<=# Int#
0#) then
VarSet
empty
else if Int# -> Bool
isTrue# (Int#
n Int# -> Int# -> Int#
<# WORD_SIZE_IN_BITS#) then
Word# -> VarSet
VS# (Int# -> Word#
uncheckedWordOnes# Int#
n)
else
ByteArray# -> VarSet
VB# (Int# -> ByteArray#
byteArrayOnes# Int#
n)
{-# INLINABLE full #-}
range :: Int -> Int -> VarSet
range :: Int -> Int -> VarSet
range Int
lo Int
hi =
Int -> VarSet
full Int
hi VarSet -> VarSet -> VarSet
\\ Int -> VarSet
full (Int
lo Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE range #-}
insert :: Int -> VarSet -> VarSet
insert :: Int -> VarSet -> VarSet
insert (I# Int#
i) (VS# Word#
w) =
if Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# WORD_SIZE_IN_BITS#) then
Word# -> VarSet
VS# (Word# -> Int# -> Word#
uncheckedSetBitWord# Word#
w Int#
i)
else
ByteArray# -> VarSet
VB# (ByteArray# -> Word# -> ByteArray#
bigNatSetBit# (Word# -> ByteArray#
bigNatFromWord# Word#
w) (Int# -> Word#
int2Word# Int#
i))
insert (I# Int#
i) (VB# ByteArray#
bs) = ByteArray# -> VarSet
VB# (ByteArray# -> Word# -> ByteArray#
bigNatSetBit# ByteArray#
bs (Int# -> Word#
int2Word# Int#
i))
inserts :: [Int] -> VarSet -> VarSet
inserts :: [Int] -> VarSet -> VarSet
inserts [Int]
xs VarSet
vs = (VarSet -> Int -> VarSet) -> VarSet -> [Int] -> VarSet
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Fold.foldl' ((Int -> VarSet -> VarSet) -> VarSet -> Int -> VarSet
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> VarSet -> VarSet
insert) VarSet
vs [Int]
xs
{-# INLINE inserts #-}
insertsDesc :: [Int] -> VarSet -> VarSet
insertsDesc :: [Int] -> VarSet -> VarSet
insertsDesc [] VarSet
vs = VarSet
vs
insertsDesc (I# Int#
x:[Int]
xs) (VS# Word#
w) | Int# -> Bool
isTrue# (Int#
x Int# -> Int# -> Int#
<# WORD_SIZE_IN_BITS#) = VS# (insertsDescFast# xs (uncheckedSetBitWord# w x))
insertsDesc [Int]
xs VarSet
vs = [Int] -> VarSet -> VarSet
inserts [Int]
xs VarSet
vs
insertsDescFast# :: [Int] -> Word# -> Word#
insertsDescFast# :: [Int] -> Word# -> Word#
insertsDescFast# [] Word#
w = Word#
w
insertsDescFast# (I# Int#
x:[Int]
xs) Word#
w = [Int] -> Word# -> Word#
insertsDescFast# [Int]
xs (Word# -> Int# -> Word#
uncheckedSetBitWord# Word#
w Int#
x)
delete :: Int -> VarSet -> VarSet
delete :: Int -> VarSet -> VarSet
delete (I# Int#
i) vs :: VarSet
vs@(VS# Word#
w) =
if Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# WORD_SIZE_IN_BITS#) then
Word# -> VarSet
VS# (Word# -> Int# -> Word#
uncheckedClearBitWord# Word#
w Int#
i)
else
VarSet
vs
delete (I# Int#
i) (VB# ByteArray#
vs) = ByteArray# -> VarSet
byteArrayToVarSet# (ByteArray# -> Word# -> ByteArray#
bigNatClearBit# ByteArray#
vs (Int# -> Word#
int2Word# Int#
i))
null :: VarSet -> Bool
null :: VarSet -> Bool
null (VS# Word#
0##) = Bool
True
null VarSet
_ = Bool
False
{-# INLINE null #-}
member :: Int -> VarSet -> Bool
member :: Int -> VarSet -> Bool
member (I# Int#
i) (VS# Word#
w) = Int# -> Bool
isTrue# ((Int#
0# Int# -> Int# -> Int#
<=# Int#
i) Int# -> Int# -> Int#
`andI#` (Int#
i Int# -> Int# -> Int#
<# WORD_SIZE_IN_BITS#) `andI#` (uncheckedTestBitWord# w i))
member (I# Int#
i) (VB# ByteArray#
bs) = Int# -> Bool
isTrue# (ByteArray# -> Word# -> Int#
bigNatTestBit# ByteArray#
bs (Int# -> Word#
int2Word# Int#
i))
{-# INLINABLE member #-}
lookupMin :: VarSet -> Maybe Int
lookupMin :: VarSet -> Maybe Int
lookupMin (VS# Word#
w) =
if Int# -> Bool
isTrue# (Word#
w Word# -> Word# -> Int#
`eqWord#` Word#
0##) then
Maybe Int
forall a. Maybe a
Nothing
else
Int -> Maybe Int
forall a. a -> Maybe a
Just (Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
lowestBitWord# Word#
w)))
lookupMin (VB# ByteArray#
bs) = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int# -> Int
I# (Int# -> ByteArray# -> Int#
lookupMinSlow# Int#
0# ByteArray#
bs))
lookupMinSlow# :: Int# -> ByteArray# -> Int#
lookupMinSlow# :: Int# -> ByteArray# -> Int#
lookupMinSlow# Int#
i ByteArray#
bs =
let w :: Word#
w = ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs Int#
i in
if Int# -> Bool
isTrue# (Word# -> Word# -> Int#
eqWord# Word#
w Word#
0##) then
Int# -> ByteArray# -> Int#
lookupMinSlow# (Int#
i Int# -> Int# -> Int#
+# Int#
1#) ByteArray#
bs
else
WORD_SIZE_IN_BITS# *# i +# (word2Int# (lowestBitWord# w))
{-# NOINLINE lookupMinSlow# #-}
lookupMax :: VarSet -> Maybe Int
lookupMax :: VarSet -> Maybe Int
lookupMax (VS# Word#
w) =
if Int# -> Bool
isTrue# (Word#
w Word# -> Word# -> Int#
`eqWord#` Word#
0##) then
Maybe Int
forall a. Maybe a
Nothing
else
Int -> Maybe Int
forall a. a -> Maybe a
Just (Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
highestBitWord# Word#
w)))
lookupMax (VB# ByteArray#
bs) =
let len :: Int#
len = ByteArray# -> Int#
wordArraySize# ByteArray#
bs
in Int -> Maybe Int
forall a. a -> Maybe a
Just (Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
highestBitWord# (ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs (Int#
len Int# -> Int# -> Int#
-# Int#
1#)))))
size :: VarSet -> Int
size :: VarSet -> Int
size (VS# Word#
w) = Int# -> Int
I# (Word# -> Int#
word2Int# (Word# -> Word#
popCnt# Word#
w))
size (VB# ByteArray#
bs) = Int# -> Int
I# (Word# -> Int#
word2Int# (ByteArray# -> Word#
bigNatPopCount# ByteArray#
bs))
{-# INLINABLE size #-}
disjoint :: VarSet -> VarSet -> Bool
disjoint :: VarSet -> VarSet -> Bool
disjoint (VS# Word#
w1) (VS# Word#
w2) = Int# -> Bool
isTrue# (Word# -> Word# -> Int#
disjointWord# Word#
w1 Word#
w2)
disjoint VarSet
vs1 VarSet
vs2 = Int# -> Bool
isTrue# (VarSet -> VarSet -> Int#
disjointSlow# VarSet
vs1 VarSet
vs2)
{-# INLINABLE disjoint #-}
disjointSlow# :: VarSet -> VarSet -> Int#
disjointSlow# :: VarSet -> VarSet -> Int#
disjointSlow# (VS# Word#
w1) (VS# Word#
w2) = Word# -> Word# -> Int#
disjointWord# Word#
w1 Word#
w2
disjointSlow# (VB# ByteArray#
bs1) (VS# Word#
w2) = Word# -> Word# -> Int#
disjointWord# (ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs1 Int#
0#) Word#
w2
disjointSlow# (VS# Word#
w1) (VB# ByteArray#
bs2) = Word# -> Word# -> Int#
disjointWord# (ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs2 Int#
0#) Word#
w1
disjointSlow# (VB# ByteArray#
bs1) (VB# ByteArray#
bs2) = ByteArray# -> ByteArray# -> Int#
byteArrayDisjoint# ByteArray#
bs1 ByteArray#
bs2
{-# NOINLINE disjointSlow# #-}
union :: VarSet -> VarSet -> VarSet
union :: VarSet -> VarSet -> VarSet
union (VS# Word#
w1) (VS# Word#
w2) = Word# -> VarSet
VS# (Word#
w1 Word# -> Word# -> Word#
`or#` Word#
w2)
union VarSet
vs1 VarSet
vs2 = VarSet -> VarSet -> VarSet
unionSlow VarSet
vs1 VarSet
vs2
{-# INLINABLE union #-}
unionSlow :: VarSet -> VarSet -> VarSet
unionSlow :: VarSet -> VarSet -> VarSet
unionSlow (VS# Word#
w1) (VS# Word#
w2) = Word# -> VarSet
VS# (Word#
w1 Word# -> Word# -> Word#
`or#` Word#
w2)
unionSlow (VS# Word#
w1) (VB# ByteArray#
bs2) = ByteArray# -> VarSet
VB# (ByteArray# -> Word# -> ByteArray#
bigNatOrWord# ByteArray#
bs2 Word#
w1)
unionSlow (VB# ByteArray#
bs1) (VS# Word#
w2) = ByteArray# -> VarSet
VB# (ByteArray# -> Word# -> ByteArray#
bigNatOrWord# ByteArray#
bs1 Word#
w2)
unionSlow (VB# ByteArray#
bs1) (VB# ByteArray#
bs2) = ByteArray# -> VarSet
VB# (ByteArray# -> ByteArray# -> ByteArray#
bigNatOr ByteArray#
bs1 ByteArray#
bs2)
{-# NOINLINE unionSlow #-}
unions :: P.Foldable f => f VarSet -> VarSet
unions :: forall (f :: * -> *). Foldable f => f VarSet -> VarSet
unions = (VarSet -> VarSet -> VarSet) -> VarSet -> f VarSet -> VarSet
forall b a. (b -> a -> b) -> b -> f a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Fold.foldl' VarSet -> VarSet -> VarSet
union VarSet
empty
{-# SPECIALIZE unions :: [VarSet] -> VarSet #-}
intersection :: VarSet -> VarSet -> VarSet
intersection :: VarSet -> VarSet -> VarSet
intersection (VS# Word#
w1) (VS# Word#
w2) = Word# -> VarSet
VS# (Word#
w1 Word# -> Word# -> Word#
`and#` Word#
w2)
intersection VarSet
vs1 VarSet
vs2 = VarSet -> VarSet -> VarSet
intersectionSlow VarSet
vs1 VarSet
vs2
{-# INLINABLE intersection #-}
intersectionSlow :: VarSet -> VarSet -> VarSet
intersectionSlow :: VarSet -> VarSet -> VarSet
intersectionSlow (VS# Word#
w1) (VS# Word#
w2) = Word# -> VarSet
VS# (Word#
w1 Word# -> Word# -> Word#
`and#` Word#
w2)
intersectionSlow (VS# Word#
w1) (VB# ByteArray#
bs2) = Word# -> VarSet
VS# (Word#
w1 Word# -> Word# -> Word#
`and#` ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs2 Int#
0#)
intersectionSlow (VB# ByteArray#
bs1) (VS# Word#
w2) = Word# -> VarSet
VS# (ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs1 Int#
0# Word# -> Word# -> Word#
`and#` Word#
w2)
intersectionSlow (VB# ByteArray#
bs1) (VB# ByteArray#
bs2) = ByteArray# -> VarSet
VB# (ByteArray# -> ByteArray# -> ByteArray#
bigNatAnd ByteArray#
bs1 ByteArray#
bs2)
{-# NOINLINE intersectionSlow #-}
difference :: VarSet -> VarSet -> VarSet
difference :: VarSet -> VarSet -> VarSet
difference (VS# Word#
w1) (VS# Word#
w2) = Word# -> VarSet
VS# (Word#
w1 Word# -> Word# -> Word#
`andNot#` Word#
w2)
difference VarSet
vs1 VarSet
vs2 = VarSet -> VarSet -> VarSet
differenceSlow VarSet
vs1 VarSet
vs2
{-# INLINABLE difference #-}
differenceSlow :: VarSet -> VarSet -> VarSet
differenceSlow :: VarSet -> VarSet -> VarSet
differenceSlow (VS# Word#
w1) (VS# Word#
w2) = Word# -> VarSet
VS# (Word#
w1 Word# -> Word# -> Word#
`andNot#` Word#
w2)
differenceSlow (VS# Word#
w1) (VB# ByteArray#
bs2) = Word# -> VarSet
VS# (Word#
w1 Word# -> Word# -> Word#
`andNot#` ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs2 Int#
0#)
differenceSlow (VB# ByteArray#
bs1) (VS# Word#
w2) = ByteArray# -> VarSet
VB# (ByteArray# -> Word# -> ByteArray#
bigNatAndNotWord# ByteArray#
bs1 Word#
w2)
differenceSlow (VB# ByteArray#
bs1) (VB# ByteArray#
bs2) = ByteArray# -> VarSet
byteArrayToVarSet# (ByteArray# -> ByteArray# -> ByteArray#
bigNatAndNot ByteArray#
bs1 ByteArray#
bs2)
{-# NOINLINE differenceSlow #-}
(\\) :: VarSet -> VarSet -> VarSet
\\ :: VarSet -> VarSet -> VarSet
(\\) = VarSet -> VarSet -> VarSet
difference
{-# INLINE (\\) #-}
complement :: Int -> VarSet -> VarSet
complement :: Int -> VarSet -> VarSet
complement Int
n VarSet
vs = Int -> VarSet
full Int
n VarSet -> VarSet -> VarSet
\\ VarSet
vs
{-# INLINE complement #-}
isSubsetOf :: VarSet -> VarSet -> Bool
isSubsetOf :: VarSet -> VarSet -> Bool
isSubsetOf (VS# Word#
w1) (VS# Word#
w2) = Int# -> Bool
isTrue# ((Word#
w1 Word# -> Word# -> Word#
`and#` Word#
w2) Word# -> Word# -> Int#
`eqWord#` Word#
w1)
isSubsetOf VarSet
vs1 VarSet
vs2 = Int# -> Bool
isTrue# (VarSet -> VarSet -> Int#
isSubsetOfSlow# VarSet
vs1 VarSet
vs2)
{-# INLINABLE isSubsetOf #-}
isSubsetOfSlow# :: VarSet -> VarSet -> Int#
isSubsetOfSlow# :: VarSet -> VarSet -> Int#
isSubsetOfSlow# (VS# Word#
w1) (VS# Word#
w2) = (Word#
w1 Word# -> Word# -> Word#
`and#` Word#
w2) Word# -> Word# -> Int#
`eqWord#` Word#
w1
isSubsetOfSlow# (VS# Word#
w1) (VB# ByteArray#
bs2) = (Word#
w1 Word# -> Word# -> Word#
`and#` ByteArray# -> Int# -> Word#
indexWordArray# ByteArray#
bs2 Int#
0#) Word# -> Word# -> Int#
`eqWord#` Word#
w1
isSubsetOfSlow# (VB# ByteArray#
bs1) (VS# Word#
w2) = Int#
0#
isSubsetOfSlow# (VB# ByteArray#
bs1) (VB# ByteArray#
bs2) = ByteArray# -> ByteArray# -> Int#
byteArrayIsSubsetOf# ByteArray#
bs1 ByteArray#
bs2
{-# NOINLINE isSubsetOfSlow# #-}
inRange :: Int -> Int -> VarSet -> Bool
inRange :: Int -> Int -> VarSet -> Bool
inRange Int
lo Int
hi VarSet
vs =
VarSet
vs VarSet -> VarSet -> Bool
`isSubsetOf` Int -> Int -> VarSet
range Int
lo Int
hi
{-# INLINE inRange #-}
split :: Int -> VarSet -> (VarSet, VarSet)
split :: Int -> VarSet -> (VarSet, VarSet)
split Int
n VarSet
vs =
let !lo :: VarSet
lo = VarSet -> VarSet -> VarSet
intersection VarSet
vs (Int -> VarSet
full Int
n)
!hi :: VarSet
hi = VarSet -> VarSet -> VarSet
difference VarSet
vs (Int -> VarSet
full (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
in (VarSet
lo, VarSet
hi)
{-# INLINE split #-}
filterLT :: Int -> VarSet -> VarSet
filterLT :: Int -> VarSet -> VarSet
filterLT Int
n VarSet
vs = VarSet -> VarSet -> VarSet
intersection VarSet
vs (Int -> VarSet
full Int
n)
{-# INLINE filterLT #-}
filterLE :: Int -> VarSet -> VarSet
filterLE :: Int -> VarSet -> VarSet
filterLE Int
n VarSet
vs = VarSet -> VarSet -> VarSet
intersection VarSet
vs (Int -> VarSet
full (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
{-# INLINE filterLE #-}
filterGT :: Int -> VarSet -> VarSet
filterGT :: Int -> VarSet -> VarSet
filterGT Int
n VarSet
vs = VarSet -> VarSet -> VarSet
difference VarSet
vs (Int -> VarSet
full (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
{-# INLINE filterGT #-}
filterGE :: Int -> VarSet -> VarSet
filterGE :: Int -> VarSet -> VarSet
filterGE Int
n VarSet
vs = VarSet -> VarSet -> VarSet
difference VarSet
vs (Int -> VarSet
full Int
n)
{-# INLINE filterGE #-}
foldr :: (Int -> a -> a) -> a -> VarSet -> a
foldr :: forall a. (Int -> a -> a) -> a -> VarSet -> a
foldr Int -> a -> a
f a
a (VS# Word#
w) = (Int -> a -> a) -> a -> Word# -> a
forall a. (Int -> a -> a) -> a -> Word# -> a
wordFoldrBits# Int -> a -> a
f a
a Word#
w
foldr Int -> a -> a
f a
a (VB# ByteArray#
bs) = (Int -> a -> a) -> a -> ByteArray# -> a
forall a. (Int -> a -> a) -> a -> ByteArray# -> a
byteArrayFoldrBits# Int -> a -> a
f a
a ByteArray#
bs
foldl :: (a -> Int -> a) -> a -> VarSet -> a
foldl :: forall a. (a -> Int -> a) -> a -> VarSet -> a
foldl a -> Int -> a
f a
a (VS# Word#
w) = (a -> Int -> a) -> a -> Word# -> a
forall a. (a -> Int -> a) -> a -> Word# -> a
wordFoldlBits# a -> Int -> a
f a
a Word#
w
foldl a -> Int -> a
f a
a (VB# ByteArray#
bs) = (a -> Int -> a) -> a -> ByteArray# -> a
forall a. (a -> Int -> a) -> a -> ByteArray# -> a
byteArrayFoldlBits# a -> Int -> a
f a
a ByteArray#
bs
foldr' :: (Int -> a -> a) -> a -> VarSet -> a
foldr' :: forall a. (Int -> a -> a) -> a -> VarSet -> a
foldr' Int -> a -> a
f a
a (VS# Word#
w) = (Int -> a -> a) -> a -> Word# -> a
forall a. (Int -> a -> a) -> a -> Word# -> a
wordFoldrBitsStrict# Int -> a -> a
f a
a Word#
w
foldr' Int -> a -> a
f a
a (VB# ByteArray#
bs) = (Int -> a -> a) -> a -> ByteArray# -> a
forall a. (Int -> a -> a) -> a -> ByteArray# -> a
byteArrayFoldrBitsStrict# Int -> a -> a
f a
a ByteArray#
bs
foldl' :: (Int -> a -> a) -> a -> VarSet -> a
foldl' :: forall a. (Int -> a -> a) -> a -> VarSet -> a
foldl' Int -> a -> a
f a
a (VS# Word#
w) = (Int -> a -> a) -> a -> Word# -> a
forall a. (Int -> a -> a) -> a -> Word# -> a
wordFoldrBitsStrict# Int -> a -> a
f a
a Word#
w
foldl' Int -> a -> a
f a
a (VB# ByteArray#
bs) = (Int -> a -> a) -> a -> ByteArray# -> a
forall a. (Int -> a -> a) -> a -> ByteArray# -> a
byteArrayFoldrBitsStrict# Int -> a -> a
f a
a ByteArray#
bs
minView :: VarSet -> Maybe (Int, VarSet)
minView :: VarSet -> Maybe (Int, VarSet)
minView VarSet
vs =
case VarSet -> Maybe Int
lookupMin VarSet
vs of
Just Int
i ->
let !vs' :: VarSet
vs' = Int -> VarSet -> VarSet
delete Int
i VarSet
vs
in (Int, VarSet) -> Maybe (Int, VarSet)
forall a. a -> Maybe a
Just (Int
i, VarSet
vs')
Maybe Int
Nothing -> Maybe (Int, VarSet)
forall a. Maybe a
Nothing
{-# INLINABLE minView #-}
maxView :: VarSet -> Maybe (Int, VarSet)
maxView :: VarSet -> Maybe (Int, VarSet)
maxView VarSet
vs =
case VarSet -> Maybe Int
lookupMax VarSet
vs of
Just Int
i ->
let !vs' :: VarSet
vs' = Int -> VarSet -> VarSet
delete Int
i VarSet
vs
in (Int, VarSet) -> Maybe (Int, VarSet)
forall a. a -> Maybe a
Just (Int
i, VarSet
vs')
Maybe Int
Nothing -> Maybe (Int, VarSet)
forall a. Maybe a
Nothing
{-# INLINABLE maxView #-}
strengthen :: Int -> VarSet -> VarSet
strengthen :: Int -> VarSet -> VarSet
strengthen (I# Int#
n) (VS# Word#
w) =
Word# -> VarSet
VS# (Word#
w Word# -> Int# -> Word#
`shiftRL#` Int#
n)
strengthen (I# Int#
n) (VB# ByteArray#
bs) =
ByteArray# -> VarSet
byteArrayToVarSet# (ByteArray# -> Word# -> ByteArray#
bigNatShiftR# ByteArray#
bs (Int# -> Word#
int2Word# Int#
n))
weaken :: Int -> VarSet -> VarSet
weaken :: Int -> VarSet -> VarSet
weaken (I# Int#
n) (VS# Word#
w) =
if Int# -> Bool
isTrue# (Word# -> Word#
clz# Word#
w Word# -> Word# -> Int#
`geWord#` Int# -> Word#
int2Word# Int#
n) then
Word# -> VarSet
VS# (Word#
w Word# -> Int# -> Word#
`uncheckedShiftL#` Int#
n)
else
ByteArray# -> VarSet
VB# (ByteArray# -> Word# -> ByteArray#
bigNatShiftL# (Word# -> ByteArray#
bigNatFromWord# Word#
w) (Int# -> Word#
int2Word# Int#
n))
weaken (I# Int#
n) (VB# ByteArray#
bs) =
ByteArray# -> VarSet
VB# (ByteArray# -> Word# -> ByteArray#
bigNatShiftL# ByteArray#
bs (Int# -> Word#
int2Word# Int#
n))
toDescList :: VarSet -> [Int]
toDescList :: VarSet -> [Int]
toDescList = ([Int] -> Int -> [Int]) -> [Int] -> VarSet -> [Int]
forall a. (a -> Int -> a) -> a -> VarSet -> a
foldl ((Int -> [Int] -> [Int]) -> [Int] -> Int -> [Int]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (:)) []
{-# INLINE toDescList #-}
toAscList :: VarSet -> [Int]
toAscList :: VarSet -> [Int]
toAscList = (Int -> [Int] -> [Int]) -> [Int] -> VarSet -> [Int]
forall a. (Int -> a -> a) -> a -> VarSet -> a
foldr (:) []
{-# INLINE toAscList #-}
traceVarSetSize :: VarSet -> VarSet
traceVarSetSize :: VarSet -> VarSet
traceVarSetSize vs :: VarSet
vs@(VS# Word#
_) = String -> VarSet -> VarSet
forall a. String -> a -> a
traceEvent (String
"VarSet.size=1") VarSet
vs
traceVarSetSize vs :: VarSet
vs@(VB# ByteArray#
bs) = String -> VarSet -> VarSet
forall a. String -> a -> a
traceEvent (String
"VarSet.size=" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Word -> String
forall a. Show a => a -> String
show (ByteArray# -> Word
bigNatSize ByteArray#
bs)) VarSet
vs