module Test.Falsify.Reexported.Generator.Precision (
WordN(..)
, wordN
, properFraction
) where
import Prelude hiding (properFraction)
import Data.Bits
import Data.Word
import GHC.Stack
import Test.Falsify.Internal.Generator
import Test.Falsify.Internal.Range
import Test.Falsify.Internal.SampleTree (sampleValue)
import Test.Falsify.Internal.Search
data WordN = WordN Precision Word64
deriving (Int -> WordN -> ShowS
[WordN] -> ShowS
WordN -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WordN] -> ShowS
$cshowList :: [WordN] -> ShowS
show :: WordN -> String
$cshow :: WordN -> String
showsPrec :: Int -> WordN -> ShowS
$cshowsPrec :: Int -> WordN -> ShowS
Show, WordN -> WordN -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WordN -> WordN -> Bool
$c/= :: WordN -> WordN -> Bool
== :: WordN -> WordN -> Bool
$c== :: WordN -> WordN -> Bool
Eq, Eq WordN
WordN -> WordN -> Bool
WordN -> WordN -> Ordering
WordN -> WordN -> WordN
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: WordN -> WordN -> WordN
$cmin :: WordN -> WordN -> WordN
max :: WordN -> WordN -> WordN
$cmax :: WordN -> WordN -> WordN
>= :: WordN -> WordN -> Bool
$c>= :: WordN -> WordN -> Bool
> :: WordN -> WordN -> Bool
$c> :: WordN -> WordN -> Bool
<= :: WordN -> WordN -> Bool
$c<= :: WordN -> WordN -> Bool
< :: WordN -> WordN -> Bool
$c< :: WordN -> WordN -> Bool
compare :: WordN -> WordN -> Ordering
$ccompare :: WordN -> WordN -> Ordering
Ord)
forgetPrecision :: WordN -> Word64
forgetPrecision :: WordN -> Word64
forgetPrecision (WordN Precision
_ Word64
x) = Word64
x
truncateAt :: Precision -> Word64 -> WordN
truncateAt :: Precision -> Word64 -> WordN
truncateAt Precision
desiredPrecision Word64
x =
Precision -> Word64 -> WordN
WordN Precision
actualPrecision (Word64
x forall a. Bits a => a -> a -> a
.&. Precision -> Word64
mask Precision
actualPrecision)
where
maximumPrecision, actualPrecision :: Precision
maximumPrecision :: Precision
maximumPrecision = Word8 -> Precision
Precision Word8
64
actualPrecision :: Precision
actualPrecision = forall a. Ord a => a -> a -> a
min Precision
desiredPrecision Precision
maximumPrecision
mask :: Precision -> Word64
mask :: Precision -> Word64
mask (Precision Word8
n) = Word64
2 forall a b. (Num a, Integral b) => a -> b -> a
^ Word8
n forall a. Num a => a -> a -> a
- Word64
1
wordN :: Precision -> Gen WordN
wordN :: Precision -> Gen WordN
wordN Precision
p =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Precision -> Word64 -> WordN
truncateAt Precision
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sample -> Word64
sampleValue) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sample -> [Word64]) -> Gen Sample
primWith forall a b. (a -> b) -> a -> b
$
Word64 -> [Word64]
binarySearch
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WordN -> Word64
forgetPrecision
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Precision -> Word64 -> WordN
truncateAt Precision
p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sample -> Word64
sampleValue
mkFraction :: WordN -> ProperFraction
mkFraction :: WordN -> ProperFraction
mkFraction (WordN (Precision Word8
p) Word64
x) =
Double -> ProperFraction
ProperFraction forall a b. (a -> b) -> a -> b
$ (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x) forall a. Fractional a => a -> a -> a
/ (Double
2 forall a b. (Num a, Integral b) => a -> b -> a
^ Word8
p)
properFraction :: HasCallStack => Precision -> Gen ProperFraction
properFraction :: HasCallStack => Precision -> Gen ProperFraction
properFraction (Precision Word8
0) = forall a. HasCallStack => String -> a
error String
"fraction: 0 precision"
properFraction Precision
p = WordN -> ProperFraction
mkFraction forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Precision -> Gen WordN
wordN Precision
p