{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE CPP #-}
module Foundation.Check.Arbitrary
    ( Arbitrary(..)
    , frequency
    , oneof
    , elements
    , between
    ) where

import           Basement.Imports
import           Foundation.Primitive
import           Basement.Nat
import           Basement.Cast (cast)
import           Basement.IntegralConv
import           Basement.Bounded
import           Basement.Types.OffsetSize
import qualified Basement.Types.Char7 as Char7
import           Basement.Types.Word128 (Word128(..))
import           Basement.Types.Word256 (Word256(..))
#if __GLASGOW_HASKELL__ >= 710
import qualified Basement.Sized.List as ListN
#endif
import           Foundation.Check.Gen
import           Foundation.Random
import           Foundation.Bits
import           Foundation.Collection
import           Foundation.Numerical
import           Control.Monad (replicateM)

-- | How to generate an arbitrary value for 'a'
class Arbitrary a where
    arbitrary :: Gen a

instance Arbitrary Integer where
    arbitrary :: Gen Integer
arbitrary = Gen Integer
arbitraryInteger
instance Arbitrary Natural where
    arbitrary :: Gen Natural
arbitrary = Gen Natural
arbitraryNatural

instance (NatWithinBound Word64 n, KnownNat n) => Arbitrary (Zn64 n) where
    arbitrary :: Gen (Zn64 n)
arbitrary = Word64 -> Zn64 n
forall (n :: Nat).
(KnownNat n, NatWithinBound Word64 n) =>
Word64 -> Zn64 n
zn64 (Word64 -> Zn64 n) -> Gen Word64 -> Gen (Zn64 n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
forall a. Arbitrary a => Gen a
arbitrary
instance KnownNat n => Arbitrary (Zn n) where
    arbitrary :: Gen (Zn n)
arbitrary = Natural -> Zn n
forall (n :: Nat). KnownNat n => Natural -> Zn n
zn (Natural -> Zn n) -> Gen Natural -> Gen (Zn n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Natural
arbitraryNatural

-- prim types
instance Arbitrary Int where
    arbitrary :: Gen Int
arbitrary = Int64 -> Int
int64ToInt (Int64 -> Int) -> Gen Int64 -> Gen Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Int64
arbitraryInt64
instance Arbitrary Word where
    arbitrary :: Gen Word
arbitrary = Word64 -> Word
word64ToWord (Word64 -> Word) -> Gen Word64 -> Gen Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64
instance Arbitrary Word256 where
    arbitrary :: Gen Word256
arbitrary = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64 -> Word64 -> Word64 -> Word64 -> Word256)
-> Gen Word64 -> Gen (Word64 -> Word64 -> Word64 -> Word256)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64 Gen (Word64 -> Word64 -> Word64 -> Word256)
-> Gen Word64 -> Gen (Word64 -> Word64 -> Word256)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word64
arbitraryWord64 Gen (Word64 -> Word64 -> Word256)
-> Gen Word64 -> Gen (Word64 -> Word256)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word64
arbitraryWord64 Gen (Word64 -> Word256) -> Gen Word64 -> Gen Word256
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word64
arbitraryWord64
instance Arbitrary Word128 where
    arbitrary :: Gen Word128
arbitrary = Word64 -> Word64 -> Word128
Word128 (Word64 -> Word64 -> Word128)
-> Gen Word64 -> Gen (Word64 -> Word128)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64 Gen (Word64 -> Word128) -> Gen Word64 -> Gen Word128
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Word64
arbitraryWord64
instance Arbitrary Word64 where
    arbitrary :: Gen Word64
arbitrary = Gen Word64
arbitraryWord64
instance Arbitrary Word32 where
    arbitrary :: Gen Word32
arbitrary = Word64 -> Word32
forall a b. IntegralDownsize a b => a -> b
integralDownsize (Word64 -> Word32) -> Gen Word64 -> Gen Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64
instance Arbitrary Word16 where
    arbitrary :: Gen Word16
arbitrary = Word64 -> Word16
forall a b. IntegralDownsize a b => a -> b
integralDownsize (Word64 -> Word16) -> Gen Word64 -> Gen Word16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64
instance Arbitrary Word8 where
    arbitrary :: Gen Word8
arbitrary = Word64 -> Word8
forall a b. IntegralDownsize a b => a -> b
integralDownsize (Word64 -> Word8) -> Gen Word64 -> Gen Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64
instance Arbitrary Int64 where
    arbitrary :: Gen Int64
arbitrary = Gen Int64
arbitraryInt64
instance Arbitrary Int32 where
    arbitrary :: Gen Int32
arbitrary = Int64 -> Int32
forall a b. IntegralDownsize a b => a -> b
integralDownsize (Int64 -> Int32) -> Gen Int64 -> Gen Int32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Int64
arbitraryInt64
instance Arbitrary Int16 where
    arbitrary :: Gen Int16
arbitrary = Int64 -> Int16
forall a b. IntegralDownsize a b => a -> b
integralDownsize (Int64 -> Int16) -> Gen Int64 -> Gen Int16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Int64
arbitraryInt64
instance Arbitrary Int8 where
    arbitrary :: Gen Int8
arbitrary = Int64 -> Int8
forall a b. IntegralDownsize a b => a -> b
integralDownsize (Int64 -> Int8) -> Gen Int64 -> Gen Int8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Int64
arbitraryInt64
instance Arbitrary Char where
    arbitrary :: Gen Char
arbitrary = Gen Char
arbitraryChar
instance Arbitrary Char7 where
    arbitrary :: Gen Char7
arbitrary = Word8 -> Char7
Char7.fromByteMask (Word8 -> Char7) -> (Word64 -> Word8) -> Word64 -> Char7
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Word64 -> Word8
forall a b. IntegralDownsize a b => a -> b
integralDownsize (Word64 -> Char7) -> Gen Word64 -> Gen Char7
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64
instance Arbitrary (CountOf ty) where
    arbitrary :: Gen (CountOf ty)
arbitrary = Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf (Int -> CountOf ty) -> Gen Int -> Gen (CountOf ty)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Int
forall a. Arbitrary a => Gen a
arbitrary

instance Arbitrary Bool where
    arbitrary :: Gen Bool
arbitrary = (Word64 -> Int -> Bool) -> Int -> Word64 -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Int
0 (Word64 -> Bool) -> Gen Word64 -> Gen Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64

instance Arbitrary String where
    arbitrary :: Gen String
arbitrary = (GenParams -> Gen String) -> Gen String
forall a. (GenParams -> Gen a) -> Gen a
genWithParams ((GenParams -> Gen String) -> Gen String)
-> (GenParams -> Gen String) -> Gen String
forall a b. (a -> b) -> a -> b
$ \GenParams
params ->
        [Char] -> String
forall l. IsList l => [Item l] -> l
fromList ([Char] -> String) -> Gen [Char] -> Gen String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word -> Gen Word
genMax (GenParams -> Word
genMaxSizeString GenParams
params) Gen Word -> (Word -> Gen [Char]) -> Gen [Char]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word
i -> Int -> Gen Char -> Gen [Char]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word -> Int
forall source destination.
Cast source destination =>
source -> destination
cast Word
i) Gen Char
forall a. Arbitrary a => Gen a
arbitrary)

