hw-excess 0.2.0.2 → 0.2.0.3
raw patch · 10 files changed
+707/−481 lines, 10 filesdep +bytestringdep +criteriondep +hedgehogdep ~hspecdep ~hw-primPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: bytestring, criterion, hedgehog, hw-hspec-hedgehog
Dependency ranges changed: hspec, hw-prim
API changes (from Hackage documentation)
+ HaskellWorks.Data.Excess.Internal.Branchless: maxInt :: Int -> Int -> Int
+ HaskellWorks.Data.Excess.Internal.Branchless: maxInt64 :: Int64 -> Int64 -> Int64
+ HaskellWorks.Data.Excess.Internal.Branchless: minInt :: Int -> Int -> Int
+ HaskellWorks.Data.Excess.Internal.Branchless: minInt64 :: Int64 -> Int64 -> Int64
+ HaskellWorks.Data.Excess.Internal.Table: word8Excess0 :: Vector Int
+ HaskellWorks.Data.Excess.Internal.Table: word8Excess0Max :: Vector Int
+ HaskellWorks.Data.Excess.Internal.Table: word8Excess0Min :: Vector Int
+ HaskellWorks.Data.Excess.Internal.Table: word8Excess1 :: Vector Int
+ HaskellWorks.Data.Excess.Internal.Table: word8Excess1Max :: Vector Int
+ HaskellWorks.Data.Excess.Internal.Table: word8Excess1Min :: Vector Int
Files
- README.md +2/−2
- bench/Main.hs +71/−0
- hw-excess.cabal +83/−55
- src/HaskellWorks/Data/Excess/Internal/Branchless.hs +31/−0
- src/HaskellWorks/Data/Excess/Internal/Table.hs +136/−0
- src/HaskellWorks/Data/Excess/MinMaxExcess0.hs +24/−82
- src/HaskellWorks/Data/Excess/MinMaxExcess1.hs +24/−82
- test/HaskellWorks/Data/Excess/Internal/BranchlessSpec.hs +36/−0
- test/HaskellWorks/Data/Excess/MinMaxExcess0Spec.hs +151/−131
- test/HaskellWorks/Data/Excess/MinMaxExcess1Spec.hs +149/−129
README.md view
@@ -1,4 +1,4 @@ # hw-excess-[](https://circleci.com/gh/haskell-works/hw-excess/tree/0.0-branch)+[](https://circleci.com/gh/haskell-works/hw-excess) -Rank and select operations.+Support library library for rankselect.
+ bench/Main.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Main where++import Control.Monad+import Criterion.Main+import Data.List+import Data.Word+import Foreign+import HaskellWorks.Data.Excess.MinMaxExcess0+import HaskellWorks.Data.Excess.MinMaxExcess1+import HaskellWorks.Data.Excess.Triplet+import HaskellWorks.Data.Vector.AsVector64++import qualified Data.ByteString as BS+import qualified Data.ByteString.Internal as BSI+import qualified Data.ByteString.Lazy as LBS+import qualified Data.Vector.Storable as DVS++setupEnvExcess :: Int -> IO (DVS.Vector Word64)+setupEnvExcess n = do+ lbs <- LBS.readFile "/dev/random"+ return (asVector64 (LBS.toStrict (LBS.take (fromIntegral n) lbs)))++runMinMaxExcess0VectorElems :: DVS.Vector Word64 -> IO ()+runMinMaxExcess0VectorElems v = do+ let !_ = DVS.foldl go 0 v++ return ()+ where go :: Int -> Word64 -> Int+ go a b = a + lo + ex + hi+ where Triplet lo ex hi = minMaxExcess0 (b :: Word64)++runMinMaxExcess1VectorElems :: DVS.Vector Word64 -> IO ()+runMinMaxExcess1VectorElems v = do+ let !_ = DVS.foldl go 0 v++ return ()+ where go :: Int -> Word64 -> Int+ go a b = a + lo + ex + hi+ where Triplet lo ex hi = minMaxExcess1 (b :: Word64)++runMinMaxExcess0Vector :: DVS.Vector Word64 -> IO ()+runMinMaxExcess0Vector v = do+ let !_ = minMaxExcess1 v++ return ()++runMinMaxExcess1Vector :: DVS.Vector Word64 -> IO ()+runMinMaxExcess1Vector v = do+ let !_ = minMaxExcess1 v++ return ()++makeBenchExcess :: IO [Benchmark]+makeBenchExcess = return $+ [ env (setupEnvExcess (1024 * 1024)) $ \v -> bgroup "MinMaxExcess Vector"+ [ bench "MinMaxExcess0" (whnfIO (runMinMaxExcess0VectorElems v))+ , bench "MinMaxExcess1" (whnfIO (runMinMaxExcess1VectorElems v))+ , bench "MinMaxExcess0" (whnfIO (runMinMaxExcess0Vector v))+ , bench "MinMaxExcess1" (whnfIO (runMinMaxExcess1Vector v))+ ]+ ]++main :: IO ()+main = do+ benchmarks <- mconcat <$> sequence+ [ makeBenchExcess+ ]+ defaultMain benchmarks
hw-excess.cabal view
@@ -1,67 +1,95 @@--- This file has been generated from package.yaml by hpack version 0.18.1.------ see: https://github.com/sol/hpack--name: hw-excess-version: 0.2.0.2-synopsis: Excess-description: Please see README.md-category: Data, Conduit-homepage: http://github.com/haskell-works/hw-excess#readme-bug-reports: https://github.com/haskell-works/hw-excess/issues-author: John Ky-maintainer: newhoggy@gmail.com-copyright: 2016 John Ky-license: BSD3-license-file: LICENSE-tested-with: GHC == 8.4.2, GHC == 8.2.2, GHC == 8.0.2, GHC == 7.10.3-build-type: Simple-cabal-version: >= 1.10+cabal-version: 2.2 +name: hw-excess+version: 0.2.0.3+synopsis: Excess+description: Please see README.md+category: Data, Succinct Data Structures, Data Structures+homepage: http://github.com/haskell-works/hw-excess#readme+bug-reports: https://github.com/haskell-works/hw-excess/issues+author: John Ky+maintainer: newhoggy@gmail.com+copyright: 2016 John Ky+license: BSD-3-Clause+license-file: LICENSE+tested-with: GHC == 8.6.5, GHC == 8.4.4, GHC == 8.2.2+build-type: Simple extra-source-files:- README.md+ README.md source-repository head type: git location: https://github.com/haskell-works/hw-excess +common base { build-depends: base >= 4.8 && < 5 }++common bytestring { build-depends: bytestring >= 0.10 && < 0.11 }+common criterion { build-depends: criterion >= 1.4 && < 1.6 }+common QuickCheck { build-depends: QuickCheck >= 2.10 && < 2.12 }+common hedgehog { build-depends: hedgehog >= 0.5 && < 0.7 }+common hspec { build-depends: hspec >= 2.3 && < 3 }+common hw-bits { build-depends: hw-bits >= 0.4.0.0 && < 0.8 }+common hw-hspec-hedgehog { build-depends: hw-hspec-hedgehog >= 0.1.0.4 && < 0.2 }+common hw-prim { build-depends: hw-prim >= 0.6.2.24 && < 0.7 }+common hw-rankselect-base { build-depends: hw-rankselect-base >= 0.2.0.0 && < 0.4 }+common safe { build-depends: safe >= 0.2 && < 0.4 }+common vector { build-depends: vector >= 0.12 && < 0.13 }++common config+ default-language: Haskell2010+ library- hs-source-dirs:- src- ghc-options: -Wall -O2 -msse4.2- build-depends:- base >=4.8 && <5- , hw-bits >=0.4.0.0 && < 0.8- , hw-prim >=0.4.0.0 && < 0.7- , vector >= 0.12 && < 0.13- , hw-rankselect-base >=0.2.0.0 && < 0.4- , safe >= 0.2 && < 0.4+ import: base, config+ , hw-bits+ , hw-prim+ , hw-rankselect-base+ , safe+ , vector exposed-modules:- HaskellWorks.Data.Excess- HaskellWorks.Data.Excess.Excess0- HaskellWorks.Data.Excess.Excess1- HaskellWorks.Data.Excess.MinMaxExcess0- HaskellWorks.Data.Excess.MinMaxExcess1- HaskellWorks.Data.Excess.Triplet- other-modules:- Paths_hw_excess- default-language: Haskell2010+ HaskellWorks.Data.Excess+ HaskellWorks.Data.Excess.Excess0+ HaskellWorks.Data.Excess.Excess1+ HaskellWorks.Data.Excess.Internal.Branchless+ HaskellWorks.Data.Excess.Internal.Table+ HaskellWorks.Data.Excess.MinMaxExcess0+ HaskellWorks.Data.Excess.MinMaxExcess1+ HaskellWorks.Data.Excess.Triplet+ autogen-modules: Paths_hw_excess+ other-modules: Paths_hw_excess+ hs-source-dirs: src+ ghc-options: -Wall -O2 -msse4.2 test-suite hw-excess-test- type: exitcode-stdio-1.0- main-is: Spec.hs- hs-source-dirs:- test- ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N- build-depends:- base >=4.8 && <5- , hw-bits >=0.4.0.0 && < 0.8- , hw-prim >=0.4.0.0 && < 0.7- , vector >= 0.12 && < 0.13- , hspec >= 2.3 && < 2.6- , hw-excess- , QuickCheck >= 2.10 && < 2.12+ import: base, config+ , QuickCheck+ , hedgehog+ , hspec+ , hw-bits+ , hw-prim+ , hw-hspec-hedgehog+ , vector+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ hs-source-dirs: test+ ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N+ build-tool-depends: hspec-discover:hspec-discover+ build-depends: hw-excess+ autogen-modules: Paths_hw_excess other-modules:- HaskellWorks.Data.Excess.MinMaxExcess0Spec- HaskellWorks.Data.Excess.MinMaxExcess1Spec- default-language: Haskell2010+ HaskellWorks.Data.Excess.Internal.BranchlessSpec+ HaskellWorks.Data.Excess.MinMaxExcess0Spec+ HaskellWorks.Data.Excess.MinMaxExcess1Spec+ Paths_hw_excess++benchmark bench+ import: base, config+ , bytestring+ , criterion+ , hw-prim+ , vector+ type: exitcode-stdio-1.0+ main-is: Main.hs+ hs-source-dirs: bench+ ghc-options: -O2 -msse4.2+ build-depends: hw-excess+ other-modules: Paths_hw_excess
+ src/HaskellWorks/Data/Excess/Internal/Branchless.hs view
@@ -0,0 +1,31 @@+module HaskellWorks.Data.Excess.Internal.Branchless+ ( maxInt64+ , maxInt+ , minInt64+ , minInt+ ) where++import Data.Int+import HaskellWorks.Data.Bits.BitWise++import qualified HaskellWorks.Data.Branchless as BL++minInt64 :: Int64 -> Int64 -> Int64+minInt64 a b = fromIntegral ((m .&. fromIntegral a) .|. (comp m .&. fromIntegral b))+ where t = BL.ltWord64 (fromIntegral (a - minBound)) (fromIntegral (b - minBound))+ m = 0 - t+{-# INLINE minInt64 #-}++minInt :: Int -> Int -> Int+minInt a b = fromIntegral (minInt64 (fromIntegral a) (fromIntegral b))+{-# INLINE minInt #-}++maxInt64 :: Int64 -> Int64 -> Int64+maxInt64 a b = fromIntegral ((m .&. fromIntegral a) .|. (comp m .&. fromIntegral b))+ where t = BL.gtWord64 (fromIntegral (a - minBound)) (fromIntegral (b - minBound))+ m = 0 - t+{-# INLINE maxInt64 #-}++maxInt :: Int -> Int -> Int+maxInt a b = fromIntegral (maxInt64 (fromIntegral a) (fromIntegral b))+{-# INLINE maxInt #-}
+ src/HaskellWorks/Data/Excess/Internal/Table.hs view
@@ -0,0 +1,136 @@+module HaskellWorks.Data.Excess.Internal.Table+ ( word8Excess0+ , word8Excess0Max+ , word8Excess0Min+ , word8Excess1+ , word8Excess1Max+ , word8Excess1Min+ ) where++import qualified Data.Vector.Storable as DVS++word8Excess0Min :: DVS.Vector Int+word8Excess0Min = DVS.fromList+ [ 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4+ , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5+ , 0, -1, -1, -3, -1, -3, -3, -5, -1, -3, -3, -5, -3, -5, -5, -7+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4+ , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6+ , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4+ , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6+ , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6+ , 0, -2, -2, -4, -2, -4, -4, -6, -2, -4, -4, -6, -4, -6, -6, -8+ ]+{-# NOINLINE word8Excess0Min #-}++word8Excess0 :: DVS.Vector Int+word8Excess0 = DVS.fromList+ [ 8, 6, 6, 4, 6, 4, 4, 2, 6, 4, 4, 2, 4, 2, 2, 0+ , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2+ , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2+ , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4+ , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2+ , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4+ , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4+ , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6+ , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2+ , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4+ , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4+ , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6+ , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4+ , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6+ , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6+ , 0, -2, -2, -4, -2, -4, -4, -6, -2, -4, -4, -6, -4, -6, -6, -8+ ]+{-# NOINLINE word8Excess0 #-}++word8Excess0Max :: DVS.Vector Int+word8Excess0Max = DVS.fromList+ [ 8, 6, 6, 4, 6, 4, 4, 2, 6, 4, 4, 2, 4, 2, 2, 0+ , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0+ , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0+ , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0+ , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 7, 5, 5, 3, 5, 3, 3, 1, 5, 3, 3, 1, 3, 1, 1, 0+ , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0+ , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0+ ]+{-# NOINLINE word8Excess0Max #-}++word8Excess1Min :: DVS.Vector Int+word8Excess1Min = DVS.fromList+ [ -8, -6, -6, -4, -6, -4, -4, -2, -6, -4, -4, -2, -4, -2, -2, 0+ , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, -1, 0+ , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, -1, 0+ , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, -1, 0+ , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -5, -3, -3, -1, -3, -1, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -7, -5, -5, -3, -5, -3, -3, -1, -5, -3, -3, -1, -3, -1, -1, 0+ , -5, -3, -3, -1, -3, -1, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -5, -3, -3, -1, -3, -1, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, -1, 0+ , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -5, -3, -3, -1, -3, -1, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0+ ]+{-# NOINLINE word8Excess1Min #-}++word8Excess1 :: DVS.Vector Int+word8Excess1 = DVS.fromList+ [ -8, -6, -6, -4, -6, -4, -4, -2, -6, -4, -4, -2, -4, -2, -2, 0+ , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2+ , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2+ , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4+ , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2+ , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4+ , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4+ , -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6+ , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2+ , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4+ , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4+ , -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6+ , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4+ , -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6+ , -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6+ , 0, 2, 2, 4, 2, 4, 4, 6, 2, 4, 4, 6, 4, 6, 6, 8+ ]+{-# NOINLINE word8Excess1 #-}++word8Excess1Max :: DVS.Vector Int+word8Excess1Max = DVS.fromList+ [ 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 1, 3, 1, 3, 3, 5+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4+ , 0, 1, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 1, 3, 1, 3, 3, 5+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 1, 3, 1, 3, 3, 5+ , 0, 1, 1, 3, 1, 3, 3, 5, 1, 3, 3, 5, 3, 5, 5, 7+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 1, 3, 1, 3, 3, 5+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4+ , 0, 1, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6+ , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4+ , 0, 1, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6+ , 0, 1, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6+ , 0, 2, 2, 4, 2, 4, 4, 6, 2, 4, 4, 6, 4, 6, 6, 8+ ]+{-# NOINLINE word8Excess1Max #-}
src/HaskellWorks/Data/Excess/MinMaxExcess0.hs view
@@ -9,10 +9,12 @@ import Data.Word import HaskellWorks.Data.Bits.BitWise import HaskellWorks.Data.Bits.FixedBitSize+import HaskellWorks.Data.Excess.Internal.Table import HaskellWorks.Data.Excess.Triplet import HaskellWorks.Data.Naive -import qualified Data.Vector.Storable as DVS+import qualified Data.Vector.Storable as DVS+import qualified HaskellWorks.Data.Excess.Internal.Branchless as BL type MinExcess = Int type MaxExcess = Int@@ -56,31 +58,31 @@ {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 Word8 where- minMaxExcess0 w = Triplet (word8Excess0Min DVS.! fromIntegral w)- (word8Excess0 DVS.! fromIntegral w)- (word8Excess0Max DVS.! fromIntegral w)+ minMaxExcess0 w = Triplet (DVS.unsafeIndex word8Excess0Min (fromIntegral w))+ (DVS.unsafeIndex word8Excess0 (fromIntegral w))+ (DVS.unsafeIndex word8Excess0Max (fromIntegral w)) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 Word16 where- minMaxExcess0 w = Triplet (minExcessA `min` (minExcessB + allExcessA))+ minMaxExcess0 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB)- (maxExcessA `max` (maxExcessB + allExcessA))+ (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess0 (fromIntegral w :: Word8) Triplet minExcessB allExcessB maxExcessB = minMaxExcess0 (fromIntegral (w .>. 8) :: Word8) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 Word32 where- minMaxExcess0 w = Triplet (minExcessA `min` (minExcessB + allExcessA))+ minMaxExcess0 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB)- (maxExcessA `max` (maxExcessB + allExcessA))+ (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess0 (fromIntegral w :: Word16) Triplet minExcessB allExcessB maxExcessB = minMaxExcess0 (fromIntegral (w .>. 16) :: Word16) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 Word64 where- minMaxExcess0 w = Triplet (minExcessA `min` (minExcessB + allExcessA))+ minMaxExcess0 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB)- (maxExcessA `max` (maxExcessB + allExcessA))+ (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess0 (fromIntegral w :: Word32) Triplet minExcessB allExcessB maxExcessB = minMaxExcess0 (fromIntegral (w .>. 32) :: Word32) {-# INLINE minMaxExcess0 #-}@@ -89,94 +91,34 @@ minMaxExcess0 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word8 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess0 w in- Triplet (minE `min` (wMinE + allE))- ( wAllE + allE )- (maxE `max` (wMaxE + allE))+ Triplet (BL.minInt minE (wMinE + allE))+ ( wAllE + allE )+ (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (DVS.Vector Word16) where minMaxExcess0 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word16 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess0 w in- Triplet (minE `min` (wMinE + allE))- ( wAllE + allE )- (maxE `max` (wMaxE + allE))+ Triplet (BL.minInt minE (wMinE + allE))+ ( wAllE + allE )+ (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (DVS.Vector Word32) where minMaxExcess0 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word32 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess0 w in- Triplet (minE `min` (wMinE + allE))- ( wAllE + allE )- (maxE `max` (wMaxE + allE))+ Triplet (BL.minInt minE (wMinE + allE))+ ( wAllE + allE )+ (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (DVS.Vector Word64) where minMaxExcess0 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word64 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess0 w in- Triplet (minE `min` (wMinE + allE))- ( wAllE + allE )- (maxE `max` (wMaxE + allE))+ Triplet (BL.minInt minE (wMinE + allE))+ ( wAllE + allE )+ (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess0 #-}--word8Excess0Min :: DVS.Vector Int-word8Excess0Min = DVS.fromList- [ 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4- , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5- , 0, -1, -1, -3, -1, -3, -3, -5, -1, -3, -3, -5, -3, -5, -5, -7- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4- , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6- , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4- , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6- , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6- , 0, -2, -2, -4, -2, -4, -4, -6, -2, -4, -4, -6, -4, -6, -6, -8- ]--word8Excess0 :: DVS.Vector Int-word8Excess0 = DVS.fromList- [ 8, 6, 6, 4, 6, 4, 4, 2, 6, 4, 4, 2, 4, 2, 2, 0- , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2- , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2- , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4- , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2- , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4- , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4- , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6- , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2- , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4- , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4- , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6- , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4- , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6- , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6- , 0, -2, -2, -4, -2, -4, -4, -6, -2, -4, -4, -6, -4, -6, -6, -8- ]--word8Excess0Max :: DVS.Vector Int-word8Excess0Max = DVS.fromList- [ 8, 6, 6, 4, 6, 4, 4, 2, 6, 4, 4, 2, 4, 2, 2, 0- , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0- , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0- , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0- , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 7, 5, 5, 3, 5, 3, 3, 1, 5, 3, 3, 1, 3, 1, 1, 0- , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0- , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0- ]
src/HaskellWorks/Data/Excess/MinMaxExcess1.hs view
@@ -9,10 +9,12 @@ import Data.Word import HaskellWorks.Data.Bits.BitWise import HaskellWorks.Data.Bits.FixedBitSize+import HaskellWorks.Data.Excess.Internal.Table import HaskellWorks.Data.Excess.Triplet import HaskellWorks.Data.Naive -import qualified Data.Vector.Storable as DVS+import qualified Data.Vector.Storable as DVS+import qualified HaskellWorks.Data.Excess.Internal.Branchless as BL type MinExcess = Int type MaxExcess = Int@@ -56,31 +58,31 @@ {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 Word8 where- minMaxExcess1 w = Triplet (word8Excess1Min DVS.! fromIntegral w)- (word8Excess1 DVS.! fromIntegral w)- (word8Excess1Max DVS.! fromIntegral w)+ minMaxExcess1 w = Triplet (DVS.unsafeIndex word8Excess1Min (fromIntegral w))+ (DVS.unsafeIndex word8Excess1 (fromIntegral w))+ (DVS.unsafeIndex word8Excess1Max (fromIntegral w)) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 Word16 where- minMaxExcess1 w = Triplet (minExcessA `min` (minExcessB + allExcessA))+ minMaxExcess1 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB)- (maxExcessA `max` (maxExcessB + allExcessA))+ (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess1 (fromIntegral w :: Word8) Triplet minExcessB allExcessB maxExcessB = minMaxExcess1 (fromIntegral (w .>. 8) :: Word8) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 Word32 where- minMaxExcess1 w = Triplet (minExcessA `min` (minExcessB + allExcessA))+ minMaxExcess1 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB)- (maxExcessA `max` (maxExcessB + allExcessA))+ (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess1 (fromIntegral w :: Word16) Triplet minExcessB allExcessB maxExcessB = minMaxExcess1 (fromIntegral (w .>. 16) :: Word16) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 Word64 where- minMaxExcess1 w = Triplet (minExcessA `min` (minExcessB + allExcessA))+ minMaxExcess1 w = Triplet (BL.minInt minExcessA (minExcessB + allExcessA)) (allExcessA + allExcessB)- (maxExcessA `max` (maxExcessB + allExcessA))+ (BL.maxInt maxExcessA (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess1 (fromIntegral w :: Word32) Triplet minExcessB allExcessB maxExcessB = minMaxExcess1 (fromIntegral (w .>. 32) :: Word32) {-# INLINE minMaxExcess1 #-}@@ -89,94 +91,34 @@ minMaxExcess1 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word8 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess1 w in- Triplet (minE `min` (wMinE + allE))- ( wAllE + allE )- (maxE `max` (wMaxE + allE))+ Triplet (BL.minInt minE (wMinE + allE))+ ( wAllE + allE )+ (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (DVS.Vector Word16) where minMaxExcess1 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word16 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess1 w in- Triplet (minE `min` (wMinE + allE))- ( wAllE + allE )- (maxE `max` (wMaxE + allE))+ Triplet (BL.minInt minE (wMinE + allE))+ ( wAllE + allE )+ (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (DVS.Vector Word32) where minMaxExcess1 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word32 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess1 w in- Triplet (minE `min` (wMinE + allE))- ( wAllE + allE )- (maxE `max` (wMaxE + allE))+ Triplet (BL.minInt minE (wMinE + allE))+ ( wAllE + allE )+ (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess1 #-} instance MinMaxExcess1 (DVS.Vector Word64) where minMaxExcess1 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word64 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess1 w in- Triplet (minE `min` (wMinE + allE))- ( wAllE + allE )- (maxE `max` (wMaxE + allE))+ Triplet (BL.minInt minE (wMinE + allE))+ ( wAllE + allE )+ (BL.maxInt maxE (wMaxE + allE)) {-# INLINE minMaxExcess1 #-}--word8Excess1Min :: DVS.Vector Int-word8Excess1Min = DVS.fromList- [ -8, -6, -6, -4, -6, -4, -4, -2, -6, -4, -4, -2, -4, -2, -2, 0- , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, -1, 0- , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, -1, 0- , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, -1, 0- , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -5, -3, -3, -1, -3, -1, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -7, -5, -5, -3, -5, -3, -3, -1, -5, -3, -3, -1, -3, -1, -1, 0- , -5, -3, -3, -1, -3, -1, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -5, -3, -3, -1, -3, -1, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, -1, 0- , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -5, -3, -3, -1, -3, -1, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- , -4, -2, -2, 0, -2, 0, -1, 0, -3, -1, -1, 0, -2, 0, -1, 0- ]--word8Excess1 :: DVS.Vector Int-word8Excess1 = DVS.fromList- [ -8, -6, -6, -4, -6, -4, -4, -2, -6, -4, -4, -2, -4, -2, -2, 0- , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2- , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2- , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4- , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2- , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4- , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4- , -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6- , -6, -4, -4, -2, -4, -2, -2, 0, -4, -2, -2, 0, -2, 0, 0, 2- , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4- , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4- , -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6- , -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4- , -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6- , -2, 0, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6- , 0, 2, 2, 4, 2, 4, 4, 6, 2, 4, 4, 6, 4, 6, 6, 8- ]--word8Excess1Max :: DVS.Vector Int-word8Excess1Max = DVS.fromList- [ 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 1, 3, 1, 3, 3, 5- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4- , 0, 1, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 1, 3, 1, 3, 3, 5- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 1, 3, 1, 3, 3, 5- , 0, 1, 1, 3, 1, 3, 3, 5, 1, 3, 3, 5, 3, 5, 5, 7- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 1, 3, 1, 3, 3, 5- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4- , 0, 1, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6- , 0, 1, 0, 2, 0, 1, 1, 3, 0, 1, 0, 2, 0, 2, 2, 4- , 0, 1, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6- , 0, 1, 0, 2, 0, 2, 2, 4, 0, 2, 2, 4, 2, 4, 4, 6- , 0, 2, 2, 4, 2, 4, 4, 6, 2, 4, 4, 6, 4, 6, 6, 8- ]
+ test/HaskellWorks/Data/Excess/Internal/BranchlessSpec.hs view
@@ -0,0 +1,36 @@+module HaskellWorks.Data.Excess.Internal.BranchlessSpec (spec) where++import HaskellWorks.Hspec.Hedgehog+import Hedgehog+import Test.Hspec++import qualified HaskellWorks.Data.Excess.Internal.Branchless as BL+import qualified Hedgehog.Gen as G+import qualified Hedgehog.Range as R++{-# ANN module ("HLint: Ignore Redundant do" :: String) #-}+{-# ANN module ("HLint: Ignore Reduce duplication" :: String) #-}++spec :: Spec+spec = describe "HaskellWorks.Data.Excess.Internal.Branchless" $ do+ describe "For Int64" $ do+ it "minInt64 behaves like min" $ requireProperty $ do+ a <- forAll $ G.int64 R.constantBounded+ b <- forAll $ G.int64 R.constantBounded++ min a b === BL.minInt64 a b+ it "minInt behaves like min" $ requireProperty $ do+ a <- forAll $ G.int R.constantBounded+ b <- forAll $ G.int R.constantBounded++ min a b === BL.minInt a b+ it "maxInt64 behaves like max" $ requireProperty $ do+ a <- forAll $ G.int64 R.constantBounded+ b <- forAll $ G.int64 R.constantBounded++ max a b === BL.maxInt64 a b+ it "maxInt behaves like max" $ requireProperty $ do+ a <- forAll $ G.int R.constantBounded+ b <- forAll $ G.int R.constantBounded++ max a b === BL.maxInt a b
test/HaskellWorks/Data/Excess/MinMaxExcess0Spec.hs view
@@ -3,15 +3,17 @@ module HaskellWorks.Data.Excess.MinMaxExcess0Spec (spec) where -import Data.Word import HaskellWorks.Data.Bits.Word-import HaskellWorks.Data.Naive import HaskellWorks.Data.Excess.MinMaxExcess0 import HaskellWorks.Data.Excess.Triplet+import HaskellWorks.Data.Naive+import HaskellWorks.Hspec.Hedgehog+import Hedgehog import Test.Hspec-import Test.QuickCheck -import qualified Data.Vector.Storable as DVS+import qualified Data.Vector.Storable as DVS+import qualified Hedgehog.Gen as G+import qualified Hedgehog.Range as R {-# ANN module ("HLint: Ignore Redundant do" :: String) #-} {-# ANN module ("HLint: Ignore Reduce duplication" :: String) #-}@@ -19,133 +21,151 @@ spec :: Spec spec = describe "HaskellWorks.Data.Excess.MinMaxExcess0Spec" $ do describe "For Word8" $ do- it "Excess should be between min excess and max excess" $- property $ \(w :: Word8) ->- let Triplet minE e maxE = minMaxExcess0 w in- minE <= e && e <= maxE- it "minE2 == minE0 `min` (minE1 + e0)" $- property $ \(w0 :: Word8, w1 :: Word8) ->- let w2 = leConcat w0 w1 in- let Triplet minE0 e0 _ = minMaxExcess0 w0 in- let Triplet minE1 _ _ = minMaxExcess0 w1 in- let Triplet minE2 _ _ = minMaxExcess0 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0)" $- property $ \(w0 :: Word8, w1 :: Word8) ->- let w2 = leConcat w0 w1 in- let Triplet _ e0 maxE0 = minMaxExcess0 w0 in- let Triplet _ _ maxE1 = minMaxExcess0 w1 in- let Triplet _ _ maxE2 = minMaxExcess0 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)- it "minE2 == minE0 `min` (minE1 + e0) via vector" $- property $ \(w0 :: Word8, w1 :: Word8) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet minE0 e0 _ = minMaxExcess0 w0 in- let Triplet minE1 _ _ = minMaxExcess0 w1 in- let Triplet minE2 _ _ = minMaxExcess0 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $- property $ \(w0 :: Word8, w1 :: Word8) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet _ e0 maxE0 = minMaxExcess0 w0 in- let Triplet _ _ maxE1 = minMaxExcess0 w1 in- let Triplet _ _ maxE2 = minMaxExcess0 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)+ it "Excess should be between min excess and max excess" $ requireProperty $ do+ w <- forAll $ G.word8 R.constantBounded+ let Triplet minE e maxE = minMaxExcess0 w+ assert $ minE <= e && e <= maxE+ it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word8 R.constantBounded+ w1 <- forAll $ G.word8 R.constantBounded+ let w2 = leConcat w0 w1+ let Triplet minE0 e0 _ = minMaxExcess0 w0+ let Triplet minE1 _ _ = minMaxExcess0 w1+ let Triplet minE2 _ _ = minMaxExcess0 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word8 R.constantBounded+ w1 <- forAll $ G.word8 R.constantBounded+ let w2 = leConcat w0 w1+ let Triplet _ e0 maxE0 = minMaxExcess0 w0+ let Triplet _ _ maxE1 = minMaxExcess0 w1+ let Triplet _ _ maxE2 = minMaxExcess0 w2+ maxE2 === maxE0 `max` (maxE1 + e0)+ it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word8 R.constantBounded+ w1 <- forAll $ G.word8 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet minE0 e0 _ = minMaxExcess0 w0+ let Triplet minE1 _ _ = minMaxExcess0 w1+ let Triplet minE2 _ _ = minMaxExcess0 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word8 R.constantBounded+ w1 <- forAll $ G.word8 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet _ e0 maxE0 = minMaxExcess0 w0+ let Triplet _ _ maxE1 = minMaxExcess0 w1+ let Triplet _ _ maxE2 = minMaxExcess0 w2+ maxE2 === maxE0 `max` (maxE1 + e0) describe "For Word16" $ do- it "Excess should be between min excess and max excess" $- property $ \(w :: Word16) ->- let Triplet minE e maxE = minMaxExcess0 w in- minE <= e && e <= maxE- it "minE2 == minE0 `min` (minE1 + e0)" $- property $ \(w0 :: Word16, w1 :: Word16) ->- let w2 = leConcat w0 w1 in- let Triplet minE0 e0 _ = minMaxExcess0 w0 in- let Triplet minE1 _ _ = minMaxExcess0 w1 in- let Triplet minE2 _ _ = minMaxExcess0 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0)" $- property $ \(w0 :: Word16, w1 :: Word16) ->- let w2 = leConcat w0 w1 in- let Triplet _ e0 maxE0 = minMaxExcess0 w0 in- let Triplet _ _ maxE1 = minMaxExcess0 w1 in- let Triplet _ _ maxE2 = minMaxExcess0 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)- it "minE2 == minE0 `min` (minE1 + e0) via vector" $- property $ \(w0 :: Word16, w1 :: Word16) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet minE0 e0 _ = minMaxExcess0 w0 in- let Triplet minE1 _ _ = minMaxExcess0 w1 in- let Triplet minE2 _ _ = minMaxExcess0 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $- property $ \(w0 :: Word16, w1 :: Word16) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet _ e0 maxE0 = minMaxExcess0 w0 in- let Triplet _ _ maxE1 = minMaxExcess0 w1 in- let Triplet _ _ maxE2 = minMaxExcess0 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)+ it "Excess should be between min excess and max excess" $ requireProperty $ do+ w <- forAll $ G.word16 R.constantBounded+ let Triplet minE e maxE = minMaxExcess0 w+ assert $ minE <= e && e <= maxE+ it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word16 R.constantBounded+ w1 <- forAll $ G.word16 R.constantBounded+ let w2 = leConcat w0 w1+ let Triplet minE0 e0 _ = minMaxExcess0 w0+ let Triplet minE1 _ _ = minMaxExcess0 w1+ let Triplet minE2 _ _ = minMaxExcess0 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word16 R.constantBounded+ w1 <- forAll $ G.word16 R.constantBounded+ let w2 = leConcat w0 w1+ let Triplet _ e0 maxE0 = minMaxExcess0 w0+ let Triplet _ _ maxE1 = minMaxExcess0 w1+ let Triplet _ _ maxE2 = minMaxExcess0 w2+ maxE2 === maxE0 `max` (maxE1 + e0)+ it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word16 R.constantBounded+ w1 <- forAll $ G.word16 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet minE0 e0 _ = minMaxExcess0 w0+ let Triplet minE1 _ _ = minMaxExcess0 w1+ let Triplet minE2 _ _ = minMaxExcess0 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word16 R.constantBounded+ w1 <- forAll $ G.word16 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet _ e0 maxE0 = minMaxExcess0 w0+ let Triplet _ _ maxE1 = minMaxExcess0 w1+ let Triplet _ _ maxE2 = minMaxExcess0 w2+ maxE2 === maxE0 `max` (maxE1 + e0) describe "For Word32" $ do- it "Excess should be between min excess and max excess" $- property $ \(w :: Word32) ->- let Triplet minE e maxE = minMaxExcess0 w in- minE <= e && e <= maxE- it "minE2 == minE0 `min` (minE1 + e0)" $- property $ \(w0 :: Word32, w1 :: Word32) ->- let w2 = leConcat w0 w1 in- let Triplet minE0 e0 _ = minMaxExcess0 w0 in- let Triplet minE1 _ _ = minMaxExcess0 w1 in- let Triplet minE2 _ _ = minMaxExcess0 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0)" $- property $ \(w0 :: Word32, w1 :: Word32) ->- let w2 = leConcat w0 w1 in- let Triplet _ e0 maxE0 = minMaxExcess0 w0 in- let Triplet _ _ maxE1 = minMaxExcess0 w1 in- let Triplet _ _ maxE2 = minMaxExcess0 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)- it "minE2 == minE0 `min` (minE1 + e0) via vector" $- property $ \(w0 :: Word32, w1 :: Word32) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet minE0 e0 _ = minMaxExcess0 w0 in- let Triplet minE1 _ _ = minMaxExcess0 w1 in- let Triplet minE2 _ _ = minMaxExcess0 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $- property $ \(w0 :: Word32, w1 :: Word32) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet _ e0 maxE0 = minMaxExcess0 w0 in- let Triplet _ _ maxE1 = minMaxExcess0 w1 in- let Triplet _ _ maxE2 = minMaxExcess0 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)+ it "Excess should be between min excess and max excess" $ requireProperty $ do+ w <- forAll $ G.word32 R.constantBounded+ let Triplet minE e maxE = minMaxExcess0 w+ assert $ minE <= e && e <= maxE+ it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word32 R.constantBounded+ w1 <- forAll $ G.word32 R.constantBounded++ let w2 = leConcat w0 w1+ let Triplet minE0 e0 _ = minMaxExcess0 w0+ let Triplet minE1 _ _ = minMaxExcess0 w1+ let Triplet minE2 _ _ = minMaxExcess0 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word32 R.constantBounded+ w1 <- forAll $ G.word32 R.constantBounded++ let w2 = leConcat w0 w1+ let Triplet _ e0 maxE0 = minMaxExcess0 w0+ let Triplet _ _ maxE1 = minMaxExcess0 w1+ let Triplet _ _ maxE2 = minMaxExcess0 w2+ maxE2 === maxE0 `max` (maxE1 + e0)+ it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word32 R.constantBounded+ w1 <- forAll $ G.word32 R.constantBounded++ let w2 = DVS.fromList [w0, w1]+ let Triplet minE0 e0 _ = minMaxExcess0 w0+ let Triplet minE1 _ _ = minMaxExcess0 w1+ let Triplet minE2 _ _ = minMaxExcess0 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word32 R.constantBounded+ w1 <- forAll $ G.word32 R.constantBounded++ let w2 = DVS.fromList [w0, w1]+ let Triplet _ e0 maxE0 = minMaxExcess0 w0+ let Triplet _ _ maxE1 = minMaxExcess0 w1+ let Triplet _ _ maxE2 = minMaxExcess0 w2+ maxE2 === maxE0 `max` (maxE1 + e0) describe "For Word64" $ do- it "Excess should be between min excess and max excess" $- property $ \(w :: Word64) ->- let Triplet minE e maxE = minMaxExcess0 w in- minE <= e && e <= maxE- it "minE2 == minE0 `min` (minE1 + e0) via vector" $- property $ \(w0 :: Word64, w1 :: Word64) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet minE0 e0 _ = minMaxExcess0 w0 in- let Triplet minE1 _ _ = minMaxExcess0 w1 in- let Triplet minE2 _ _ = minMaxExcess0 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $- property $ \(w0 :: Word64, w1 :: Word64) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet _ e0 maxE0 = minMaxExcess0 w0 in- let Triplet _ _ maxE1 = minMaxExcess0 w1 in- let Triplet _ _ maxE2 = minMaxExcess0 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)- describe "Equivalent to native implementation" $ do- it "For Word8" $ do- property $ \(w :: Word8) ->- minMaxExcess0 w == minMaxExcess0 (Naive w)- it "For Word16" $ do- property $ \(w :: Word16) ->- minMaxExcess0 w == minMaxExcess0 (Naive w)- it "For Word32" $ do- property $ \(w :: Word32) ->- minMaxExcess0 w == minMaxExcess0 (Naive w)- it "For Word64" $ do- property $ \(w :: Word64) ->- minMaxExcess0 w == minMaxExcess0 (Naive w)+ it "Excess should be between min excess and max excess" $ requireProperty $ do+ w <- forAll $ G.word64 R.constantBounded+ let Triplet minE e maxE = minMaxExcess0 w+ assert $ minE <= e && e <= maxE+ it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word64 R.constantBounded+ w1 <- forAll $ G.word64 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet minE0 e0 _ = minMaxExcess0 w0+ let Triplet minE1 _ _ = minMaxExcess0 w1+ let Triplet minE2 _ _ = minMaxExcess0 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word64 R.constantBounded+ w1 <- forAll $ G.word64 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet _ e0 maxE0 = minMaxExcess0 w0+ let Triplet _ _ maxE1 = minMaxExcess0 w1+ let Triplet _ _ maxE2 = minMaxExcess0 w2+ maxE2 === maxE0 `max` (maxE1 + e0)+ describe "Equivalent to native implementation" $ do+ it "For Word8" $ requireProperty $ do+ w <- forAll $ G.word8 R.constantBounded+ minMaxExcess0 w === minMaxExcess0 (Naive w)+ it "For Word16" $ requireProperty $ do+ w <- forAll $ G.word16 R.constantBounded+ minMaxExcess0 w === minMaxExcess0 (Naive w)+ it "For Word32" $ requireProperty $ do+ w <- forAll $ G.word32 R.constantBounded+ minMaxExcess0 w === minMaxExcess0 (Naive w)+ it "For Word64" $ requireProperty $ do+ w <- forAll $ G.word64 R.constantBounded+ minMaxExcess0 w === minMaxExcess0 (Naive w)
test/HaskellWorks/Data/Excess/MinMaxExcess1Spec.hs view
@@ -3,15 +3,17 @@ module HaskellWorks.Data.Excess.MinMaxExcess1Spec (spec) where -import Data.Word import HaskellWorks.Data.Bits.Word import HaskellWorks.Data.Excess.MinMaxExcess1 import HaskellWorks.Data.Excess.Triplet import HaskellWorks.Data.Naive+import HaskellWorks.Hspec.Hedgehog+import Hedgehog import Test.Hspec-import Test.QuickCheck -import qualified Data.Vector.Storable as DVS+import qualified Data.Vector.Storable as DVS+import qualified Hedgehog.Gen as G+import qualified Hedgehog.Range as R {-# ANN module ("HLint: Ignore Redundant do" :: String) #-} {-# ANN module ("HLint: Ignore Reduce duplication" :: String) #-}@@ -19,133 +21,151 @@ spec :: Spec spec = describe "HaskellWorks.Data.Excess.MinMaxExcess1Spec" $ do describe "For Word8" $ do- it "Excess should be between min excess and max excess" $- property $ \(w :: Word8) ->- let Triplet minE e maxE = minMaxExcess1 w in- minE <= e && e <= maxE- it "minE2 == minE0 `min` (minE1 + e0)" $- property $ \(w0 :: Word8, w1 :: Word8) ->- let w2 = leConcat w0 w1 in- let Triplet minE0 e0 _ = minMaxExcess1 w0 in- let Triplet minE1 _ _ = minMaxExcess1 w1 in- let Triplet minE2 _ _ = minMaxExcess1 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0)" $- property $ \(w0 :: Word8, w1 :: Word8) ->- let w2 = leConcat w0 w1 in- let Triplet _ e0 maxE0 = minMaxExcess1 w0 in- let Triplet _ _ maxE1 = minMaxExcess1 w1 in- let Triplet _ _ maxE2 = minMaxExcess1 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)- it "minE2 == minE0 `min` (minE1 + e0) via vector" $- property $ \(w0 :: Word8, w1 :: Word8) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet minE0 e0 _ = minMaxExcess1 w0 in- let Triplet minE1 _ _ = minMaxExcess1 w1 in- let Triplet minE2 _ _ = minMaxExcess1 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $- property $ \(w0 :: Word8, w1 :: Word8) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet _ e0 maxE0 = minMaxExcess1 w0 in- let Triplet _ _ maxE1 = minMaxExcess1 w1 in- let Triplet _ _ maxE2 = minMaxExcess1 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)+ it "Excess should be between min excess and max excess" $ requireProperty $ do+ w <- forAll $ G.word8 R.constantBounded+ let Triplet minE e maxE = minMaxExcess1 w+ assert $ minE <= e && e <= maxE+ it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word8 R.constantBounded+ w1 <- forAll $ G.word8 R.constantBounded++ let w2 = leConcat w0 w1+ let Triplet minE0 e0 _ = minMaxExcess1 w0+ let Triplet minE1 _ _ = minMaxExcess1 w1+ let Triplet minE2 _ _ = minMaxExcess1 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word8 R.constantBounded+ w1 <- forAll $ G.word8 R.constantBounded++ let w2 = leConcat w0 w1+ let Triplet _ e0 maxE0 = minMaxExcess1 w0+ let Triplet _ _ maxE1 = minMaxExcess1 w1+ let Triplet _ _ maxE2 = minMaxExcess1 w2+ maxE2 === maxE0 `max` (maxE1 + e0)+ it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word8 R.constantBounded+ w1 <- forAll $ G.word8 R.constantBounded++ let w2 = DVS.fromList [w0, w1]+ let Triplet minE0 e0 _ = minMaxExcess1 w0+ let Triplet minE1 _ _ = minMaxExcess1 w1+ let Triplet minE2 _ _ = minMaxExcess1 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word8 R.constantBounded+ w1 <- forAll $ G.word8 R.constantBounded++ let w2 = DVS.fromList [w0, w1]+ let Triplet _ e0 maxE0 = minMaxExcess1 w0+ let Triplet _ _ maxE1 = minMaxExcess1 w1+ let Triplet _ _ maxE2 = minMaxExcess1 w2+ maxE2 === maxE0 `max` (maxE1 + e0) describe "For Word16" $ do- it "Excess should be between min excess and max excess" $- property $ \(w :: Word16) ->- let Triplet minE e maxE = minMaxExcess1 w in- minE <= e && e <= maxE- it "minE2 == minE0 `min` (minE1 + e0)" $- property $ \(w0 :: Word16, w1 :: Word16) ->- let w2 = leConcat w0 w1 in- let Triplet minE0 e0 _ = minMaxExcess1 w0 in- let Triplet minE1 _ _ = minMaxExcess1 w1 in- let Triplet minE2 _ _ = minMaxExcess1 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0)" $- property $ \(w0 :: Word16, w1 :: Word16) ->- let w2 = leConcat w0 w1 in- let Triplet _ e0 maxE0 = minMaxExcess1 w0 in- let Triplet _ _ maxE1 = minMaxExcess1 w1 in- let Triplet _ _ maxE2 = minMaxExcess1 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)- it "minE2 == minE0 `min` (minE1 + e0) via vector" $- property $ \(w0 :: Word16, w1 :: Word16) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet minE0 e0 _ = minMaxExcess1 w0 in- let Triplet minE1 _ _ = minMaxExcess1 w1 in- let Triplet minE2 _ _ = minMaxExcess1 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $- property $ \(w0 :: Word16, w1 :: Word16) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet _ e0 maxE0 = minMaxExcess1 w0 in- let Triplet _ _ maxE1 = minMaxExcess1 w1 in- let Triplet _ _ maxE2 = minMaxExcess1 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)+ it "Excess should be between min excess and max excess" $ requireProperty $ do+ w <- forAll $ G.word16 R.constantBounded+ let Triplet minE e maxE = minMaxExcess1 w+ assert $ minE <= e && e <= maxE+ it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word16 R.constantBounded+ w1 <- forAll $ G.word16 R.constantBounded+ let w2 = leConcat w0 w1+ let Triplet minE0 e0 _ = minMaxExcess1 w0+ let Triplet minE1 _ _ = minMaxExcess1 w1+ let Triplet minE2 _ _ = minMaxExcess1 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word16 R.constantBounded+ w1 <- forAll $ G.word16 R.constantBounded+ let w2 = leConcat w0 w1+ let Triplet _ e0 maxE0 = minMaxExcess1 w0+ let Triplet _ _ maxE1 = minMaxExcess1 w1+ let Triplet _ _ maxE2 = minMaxExcess1 w2+ maxE2 === maxE0 `max` (maxE1 + e0)+ it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word16 R.constantBounded+ w1 <- forAll $ G.word16 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet minE0 e0 _ = minMaxExcess1 w0+ let Triplet minE1 _ _ = minMaxExcess1 w1+ let Triplet minE2 _ _ = minMaxExcess1 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word16 R.constantBounded+ w1 <- forAll $ G.word16 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet _ e0 maxE0 = minMaxExcess1 w0+ let Triplet _ _ maxE1 = minMaxExcess1 w1+ let Triplet _ _ maxE2 = minMaxExcess1 w2+ maxE2 === maxE0 `max` (maxE1 + e0) describe "For Word32" $ do- it "Excess should be between min excess and max excess" $- property $ \(w :: Word32) ->- let Triplet minE e maxE = minMaxExcess1 w in- minE <= e && e <= maxE- it "minE2 == minE0 `min` (minE1 + e0)" $- property $ \(w0 :: Word32, w1 :: Word32) ->- let w2 = leConcat w0 w1 in- let Triplet minE0 e0 _ = minMaxExcess1 w0 in- let Triplet minE1 _ _ = minMaxExcess1 w1 in- let Triplet minE2 _ _ = minMaxExcess1 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0)" $- property $ \(w0 :: Word32, w1 :: Word32) ->- let w2 = leConcat w0 w1 in- let Triplet _ e0 maxE0 = minMaxExcess1 w0 in- let Triplet _ _ maxE1 = minMaxExcess1 w1 in- let Triplet _ _ maxE2 = minMaxExcess1 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)- it "minE2 == minE0 `min` (minE1 + e0) via vector" $- property $ \(w0 :: Word32, w1 :: Word32) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet minE0 e0 _ = minMaxExcess1 w0 in- let Triplet minE1 _ _ = minMaxExcess1 w1 in- let Triplet minE2 _ _ = minMaxExcess1 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $- property $ \(w0 :: Word32, w1 :: Word32) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet _ e0 maxE0 = minMaxExcess1 w0 in- let Triplet _ _ maxE1 = minMaxExcess1 w1 in- let Triplet _ _ maxE2 = minMaxExcess1 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)+ it "Excess should be between min excess and max excess" $ requireProperty $ do+ w <- forAll $ G.word32 R.constantBounded+ let Triplet minE e maxE = minMaxExcess1 w+ assert $ minE <= e && e <= maxE+ it "minE2 == minE0 `min` (minE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word32 R.constantBounded+ w1 <- forAll $ G.word32 R.constantBounded+ let w2 = leConcat w0 w1+ let Triplet minE0 e0 _ = minMaxExcess1 w0+ let Triplet minE1 _ _ = minMaxExcess1 w1+ let Triplet minE2 _ _ = minMaxExcess1 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0)" $ requireProperty $ do+ w0 <- forAll $ G.word32 R.constantBounded+ w1 <- forAll $ G.word32 R.constantBounded+ let w2 = leConcat w0 w1+ let Triplet _ e0 maxE0 = minMaxExcess1 w0+ let Triplet _ _ maxE1 = minMaxExcess1 w1+ let Triplet _ _ maxE2 = minMaxExcess1 w2+ maxE2 === maxE0 `max` (maxE1 + e0)+ it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word32 R.constantBounded+ w1 <- forAll $ G.word32 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet minE0 e0 _ = minMaxExcess1 w0+ let Triplet minE1 _ _ = minMaxExcess1 w1+ let Triplet minE2 _ _ = minMaxExcess1 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word32 R.constantBounded+ w1 <- forAll $ G.word32 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet _ e0 maxE0 = minMaxExcess1 w0+ let Triplet _ _ maxE1 = minMaxExcess1 w1+ let Triplet _ _ maxE2 = minMaxExcess1 w2+ maxE2 === maxE0 `max` (maxE1 + e0) describe "For Word64" $ do- it "Excess should be between min excess and max excess" $- property $ \(w :: Word64) ->- let Triplet minE e maxE = minMaxExcess1 w in- minE <= e && e <= maxE- it "minE2 == minE0 `min` (minE1 + e0) via vector" $- property $ \(w0 :: Word64, w1 :: Word64) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet minE0 e0 _ = minMaxExcess1 w0 in- let Triplet minE1 _ _ = minMaxExcess1 w1 in- let Triplet minE2 _ _ = minMaxExcess1 w2 in- minE2 == minE0 `min` (minE1 + e0)- it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $- property $ \(w0 :: Word64, w1 :: Word64) ->- let w2 = DVS.fromList [w0, w1] in- let Triplet _ e0 maxE0 = minMaxExcess1 w0 in- let Triplet _ _ maxE1 = minMaxExcess1 w1 in- let Triplet _ _ maxE2 = minMaxExcess1 w2 in- maxE2 == maxE0 `max` (maxE1 + e0)+ it "Excess should be between min excess and max excess" $ requireProperty $ do+ w <- forAll $ G.word64 R.constantBounded+ let Triplet minE e maxE = minMaxExcess1 w+ assert $ minE <= e && e <= maxE+ it "minE2 == minE0 `min` (minE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word64 R.constantBounded+ w1 <- forAll $ G.word64 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet minE0 e0 _ = minMaxExcess1 w0+ let Triplet minE1 _ _ = minMaxExcess1 w1+ let Triplet minE2 _ _ = minMaxExcess1 w2+ minE2 === minE0 `min` (minE1 + e0)+ it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $ requireProperty $ do+ w0 <- forAll $ G.word64 R.constantBounded+ w1 <- forAll $ G.word64 R.constantBounded+ let w2 = DVS.fromList [w0, w1]+ let Triplet _ e0 maxE0 = minMaxExcess1 w0+ let Triplet _ _ maxE1 = minMaxExcess1 w1+ let Triplet _ _ maxE2 = minMaxExcess1 w2+ maxE2 === maxE0 `max` (maxE1 + e0) describe "Equivalent to native implementation" $ do- it "For Word8" $ do- property $ \(w :: Word8) ->- minMaxExcess1 w == minMaxExcess1 (Naive w)- it "For Word16" $ do- property $ \(w :: Word16) ->- minMaxExcess1 w == minMaxExcess1 (Naive w)- it "For Word32" $ do- property $ \(w :: Word32) ->- minMaxExcess1 w == minMaxExcess1 (Naive w)- it "For Word64" $ do- property $ \(w :: Word64) ->- minMaxExcess1 w == minMaxExcess1 (Naive w)+ it "For Word8" $ requireProperty $ do+ w <- forAll $ G.word8 R.constantBounded+ minMaxExcess1 w === minMaxExcess1 (Naive w)+ it "For Word16" $ requireProperty $ do+ w <- forAll $ G.word16 R.constantBounded+ minMaxExcess1 w === minMaxExcess1 (Naive w)+ it "For Word32" $ requireProperty $ do+ w <- forAll $ G.word32 R.constantBounded+ minMaxExcess1 w === minMaxExcess1 (Naive w)+ it "For Word64" $ requireProperty $ do+ w <- forAll $ G.word64 R.constantBounded+ minMaxExcess1 w === minMaxExcess1 (Naive w)