bv 0.4.1 → 0.5
raw patch · 4 files changed
+89/−25 lines, 4 filesdep ~QuickCheckdep ~integer-gmpdep ~test-framework-quickcheck2PVP ok
version bump matches the API change (PVP)
Dependency ranges changed: QuickCheck, integer-gmp, test-framework-quickcheck2, test-framework-th
API changes (from Hackage documentation)
- Data.BitVector: instance Bits BV
- Data.BitVector: instance Data BV
- Data.BitVector: instance Enum BV
- Data.BitVector: instance Eq BV
- Data.BitVector: instance Integral BV
- Data.BitVector: instance Monoid BV
- Data.BitVector: instance Num BV
- Data.BitVector: instance Ord BV
- Data.BitVector: instance Real BV
- Data.BitVector: instance Show BV
- Data.BitVector: instance Typeable BV
+ Data.BitVector: infix 4 `sge`
+ Data.BitVector: infixl 8 `ror`
+ Data.BitVector: infixl 9 !.
+ Data.BitVector: infixr 5 #
+ Data.BitVector: instance Data.Bits.Bits Data.BitVector.BV
+ Data.BitVector: instance Data.Data.Data Data.BitVector.BV
+ Data.BitVector: instance GHC.Base.Monoid Data.BitVector.BV
+ Data.BitVector: instance GHC.Classes.Eq Data.BitVector.BV
+ Data.BitVector: instance GHC.Classes.Ord Data.BitVector.BV
+ Data.BitVector: instance GHC.Enum.Enum Data.BitVector.BV
+ Data.BitVector: instance GHC.Num.Num Data.BitVector.BV
+ Data.BitVector: instance GHC.Read.Read Data.BitVector.BV
+ Data.BitVector: instance GHC.Real.Integral Data.BitVector.BV
+ Data.BitVector: instance GHC.Real.Real Data.BitVector.BV
+ Data.BitVector: instance GHC.Show.Show Data.BitVector.BV
Files
- CHANGES.md +14/−0
- bv.cabal +6/−5
- src/Data/BitVector.hs +52/−18
- test/Properties.hs +17/−2
CHANGES.md view
@@ -1,4 +1,18 @@ +0.5.0+=====++Note that changes in `fromInteger` and `toInteger` implementations break backwards compatibility.+I hope this will not cause major problems, let me know otherwise.++* Make _bv_ with compatible with GHC 8.4.1 (_base_ 4.11). Thanks to Kosyrev Serge!+* Define `toInteger` as `int` rather than `nat`.+* Make `fromInteger` consistent and always encode in two's complement, also positive integers.+* As a result of the two previous changes, now `toInteger . fromInteger == id`, as it should be.+* Add `Read BV` instance (based on `Text.Read`, so GHC-only).+* Fix a few bugs in the non-GMP implementation. (Fortunately, GMP is the default.)+* Remove upper bounds on testing dependencies.+ 0.4.1 =====
bv.cabal view
@@ -1,6 +1,6 @@ Name: bv-Version: 0.4.1+Version: 0.5 Synopsis: Bit-vector arithmetic library Description: Bit-vectors implemented as a thin wrapper over integers. Homepage: https://github.com/iagoabal/haskell-bv@@ -52,15 +52,16 @@ Other-Extensions: BangPatterns, DeriveDataTypeable, MagicHash Build-depends: base >=4.6 && <5 if impl(ghc) && flag(gmp)- Build-depends: integer-gmp, ghc-prim+ Build-depends: integer-gmp >=0.5.1,+ ghc-prim Executable bv-tester if flag(test) Buildable: True Build-depends: base >=4.6 && <5,- QuickCheck >=2.4 && < 2.7,- test-framework-quickcheck2 ==0.3.*,- test-framework-th ==0.2.*+ QuickCheck >=2.4,+ test-framework-quickcheck2 >=0.3,+ test-framework-th >=0.2 else Buildable: False
src/Data/BitVector.hs view
@@ -3,7 +3,9 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} -#if MIN_VERSION_integer_gmp(0,5,1)+-- NOTE: defined(MIN_VERSION_integer_gmp) == package configured with -fgmp++#if defined(MIN_VERSION_integer_gmp) {-# LANGUAGE MagicHash #-} #endif @@ -23,7 +25,7 @@ -- * Bit-vectors are interpreted as unsigned integers -- (i.e. natural numbers) except for some specific /signed/ operations. ----- * Most operations are in some way /size-polymorphic/ and, if required, +-- * Most operations are in some way /size-polymorphic/ and, if required, -- will perform padding to adjust the size of input bit-vectors. -- -- For documentation purposes we will write @[n]k@ to denote a bit-vector@@ -86,6 +88,7 @@ , showHex ) where +import Control.Monad ( Monad(..), when ) import Control.Exception ( assert ) import Data.Bits@@ -95,12 +98,17 @@ import qualified Data.List as List import Data.Monoid ( Monoid(..) ) import Data.Ord+#ifdef __GLASGOW_HASKELL__+import qualified Text.Read as R+#endif import Data.Typeable ( Typeable ) -#if MIN_VERSION_integer_gmp(0,5,1)+#if defined(MIN_VERSION_integer_gmp) import qualified GHC.Integer.Logarithms as I import GHC.Prim ( (+#) ) import GHC.Types ( Int(..) )+#else+import Data.Int ( Int ) #endif import Prelude@@ -110,6 +118,9 @@ , Integral(..), Integer , Maybe(..) , Real(..)+#if MIN_VERSION_base(4,11,0)+ , Semigroup(..)+#endif , Show(..), String , const , error@@ -162,6 +173,18 @@ instance Show BV where show (BV n a) = "[" ++ show n ++ "]" ++ show a +#ifdef __GLASGOW_HASKELL__+instance R.Read BV where+ readPrec = do+ R.Punc "[" <- R.lexP+ n <- R.step R.readPrec+ when (n < 0) R.pfail+ R.Punc "]" <- R.lexP+ a <- R.step R.readPrec+ when (a < 0) R.pfail+ return (bitVec (n::Int) (a::Integer))+#endif+ ---------------------------------------------------------------------- --- Safety checking & Errors @@ -469,12 +492,8 @@ {-# INLINE abs #-} signum u = bitVec 2 $ signum $ int u {-# INLINE signum #-}-#if MIN_VERSION_integer_gmp(0,5,1)- fromInteger i = bitVec n i- where n = I# (I.integerLog2# i +# 1#)-#else- fromInteger i = bitVec (integerWidth i) i-#endif+ fromInteger !i = bitVec n i+ where !n = if i >= 0 then integerWidth i + 1 else integerWidth i {-# INLINE fromInteger #-} -- | Bit-vector 'signum' as an 'Integral'.@@ -496,7 +515,7 @@ {-# INLINE quotRem #-} divMod = quotRem {-# INLINE divMod #-}- toInteger = nat+ toInteger = int {-# INLINE toInteger #-} -- | Bit-vector exponentiation.@@ -537,11 +556,14 @@ lg2 :: BV -> BV lg2 (BV _ 0) = error "Data.BitVector.lg2: zero bit-vector" lg2 (BV n 1) = BV n 0-#if MIN_VERSION_integer_gmp(0,5,1)+#if defined(MIN_VERSION_integer_gmp) lg2 (BV n a) = BV n (toInteger a') where a' = I# (I.integerLog2# a) #else-lg2 (BV n a) = BV n $ toInteger $ integerWidth (a-1)+lg2 (BV n a) = BV n $ go 0 1+ where go !k !b | b == a = k+ | b > a = k-1+ | otherwise = go (k+1) (2*b) #endif {-# INLINE lg2 #-} @@ -566,14 +588,22 @@ concat = join -- This is the most sensible monoid instance until we have size types!+ instance Monoid BV where mempty = nil {-# INLINE mempty #-}- mappend = (#)- {-# INLINE mappend #-} mconcat = join {-# INLINE mconcat #-}+#if !MIN_VERSION_base(4,11,0)+ mappend = (#)+ {-# INLINE mappend #-}+#else +instance Semigroup BV where+ (<>) = (#)+ {-# INLINE (<>) #-}+#endif+ -- | Logical extension. -- -- >>> zeroExtend 3 [1]1@@ -912,19 +942,23 @@ maxNat n = 2^n - 1 {-# INLINE maxNat #-} -#ifndef MIN_VERSION_integer_gmp -- | Minimum width of a bit-vector to represent a given integer number. ----- >>> integerWith 4+-- >>> integerWidth 4 -- 3 ----- >>> integerWith (-4)+-- >>> integerWidth (-4) -- 4 integerWidth :: Integer -> Int+#if defined(MIN_VERSION_integer_gmp) integerWidth !n+ | n >= 0 = I# (I.integerLog2# n +# 1#)+ | otherwise = I# (I.integerLog2# (-n) +# 2#)+#else+integerWidth !n | n >= 0 = go 1 1 | otherwise = 1 + integerWidth (abs n) where go !k !k_max | k_max >= n = k | otherwise = go (k+1) (2*k_max+1)-{-# INLINE integerWidth #-} #endif+{-# INLINE integerWidth #-}
test/Properties.hs view
@@ -93,11 +93,13 @@ let a = nat u in a >= 0 && a < 2^n +-- * fromInteger+ prop_bv_nat :: Integer -> Property prop_bv_nat i = i >= 0 ==> nat(fromInteger i) == i -prop_bv_neg :: Integer -> Property-prop_bv_neg i = i < 0 ==> int(fromInteger i) == i+prop_bv_id :: Integer -> Bool+prop_bv_id i = toInteger (fromInteger i :: BV) == i -- * Indexing @@ -180,6 +182,14 @@ prop_exp_spec a = forAll anExp $ \e -> e /= 0 ==> pow a e ==. a^e +-- * Logarithm++prop_lg2 :: BV -> Property+prop_lg2 a = a /= 0 ==>+ let b = lg2 a in+ 2^(nat b) <= nat a+ && nat a < 2^(nat b + 1)+ -- * Not prop_not_id :: BV -> Bool@@ -256,3 +266,8 @@ prop_group_join_id :: BV -> Property prop_group_join_id a = forallDivisorOf (size a) $ \n -> BV.join (BV.group n a) ==. a++-- * Show & Read++prop_show_read_id :: BV -> Bool+prop_show_read_id a = read (show a) ==. a