module ForSyDe.Shallow.Utility.BitVector(
BitVector, Parity(..),
intToBitVector, bitVectorToInt,
addEvenParityBit, addOddParityBit, addParityBit,
removeParityBit,
isEvenParity, isOddParity,
isBitVector
)
where
import ForSyDe.Shallow.Core.Vector
type BitVector = Vector Integer
isBitVector :: (Num t, Eq t) =>
Vector t
-> Bool
isBitVector NullV = True
isBitVector (x:>xs) = (x `elem` [0, 1]) && isBitVector xs
intToBitVector :: Int
-> Integer
-> BitVector
intToBitVector bits n | n >= 0 && n < 2^(bits-1)
= intToBitVector' bits n
intToBitVector bits n | n < 0 && abs n <= 2^(bits-1)
= intToBitVector' bits (n + 2^bits)
intToBitVector _ _ | otherwise =
error "intToBitvector : Number out of range!"
intToBitVector' :: (Num a, Ord a1, Num a1, Integral t) =>
t -> a1 -> Vector a
intToBitVector' 0 _ = NullV
intToBitVector' bits n = if n >= 2^(bits-1) then
1 :> intToBitVector' (bits-1) (n - 2^(bits-1))
else
0 :> intToBitVector' (bits-1) n
bitVectorToInt :: BitVector -> Integer
bitVectorToInt (1:>xv) | isBitVector xv
= bitVectorToInt' xv (lengthV xv) - 2 ^ lengthV xv
bitVectorToInt (0:>xv) | isBitVector xv
= bitVectorToInt' xv (lengthV xv)
bitVectorToInt _ = error "bitVectorToInt: Vector is not a BitVector!"
bitVectorToInt' :: (Integral a, Num t) => Vector t -> a -> t
bitVectorToInt' NullV _ = 0
bitVectorToInt' (x:>xv) bit = x * 2^(bit-1) + bitVectorToInt' xv (bit-1)
data Parity = Even | Odd deriving (Show, Eq)
addEvenParityBit :: (Num a, Eq a) => Vector a -> Vector a
addEvenParityBit = addParityBit Even
addOddParityBit :: (Num a, Eq a) => Vector a -> Vector a
addOddParityBit = addParityBit Odd
addParityBit :: (Num a, Eq a) => Parity -> Vector a -> Vector a
addParityBit p v
| isBitVector v = case p of
Even -> resZero even
Odd -> resZero (not even)
| otherwise = error "addParity: Vector is not a BitVector"
where even = evenNumber v
resZero b = v <+> unitV (if b then 0 else 1)
removeParityBit :: (Num t, Eq t) => Vector t -> Vector t
removeParityBit v
| isBitVector v = takeV (lengthV v - 1) v
| otherwise = error "removeParityBit: Vector is not a BitVector "
isEvenParity :: (Num t, Eq t) => Vector t -> Bool
isEvenParity = isParityCorrect Even
isOddParity :: (Num t, Eq t) => Vector t -> Bool
isOddParity = isParityCorrect Odd
isParityCorrect :: (Num t, Eq t) => Parity -> Vector t -> Bool
isParityCorrect Even xv = evenNumber xv
isParityCorrect Odd xv = not $ evenNumber xv
evenNumber :: (Num t, Eq t) => Vector t -> Bool
evenNumber NullV = True
evenNumber (0:>xv) = xor False (evenNumber xv)
evenNumber (1:>xv) = xor True (evenNumber xv)
evenNumber (_:>_) = error "evenNumber: Vector is not a BitVector "
xor :: Bool -> Bool -> Bool
xor True False = True
xor False True = True
xor _ _ = False