{-# Options_GHC -O0 #-} -- | Check a number of properties for popcount-ordered elements. -- -- $setup -- -- >>> :set -XScopedTypeVariables -- module Data.Bits.Ordered.QuickCheck where import Test.QuickCheck hiding ((.&.)) import Data.Int (Int16(..)) import Data.Bits import qualified Data.Vector.Unboxed as VU import Data.List (groupBy,sort,permutations,nub) import Data.Function (on) import Data.Maybe (isJust) import Control.Monad (join) import Debug.Trace import Data.Word (Word) import Data.Bits.Ordered -- | Check if both the memoized version and the population enumeration -- produce the same multisets, but maybe in different order. -- -- prop> \(n :: Int16) -> let b = popCount n in memoSorted b == enumSorted b -- prop_PopCountSet (NonZero (n :: Int16)) = memo == enum where b = popCount n memo = memoSorted b enum = enumSorted b memoSorted, enumSorted :: Int -> [[Int]] memoSorted b = map sort . groupBy ((==) `on` popCount) $ VU.toList $ popCntMemoInt b enumSorted b = map sort $ [0] : [ roll (popPermutation b) (Just $ 2^k-1) | k <- [1..b] ] where roll f (Just k) = k : roll f (f k) roll _ Nothing = [] prop_lsb_Int (x :: Int) = lsbZ x == maybe (-1) id (maybeLsb x) prop_lsb_Word (x :: Word) = lsbZ x == maybe (-1) id (maybeLsb x) prop_OneBits_Int (x :: Int) = popCount x == length abl && and [ testBit x k | k <- abl ] where abl = activeBitsL x -- Tests if we actually generate all permutations. prop_allPermutations (a :: Int , b :: Int) = and $ zipWith cmp (sort qs) (sort $ nub ps) where nbs = min a' b' -- number of 1 bits in set sts = max a' b' -- set size a' = a `mod` 8 -- finiteBitSize a b' = b `mod` 8 -- finiteBitSize b ps = permutations $ replicate (sts - nbs) False ++ replicate nbs True qs = go (Just $ 2 ^ nbs - 1) go :: Maybe Int -> [Int] go Nothing = [] go (Just k) = k : go (popPermutation sts k) cmp k as = and [ if a then testBit k c else (not $ testBit k c) | (a,c) <- zip (reverse as) [0 .. ] ] -- TODO popComplement prop_popShiftL_popShiftR (a::Word,b::Word) = s == l where m = a .|. b s = a .&. b l = popShiftL m r r = popShiftR m s