instance Arbitrary AsciiString where
    arbitrary :: Gen AsciiString
arbitrary = (GenParams -> Gen AsciiString) -> Gen AsciiString
forall a. (GenParams -> Gen a) -> Gen a
genWithParams ((GenParams -> Gen AsciiString) -> Gen AsciiString)
-> (GenParams -> Gen AsciiString) -> Gen AsciiString
forall a b. (a -> b) -> a -> b
$ \GenParams
params ->
        [Char7] -> AsciiString
forall l. IsList l => [Item l] -> l
fromList ([Char7] -> AsciiString) -> Gen [Char7] -> Gen AsciiString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word -> Gen Word
genMax (GenParams -> Word
genMaxSizeString GenParams
params) Gen Word -> (Word -> Gen [Char7]) -> Gen [Char7]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word
i -> Int -> Gen Char7 -> Gen [Char7]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word -> Int
forall source destination.
Cast source destination =>
source -> destination
cast Word
i) Gen Char7
forall a. Arbitrary a => Gen a
arbitrary)

instance Arbitrary Float where
    arbitrary :: Gen Float
arbitrary = Gen Float
arbitraryF32
instance Arbitrary Double where
    arbitrary :: Gen Double
arbitrary = Gen Double
arbitraryF64

instance Arbitrary a => Arbitrary (Maybe a) where
    arbitrary :: Gen (Maybe a)
