{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 908
{-# OPTIONS_GHC -Wno-x-partial #-}
#endif
module Test.Util.Range (
Range (..)
, RangeK (..)
, range
, rangeK
) where
import qualified Data.List as L
import Data.Word
import Ouroboros.Consensus.Config.SecurityParam
data RangeK =
Range_Eq_K SecurityParam
| Range_Just_Below_K SecurityParam Word64
| Range_Just_Above_K SecurityParam Word64
| Range_Near_Zero SecurityParam Word64
| Range_Less_Than_K SecurityParam Word64
| Range_More_Than_K SecurityParam Word64
deriving (RangeK -> RangeK -> Bool
(RangeK -> RangeK -> Bool)
-> (RangeK -> RangeK -> Bool) -> Eq RangeK
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RangeK -> RangeK -> Bool
== :: RangeK -> RangeK -> Bool
$c/= :: RangeK -> RangeK -> Bool
/= :: RangeK -> RangeK -> Bool
Eq)
instance Show RangeK where
show :: RangeK -> String
show RangeK
r =
case RangeK
r of
Range_Eq_K (SecurityParam Word64
k) -> String
"= (k = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
Range_Just_Below_K (SecurityParam Word64
k) Word64
n -> String
"= (k = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" > " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show (Word64
k Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
n)
Range_Just_Above_K (SecurityParam Word64
k) Word64
n -> String
"= (k = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" < " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show (Word64
k Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
n)
Range_Near_Zero (SecurityParam Word64
k) Word64
n -> String
"= (k = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" >> " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
n
Range_Less_Than_K (SecurityParam Word64
k) Word64
n -> String
"≈ (k = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" >> " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
n
Range_More_Than_K (SecurityParam Word64
k) Word64
n -> String
"≈ (k = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" << " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
n
rangeK :: Integral a => SecurityParam -> a -> RangeK
rangeK :: forall a. Integral a => SecurityParam -> a -> RangeK
rangeK (SecurityParam Word64
k) a
a
| Word64
n Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
k = SecurityParam -> RangeK
Range_Eq_K (Word64 -> SecurityParam
SecurityParam Word64
k)
| Word64
n Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
nearK = SecurityParam -> Word64 -> RangeK
Range_Near_Zero (Word64 -> SecurityParam
SecurityParam Word64
k) Word64
n
| Word64
n Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
k = if Word64
belowK Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
nearK
then SecurityParam -> Word64 -> RangeK
Range_Just_Below_K (Word64 -> SecurityParam
SecurityParam Word64
k) Word64
n
else SecurityParam -> Word64 -> RangeK
Range_Less_Than_K (Word64 -> SecurityParam
SecurityParam Word64
k) (Word64
n Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` Word64
bandSize)
| Bool
otherwise = if Word64
aboveK Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
nearK
then SecurityParam -> Word64 -> RangeK
Range_Just_Above_K (Word64 -> SecurityParam
SecurityParam Word64
k) Word64
n
else SecurityParam -> Word64 -> RangeK
Range_More_Than_K (Word64 -> SecurityParam
SecurityParam Word64
k) ([Word64] -> Word64
forall a. HasCallStack => [a] -> a
head ((Word64 -> Bool) -> [Word64] -> [Word64]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
n) [Word64]
powers))
where
n :: Word64
n = a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a
belowK :: Word64
belowK = Word64
k Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
n
aboveK :: Word64
aboveK = Word64
n Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
k
powers :: [Word64]
powers = [Word64
k Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
2 Word64 -> Int -> Word64
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
i | Int
i <- [Int
0..] :: [Int]]
nearK :: Word64
nearK = Word64
5
bandSize :: Word64
bandSize = Word64 -> Word64 -> Word64
forall a. Ord a => a -> a -> a
max Word64
1 (Word64
k Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`div` Word64
10)
data Range n = R_Eq n | R_Btwn (n, n) | R_Gt n
deriving (Int -> Range n -> ShowS
[Range n] -> ShowS
Range n -> String
(Int -> Range n -> ShowS)
-> (Range n -> String) -> ([Range n] -> ShowS) -> Show (Range n)
forall n. Show n => Int -> Range n -> ShowS
forall n. Show n => [Range n] -> ShowS
forall n. Show n => Range n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall n. Show n => Int -> Range n -> ShowS
showsPrec :: Int -> Range n -> ShowS
$cshow :: forall n. Show n => Range n -> String
show :: Range n -> String
$cshowList :: forall n. Show n => [Range n] -> ShowS
showList :: [Range n] -> ShowS
Show, Range n -> Range n -> Bool
(Range n -> Range n -> Bool)
-> (Range n -> Range n -> Bool) -> Eq (Range n)
forall n. Eq n => Range n -> Range n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall n. Eq n => Range n -> Range n -> Bool
== :: Range n -> Range n -> Bool
$c/= :: forall n. Eq n => Range n -> Range n -> Bool
/= :: Range n -> Range n -> Bool
Eq)
range :: (Ord n, Show n, Num n) => n -> Range n
range :: forall n. (Ord n, Show n, Num n) => n -> Range n
range n
n
| n
n n -> n -> Bool
forall a. Ord a => a -> a -> Bool
> n
limit = n -> Range n
forall n. n -> Range n
R_Gt n
limit
| n
n n -> [n] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`L.elem` [n]
vals = n -> Range n
forall n. n -> Range n
R_Eq n
n
| Bool
otherwise =
case ((n, n) -> Bool) -> [(n, n)] -> Maybe (n, n)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
L.find (\(n
lo, n
hi) -> n
lo n -> n -> Bool
forall a. Ord a => a -> a -> Bool
<= n
n Bool -> Bool -> Bool
&& n
n n -> n -> Bool
forall a. Ord a => a -> a -> Bool
<= n
hi) [(n, n)]
rngs of
Maybe (n, n)
Nothing -> String -> Range n
forall a. HasCallStack => String -> a
error (String -> Range n) -> String -> Range n
forall a b. (a -> b) -> a -> b
$ String
"range: unable to classify " String -> ShowS
forall a. [a] -> [a] -> [a]
++ n -> String
forall a. Show a => a -> String
show n
n
Just (n, n)
rng -> (n, n) -> Range n
forall n. (n, n) -> Range n
R_Btwn (n, n)
rng
where
vals :: [n]
vals = [n
0, n
1, n
2, n
3, n
4]
rngs :: [(n, n)]
rngs = [(n
0, n
1), (n
1, n
2), (n
2, n
3), (n
3, n
4), (n
4, n
5), (n
5, n
10), (n
10, n
20)]
limit :: n
limit = n
20