arbitrary = NonEmpty [(Word, Gen (Maybe a))] -> Gen (Maybe a)
forall a. NonEmpty [(Word, Gen a)] -> Gen a
frequency (NonEmpty [(Word, Gen (Maybe a))] -> Gen (Maybe a))
-> NonEmpty [(Word, Gen (Maybe a))] -> Gen (Maybe a)
forall a b. (a -> b) -> a -> b
$ [(Word, Gen (Maybe a))] -> NonEmpty [(Word, Gen (Maybe a))]
forall c. Collection c => c -> NonEmpty c
nonEmpty_ [ (Word
1, Maybe a -> Gen (Maybe a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing), (Word
4, a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> Gen a -> Gen (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
forall a. Arbitrary a => Gen a
arbitrary) ]

instance (Arbitrary l, Arbitrary r) => Arbitrary (Either l r) where
    arbitrary :: Gen (Either l r)
arbitrary = NonEmpty [Gen (Either l r)] -> Gen (Either l r)
forall a. NonEmpty [Gen a] -> Gen a
oneof (NonEmpty [Gen (Either l r)] -> Gen (Either l r))
-> NonEmpty [Gen (Either l r)] -> Gen (Either l r)
forall a b. (a -> b) -> a -> b
$ [Gen (Either l r)] -> NonEmpty [Gen (Either l r)]
forall c. Collection c => c -> NonEmpty c
nonEmpty_ [ l -> Either l r
forall a b. a -> Either a b
Left (l -> Either l r) -> Gen l -> Gen (Either l r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen l
forall a. Arbitrary a => Gen a
arbitrary, r -> Either l r
forall a b. b -> Either a b
Right (r -> Either l r) -> Gen r -> Gen (Either l r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen r
forall a. Arbitrary a => Gen a
arbitrary ]

instance (Arbitrary a, Arbitrary b)
    => Arbitrary (a,b) where
    arbitrary :: Gen (a, b)
arbitrary = (,) (a -> b -> (a, b)) -> Gen a -> Gen (b -> (a, b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
forall a. Arbitrary a => Gen a
arbitrary Gen (b -> (a, b)) -> Gen b -> Gen (a, b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen b
forall a. Arbitrary a => Gen a
arbitrary
instance (Arbitrary a, Arbitrary b, Arbitrary c)
    => Arbitrary (a,b,c) where
    arbitrary :: Gen (a, b, c)
arbitrary = (,,) (a -> b -> c -> (a, b, c)) -> Gen a -> Gen (b -> c -> (a, b, c))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
forall a. Arbitrary a => Gen a
arbitrary Gen (b -> c -> (a, b, c)) -> Gen b -> Gen (c -> (a, b, c))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen b
forall a. Arbitrary a => Gen a
arbitrary Gen (c -> (a, b, c)) -> Gen c -> Gen (a, b, c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen c
forall a. Arbitrary a => Gen a
arbitrary
instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d)
    => Arbitrary (a,b,c,d) where
    arbitrary :: Gen (a, b, c, d)
arbitrary = (,,,) (a -> b -> c -> d -> (a, b, c, d))
-> Gen a -> Gen (b -> c -> d -> (a, b, c, d))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
forall a. Arbitrary a => Gen a
arbitrary Gen (b -> c -> d -> (a, b, c, d))
-> Gen b -> Gen (c -> d -> (a, b, c, d))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen b
forall a. Arbitrary a => Gen a
arbitrary Gen (c -> d -> (a, b, c, d)) -> Gen c -> Gen (d -> (a, b, c, d))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen c
forall a. Arbitrary a => Gen a
arbitrary Gen (d -> (a, b, c, d)) -> Gen d -> Gen (a, b, c, d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen d
forall a. Arbitrary a => Gen a
arbitrary
instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d, Arbitrary e)
    => Arbitrary (a,b,c,d,e) where
    arbitrary :: Gen (a, b, c, d, e)
arbitrary = (,,,,) (a -> b -> c -> d -> e -> (a, b, c, d, e))
-> Gen a -> Gen (b -> c -> d -> e -> (a, b, c, d, e))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
forall a. Arbitrary a => Gen a
arbitrary Gen (b -> c -> d -> e -> (a, b, c, d, e))
-> Gen b -> Gen (c -> d -> e -> (a, b, c, d, e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen b
forall a. Arbitrary a => Gen a
arbitrary Gen (c -> d -> e -> (a, b, c, d, e))
-> Gen c -> Gen (d -> e -> (a, b, c, d, e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen c
forall a. Arbitrary a => Gen a
arbitrary Gen (d -> e -> (a, b, c, d, e))
-> Gen d -> Gen (e -> (a, b, c, d, e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen d
forall a. Arbitrary a => Gen a
arbitrary Gen (e -> (a, b, c, d, e)) -> Gen e -> Gen (a, b, c, d, e)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen e
forall a. Arbitrary a => Gen a
arbitrary
instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d, Arbitrary e, Arbitrary f)
    => Arbitrary (a,b,c,d,e,f) where
    arbitrary :: Gen (a, b, c, d, e, f)
arbitrary = (,,,,,) (a -> b -> c -> d -> e -> f -> (a, b, c, d, e, f))
-> Gen a -> Gen (b -> c -> d -> e -> f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
forall a. Arbitrary a => Gen a
arbitrary Gen (b -> c -> d -> e -> f -> (a, b, c, d, e, f))
-> Gen b -> Gen (c -> d -> e -> f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen b
forall a. Arbitrary a => Gen a
arbitrary Gen (c -> d -> e -> f -> (a, b, c, d, e, f))
-> Gen c -> Gen (d -> e -> f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen c
forall a. Arbitrary a => Gen a
arbitrary Gen (d -> e -> f -> (a, b, c, d, e, f))
-> Gen d -> Gen (e -> f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen d
forall a. Arbitrary a => Gen a
arbitrary Gen (e -> f -> (a, b, c, d, e, f))
-> Gen e -> Gen (f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen e
forall a. Arbitrary a => Gen a
arbitrary Gen (f -> (a, b, c, d, e, f)) -> Gen f -> Gen (a, b, c, d, e, f)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen f
forall a. Arbitrary a => Gen a
arbitrary

instance Arbitrary a => Arbitrary [a] where
    arbitrary :: Gen [a]
arbitrary = (GenParams -> Gen [a]) -> Gen [a]
forall a. (GenParams -> Gen a) -> Gen a
genWithParams ((GenParams -> Gen [a]) -> Gen [a])
-> (GenParams -> Gen [a]) -> Gen [a]
forall a b. (a -> b) -> a -> b
$ \GenParams
params ->
        [a] -> [a]
forall l. IsList l => [Item l] -> l
fromList ([a] -> [a]) -> Gen [a] -> Gen [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word -> Gen Word
genMax (GenParams -> Word
genMaxSizeArray GenParams
params) Gen Word -> (Word -> Gen [a]) -> Gen [a]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word
i -> Int -> Gen a -> Gen [a]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word -> Int
forall source destination.
Cast source destination =>
source -> destination
cast Word
i) Gen a
forall a. Arbitrary a => Gen a
arbitrary)
#if __GLASGOW_HASKELL__ >= 710
instance (Arbitrary a, KnownNat n, NatWithinBound Int n) => Arbitrary (ListN.ListN n a) where
    arbitrary :: Gen (ListN n a)
arbitrary = Gen a -> Gen (ListN n a)
forall (n :: Nat) (m :: * -> *) a.
(NatWithinBound Int n, Monad m, KnownNat n) =>
m a -> m (ListN n a)
ListN.replicateM Gen a
forall a. Arbitrary a => Gen a
arbitrary
#endif

arbitraryInteger :: Gen Integer
arbitraryInteger :: Gen Integer
arbitraryInteger =
    -- TODO use the sized parameter
    NonEmpty [(Word, Gen Integer)] -> Gen Integer
forall a. NonEmpty [(Word, Gen a)] -> Gen a
frequency (NonEmpty [(Word, Gen Integer)] -> Gen Integer)
-> NonEmpty [(Word, Gen Integer)] -> Gen Integer
forall a b. (a -> b) -> a -> b
$ [(Word, Gen Integer)] -> NonEmpty [(Word, Gen Integer)]
forall c. Collection c => c -> NonEmpty c
nonEmpty_
        [ (Word
4, Bool -> Word -> Gen Integer
integerOfSize Bool
True Word
2)
        , (Word
4, Bool -> Word -> Gen Integer
integerOfSize Bool
False Word
2)
        , (Word
4, Bool -> Word -> Gen Integer
integerOfSize Bool
True Word
4)
        , (Word
4, Bool -> Word -> Gen Integer
integerOfSize Bool
False Word
4)
        , (Word
2, Bool -> Word -> Gen Integer
integerOfSize Bool
True Word
8)
        , (Word
2, Bool -> Word -> Gen Integer
integerOfSize Bool
False Word
8)
        , (Word
1, Bool -> Word -> Gen Integer
integerOfSize Bool
True Word
16)
        , (Word
1, Bool -> Word -> Gen Integer
integerOfSize Bool
False Word
16)
        ]
  where
    integerOfSize :: Bool -> Word -> Gen Integer
    integerOfSize :: Bool -> Word -> Gen Integer
integerOfSize Bool
toSign Word
n = ((if Bool
toSign then Integer -> Integer
forall a. HasNegation a => a -> a
negate else Integer -> Integer
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id) (Integer -> Integer)
-> (UArray Word8 -> Integer) -> UArray Word8 -> Integer
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Integer -> Element [Word8] -> Integer)
-> Integer -> [Word8] -> Integer
forall collection a.
Foldable collection =>
(a -> Element collection -> a) -> a -> collection -> a
foldl' (\Integer
x Element [Word8]
y -> Integer
x Integer -> Integer -> Integer
forall a. Additive a => a -> a -> a
+ Word8 -> Integer
forall a b. IntegralUpsize a b => a -> b
integralUpsize Word8
Element [Word8]
y) Integer
0 ([Word8] -> Integer)
-> (UArray Word8 -> [Word8]) -> UArray Word8 -> Integer
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. UArray Word8 -> [Word8]
forall l. IsList l => l -> [Item l]
toList)
                         (UArray Word8 -> Integer) -> Gen (UArray Word8) -> Gen Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word -> Gen (UArray Word8)
forall ty. (PrimType ty, Arbitrary ty) => Word -> Gen (UArray ty)
arbitraryUArrayOf Word
n :: Gen (UArray Word8))

arbitraryNatural :: Gen Natural
arbitraryNatural :: Gen Natural
arbitraryNatural = Integer -> Natural
forall a b. IntegralDownsize a b => a -> b
integralDownsize (Integer -> Natural) -> (Integer -> Integer) -> Integer -> Natural
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Integer -> Integer
forall a. Signed a => a -> a
abs (Integer -> Natural) -> Gen Integer -> Gen Natural
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Integer
arbitraryInteger

arbitraryChar :: Gen Char
arbitraryChar :: Gen Char
arbitraryChar = NonEmpty [(Word, Gen Char)] -> Gen Char
forall a. NonEmpty [(Word, Gen a)] -> Gen a
frequency (NonEmpty [(Word, Gen Char)] -> Gen Char)
-> NonEmpty [(Word, Gen Char)] -> Gen Char
forall a b. (a -> b) -> a -> b
$ [(Word, Gen Char)] -> NonEmpty [(Word, Gen Char)]
forall c. Collection c => c -> NonEmpty c
nonEmpty_
    [ (Word
6, Word -> Char
wordToChar (Word -> Char) -> Gen Word -> Gen Char
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word -> Gen Word
genMax Word
128)
    , (Word
1, Word -> Char
wordToChar (Word -> Char) -> Gen Word -> Gen Char
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word -> Gen Word
genMax Word
0x10ffff)
    ]

arbitraryWord64 :: Gen Word64
arbitraryWord64 :: Gen Word64
arbitraryWord64 = (forall (randomly :: * -> *).
 MonadRandom randomly =>
 randomly Word64)
-> Gen Word64
forall a.
(forall (randomly :: * -> *). MonadRandom randomly => randomly a)
-> Gen a
genWithRng forall (randomly :: * -> *).
MonadRandom randomly =>
randomly Word64
getRandomWord64

arbitraryInt64 :: Gen Int64
arbitraryInt64 :: Gen Int64
arbitraryInt64 = Word64 -> Int64
forall source destination.
Cast source destination =>
source -> destination
cast (Word64 -> Int64) -> Gen Word64 -> Gen Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word64
arbitraryWord64

arbitraryF64 :: Gen Double
arbitraryF64 :: Gen Double
arbitraryF64 = (forall (randomly :: * -> *).
 MonadRandom randomly =>
 randomly Double)
-> Gen Double
forall a.
(forall (randomly :: * -> *). MonadRandom randomly => randomly a)
-> Gen a
genWithRng forall (randomly :: * -> *).
MonadRandom randomly =>
randomly Double
getRandomF64

arbitraryF32 :: Gen Float
arbitraryF32 :: Gen Float
arbitraryF32 = (forall (randomly :: * -> *).
 MonadRandom randomly =>
 randomly Float)
-> Gen Float
forall a.
(forall (randomly :: * -> *). MonadRandom randomly => randomly a)
-> Gen a
genWithRng forall (randomly :: * -> *). MonadRandom randomly => randomly Float
getRandomF32

arbitraryUArrayOf :: (PrimType ty, Arbitrary ty) => Word -> Gen (UArray ty)
arbitraryUArrayOf :: Word -> Gen (UArray ty)
arbitraryUArrayOf Word
size = (Word, Word) -> Gen Word
between (Word
0, Word
size) Gen Word -> (Word -> Gen (UArray ty)) -> Gen (UArray ty)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
    \Word
sz -> [ty] -> UArray ty
forall l. IsList l => [Item l] -> l
fromList ([ty] -> UArray ty) -> Gen [ty] -> Gen (UArray ty)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen ty -> Gen [ty]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word -> Int
forall source destination.
Cast source destination =>
source -> destination
cast Word
sz) Gen ty
forall a. Arbitrary a => Gen a
arbitrary

-- | Call one of the generator weighted
frequency :: NonEmpty [(Word, Gen a)] -> Gen a
frequency :: NonEmpty [(Word, Gen a)] -> Gen a
frequency (NonEmpty [(Word, Gen a)] -> [(Word, Gen a)]
forall a. NonEmpty a -> a
getNonEmpty -> [(Word, Gen a)]
l) = (Word, Word) -> Gen Word
between (Word
0, Word
sum) Gen Word -> (Word -> Gen a) -> Gen a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(Word, Gen a)] -> Word -> Gen a
forall t p.
(Ord t, Subtractive t, Difference t ~ t) =>
[(t, p)] -> t -> p
pickOne [(Word, Gen a)]
l
  where
    sum :: Word
    !sum :: Word
sum = (Word -> Element [Word] -> Word) -> Word -> [Word] -> Word
forall collection a.
Foldable collection =>
(a -> Element collection -> a) -> a -> collection -> a
foldl' Word -> Element [Word] -> Word
forall a. Additive a => a -> a -> a
(+) Word
0 ([Word] -> Word) -> [Word] -> Word
forall a b. (a -> b) -> a -> b
$ ((Word, Gen a) -> Word) -> [(Word, Gen a)] -> [Word]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Word, Gen a) -> Word
forall a b. (a, b) -> a
fst [(Word, Gen a)]
l

    pickOne :: [(t, p)] -> t -> p
pickOne ((t
k,p
x):[(t, p)]
xs) t
n
        | t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
<= t
k    = p
x
        | Bool
otherwise = [(t, p)] -> t -> p
pickOne [(t, p)]
xs (t
nt -> t -> Difference t
forall a. Subtractive a => a -> a -> Difference a
-t
k)
    pickOne [(t, p)]
_ t
_ = String -> p
forall a. HasCallStack => String -> a
error String
"frequency"

oneof :: NonEmpty [Gen a] -> Gen a
oneof :: NonEmpty [Gen a] -> Gen a
oneof NonEmpty [Gen a]
ne = NonEmpty [(Word, Gen a)] -> Gen a
forall a. NonEmpty [(Word, Gen a)] -> Gen a
frequency ((Gen a -> (Word, Gen a))
-> NonEmpty [Gen a] -> NonEmpty [(Word, Gen a)]
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> NonEmpty (f a) -> NonEmpty (f b)
nonEmptyFmap (\Gen a
x -> (Word
1, Gen a
x)) NonEmpty [Gen a]
ne)

elements :: NonEmpty [a] -> Gen a
elements :: NonEmpty [a] -> Gen a
elements NonEmpty [a]
l = NonEmpty [(Word, Gen a)] -> Gen a
forall a. NonEmpty [(Word, Gen a)] -> Gen a
frequency ((a -> (Word, Gen a)) -> NonEmpty [a] -> NonEmpty [(Word, Gen a)]
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> NonEmpty (f a) -> NonEmpty (f b)
nonEmptyFmap (\a
x -> (Word
1, a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x)) NonEmpty [a]
l)

between :: (Word, Word) -> Gen Word
between :: (Word, Word) -> Gen Word
between (Word
x,Word
y)
    | Word
Difference Word
range Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0 = Word -> Gen Word
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word
x
    | Bool
otherwise = Word -> Word -> Word
forall a. Additive a => a -> a -> a
(+) Word
x (Word -> Word) -> Gen Word -> Gen Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word -> Gen Word
genMax Word
Difference Word
range
  where range :: Difference Word
range = Word
y Word -> Word -> Difference Word
forall a. Subtractive a => a -> a -> Difference a
- Word
x

genMax :: Word -> Gen Word
genMax :: Word -> Gen Word
genMax Word
m = (Word -> Word -> Word) -> Word -> Word -> Word
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word -> Word -> Word
forall a. IDivisible a => a -> a -> a
mod Word
m (Word -> Word) -> Gen Word -> Gen Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word
forall a. Arbitrary a => Gen a
arbitrary