{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Cryptol.Testing.Random where
import Cryptol.Eval.Monad (ready,runEval,EvalOpts)
import Cryptol.Eval.Value (BV(..),Value,GenValue(..),SeqMap(..), WordValue(..), BitWord(..))
import qualified Cryptol.Testing.Concrete as Conc
import Cryptol.TypeCheck.AST (Type(..), TCon(..), TC(..), tNoUser, tIsFun)
import Cryptol.TypeCheck.SimpType(tRebuild')
import Cryptol.Utils.Ident (Ident)
import Cryptol.Utils.Panic (panic)
import Control.Monad (forM,join)
import Data.List (unfoldr, genericTake, genericIndex)
import System.Random (RandomGen, split, random, randomR)
import qualified Data.Sequence as Seq
type Gen g b w i = Integer -> g -> (GenValue b w i, g)
runOneTest :: RandomGen g
=> EvalOpts
-> Value
-> [Gen g Bool BV Integer]
-> Integer
-> g
-> IO (Conc.TestResult, g)
runOneTest :: EvalOpts
-> Value
-> [Gen g Bool BV Integer]
-> Integer
-> g
-> IO (TestResult, g)
runOneTest evOpts :: EvalOpts
evOpts fun :: Value
fun argGens :: [Gen g Bool BV Integer]
argGens sz :: Integer
sz g0 :: g
g0 = do
let (args :: [Value]
args, g1 :: g
g1) = (Gen g Bool BV Integer -> ([Value], g) -> ([Value], g))
-> ([Value], g) -> [Gen g Bool BV Integer] -> ([Value], g)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Gen g Bool BV Integer -> ([Value], g) -> ([Value], g)
forall b a b. (Integer -> b -> (a, b)) -> ([a], b) -> ([a], b)
mkArg ([], g
g0) [Gen g Bool BV Integer]
argGens
mkArg :: (Integer -> b -> (a, b)) -> ([a], b) -> ([a], b)
mkArg argGen :: Integer -> b -> (a, b)
argGen (as :: [a]
as, g :: b
g) = let (a :: a
a, g' :: b
g') = Integer -> b -> (a, b)
argGen Integer
sz b
g in (a
aa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
as, b
g')
TestResult
result <- EvalOpts -> Value -> [Value] -> IO TestResult
Conc.runOneTest EvalOpts
evOpts Value
fun [Value]
args
(TestResult, g) -> IO (TestResult, g)
forall (m :: * -> *) a. Monad m => a -> m a
return (TestResult
result, g
g1)
returnOneTest :: RandomGen g
=> EvalOpts
-> Value
-> [Gen g Bool BV Integer]
-> Integer
-> g
-> IO ([Value], Value, g)
returnOneTest :: EvalOpts
-> Value
-> [Gen g Bool BV Integer]
-> Integer
-> g
-> IO ([Value], Value, g)
returnOneTest evOpts :: EvalOpts
evOpts fun :: Value
fun argGens :: [Gen g Bool BV Integer]
argGens sz :: Integer
sz g0 :: g
g0 =
do let (args :: [Value]
args, g1 :: g
g1) = (Gen g Bool BV Integer -> ([Value], g) -> ([Value], g))
-> ([Value], g) -> [Gen g Bool BV Integer] -> ([Value], g)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Gen g Bool BV Integer -> ([Value], g) -> ([Value], g)
forall b a b. (Integer -> b -> (a, b)) -> ([a], b) -> ([a], b)
mkArg ([], g
g0) [Gen g Bool BV Integer]
argGens
mkArg :: (Integer -> b -> (a, b)) -> ([a], b) -> ([a], b)
mkArg argGen :: Integer -> b -> (a, b)
argGen (as :: [a]
as, g :: b
g) = let (a :: a
a, g' :: b
g') = Integer -> b -> (a, b)
argGen Integer
sz b
g in (a
aa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
as, b
g')
Value
result <- EvalOpts -> Eval Value -> IO Value
forall a. EvalOpts -> Eval a -> IO a
runEval EvalOpts
evOpts (Value -> [Value] -> Eval Value
forall b w i.
GenValue b w i -> [GenValue b w i] -> Eval (GenValue b w i)
go Value
fun [Value]
args)
([Value], Value, g) -> IO ([Value], Value, g)
forall (m :: * -> *) a. Monad m => a -> m a
return ([Value]
args, Value
result, g
g1)
where
go :: GenValue b w i -> [GenValue b w i] -> Eval (GenValue b w i)
go (VFun f :: Eval (GenValue b w i) -> Eval (GenValue b w i)
f) (v :: GenValue b w i
v : vs :: [GenValue b w i]
vs) = Eval (Eval (GenValue b w i)) -> Eval (GenValue b w i)
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (GenValue b w i -> [GenValue b w i] -> Eval (GenValue b w i)
go (GenValue b w i -> [GenValue b w i] -> Eval (GenValue b w i))
-> Eval (GenValue b w i)
-> Eval ([GenValue b w i] -> Eval (GenValue b w i))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Eval (GenValue b w i) -> Eval (GenValue b w i)
f (GenValue b w i -> Eval (GenValue b w i)
forall a. a -> Eval a
ready GenValue b w i
v)) Eval ([GenValue b w i] -> Eval (GenValue b w i))
-> Eval [GenValue b w i] -> Eval (Eval (GenValue b w i))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [GenValue b w i] -> Eval [GenValue b w i]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [GenValue b w i]
vs)
go (VFun _) [] = String -> [String] -> Eval (GenValue b w i)
forall a. HasCallStack => String -> [String] -> a
panic "Cryptol.Testing.Random" ["Not enough arguments to function while generating tests"]
go _ (_ : _) = String -> [String] -> Eval (GenValue b w i)
forall a. HasCallStack => String -> [String] -> a
panic "Cryptol.Testing.Random" ["Too many arguments to function while generating tests"]
go v :: GenValue b w i
v [] = GenValue b w i -> Eval (GenValue b w i)
forall (m :: * -> *) a. Monad m => a -> m a
return GenValue b w i
v
returnTests :: RandomGen g
=> g
-> EvalOpts
-> [Gen g Bool BV Integer]
-> Value
-> Int
-> IO [([Value], Value)]
returnTests :: g
-> EvalOpts
-> [Gen g Bool BV Integer]
-> Value
-> Int
-> IO [([Value], Value)]
returnTests g :: g
g evo :: EvalOpts
evo gens :: [Gen g Bool BV Integer]
gens fun :: Value
fun num :: Int
num = [Gen g Bool BV Integer] -> g -> Int -> IO [([Value], Value)]
forall t.
RandomGen t =>
[Gen t Bool BV Integer] -> t -> Int -> IO [([Value], Value)]
go [Gen g Bool BV Integer]
gens g
g 0
where
go :: [Gen t Bool BV Integer] -> t -> Int -> IO [([Value], Value)]
go args :: [Gen t Bool BV Integer]
args g0 :: t
g0 n :: Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
num = [([Value], Value)] -> IO [([Value], Value)]
forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise =
do let sz :: Integer
sz = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Int -> Int
forall a. Integral a => a -> a -> a
div (100 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)) Int
num)
(inputs :: [Value]
inputs, output :: Value
output, g1 :: t
g1) <- EvalOpts
-> Value
-> [Gen t Bool BV Integer]
-> Integer
-> t
-> IO ([Value], Value, t)
forall g.
RandomGen g =>
EvalOpts
-> Value
-> [Gen g Bool BV Integer]
-> Integer
-> g
-> IO ([Value], Value, g)
returnOneTest EvalOpts
evo Value
fun [Gen t Bool BV Integer]
args Integer
sz t
g0
[([Value], Value)]
more <- [Gen t Bool BV Integer] -> t -> Int -> IO [([Value], Value)]
go [Gen t Bool BV Integer]
args t
g1 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
[([Value], Value)] -> IO [([Value], Value)]
forall (m :: * -> *) a. Monad m => a -> m a
return (([Value]
inputs, Value
output) ([Value], Value) -> [([Value], Value)] -> [([Value], Value)]
forall a. a -> [a] -> [a]
: [([Value], Value)]
more)
dumpableType :: forall g. RandomGen g => Type -> Maybe [Gen g Bool BV Integer]
dumpableType :: Type -> Maybe [Gen g Bool BV Integer]
dumpableType ty :: Type
ty =
case Type -> Maybe (Type, Type)
tIsFun Type
ty of
Just (t1 :: Type
t1, t2 :: Type
t2) ->
do Gen g Bool BV Integer
g <- Type -> Maybe (Gen g Bool BV Integer)
forall b w i g.
(BitWord b w i, RandomGen g) =>
Type -> Maybe (Gen g b w i)
randomValue Type
t1
[Gen g Bool BV Integer]
as <- Type -> Maybe [Gen g Bool BV Integer]
forall g. RandomGen g => Type -> Maybe [Gen g Bool BV Integer]
testableType Type
t2
[Gen g Bool BV Integer] -> Maybe [Gen g Bool BV Integer]
forall (m :: * -> *) a. Monad m => a -> m a
return (Gen g Bool BV Integer
g Gen g Bool BV Integer
-> [Gen g Bool BV Integer] -> [Gen g Bool BV Integer]
forall a. a -> [a] -> [a]
: [Gen g Bool BV Integer]
as)
Nothing ->
do (Gen g Bool BV Integer
_ :: Gen g Bool BV Integer) <- Type -> Maybe (Gen g Bool BV Integer)
forall b w i g.
(BitWord b w i, RandomGen g) =>
Type -> Maybe (Gen g b w i)
randomValue Type
ty
[Gen g Bool BV Integer] -> Maybe [Gen g Bool BV Integer]
forall (m :: * -> *) a. Monad m => a -> m a
return []
testableType :: RandomGen g => Type -> Maybe [Gen g Bool BV Integer]
testableType :: Type -> Maybe [Gen g Bool BV Integer]
testableType ty :: Type
ty =
case Type -> Type
tNoUser Type
ty of
TCon (TC TCFun) [t1 :: Type
t1,t2 :: Type
t2] ->
do Gen g Bool BV Integer
g <- Type -> Maybe (Gen g Bool BV Integer)
forall b w i g.
(BitWord b w i, RandomGen g) =>
Type -> Maybe (Gen g b w i)
randomValue Type
t1
[Gen g Bool BV Integer]
as <- Type -> Maybe [Gen g Bool BV Integer]
forall g. RandomGen g => Type -> Maybe [Gen g Bool BV Integer]
testableType Type
t2
[Gen g Bool BV Integer] -> Maybe [Gen g Bool BV Integer]
forall (m :: * -> *) a. Monad m => a -> m a
return (Gen g Bool BV Integer
g Gen g Bool BV Integer
-> [Gen g Bool BV Integer] -> [Gen g Bool BV Integer]
forall a. a -> [a] -> [a]
: [Gen g Bool BV Integer]
as)
TCon (TC TCBit) [] -> [Gen g Bool BV Integer] -> Maybe [Gen g Bool BV Integer]
forall (m :: * -> *) a. Monad m => a -> m a
return []
_ -> Maybe [Gen g Bool BV Integer]
forall a. Maybe a
Nothing
randomValue :: (BitWord b w i, RandomGen g) => Type -> Maybe (Gen g b w i)
randomValue :: Type -> Maybe (Gen g b w i)
randomValue ty :: Type
ty =
case Type
ty of
TCon tc :: TCon
tc ts :: [Type]
ts ->
case (TCon
tc, (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Type -> Type
tRebuild' Bool
False) [Type]
ts) of
(TC TCBit, []) -> Gen g b w i -> Maybe (Gen g b w i)
forall a. a -> Maybe a
Just Gen g b w i
forall b w i g. (BitWord b w i, RandomGen g) => Gen g b w i
randomBit
(TC TCInteger, []) -> Gen g b w i -> Maybe (Gen g b w i)
forall a. a -> Maybe a
Just Gen g b w i
forall b w i g. (BitWord b w i, RandomGen g) => Gen g b w i
randomInteger
(TC TCIntMod, [TCon (TC (TCNum n :: Integer
n)) []]) ->
do Gen g b w i -> Maybe (Gen g b w i)
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Gen g b w i
forall b w i g.
(BitWord b w i, RandomGen g) =>
Integer -> Gen g b w i
randomIntMod Integer
n)
(TC TCSeq, [TCon (TC TCInf) [], el :: Type
el]) ->
do Gen g b w i
mk <- Type -> Maybe (Gen g b w i)
forall b w i g.
(BitWord b w i, RandomGen g) =>
Type -> Maybe (Gen g b w i)
randomValue Type
el
Gen g b w i -> Maybe (Gen g b w i)
forall (m :: * -> *) a. Monad m => a -> m a
return (Gen g b w i -> Gen g b w i
forall g b w i. RandomGen g => Gen g b w i -> Gen g b w i
randomStream Gen g b w i
mk)
(TC TCSeq, [TCon (TC (TCNum n :: Integer
n)) [], TCon (TC TCBit) []]) ->
Gen g b w i -> Maybe (Gen g b w i)
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Gen g b w i
forall b w i g.
(BitWord b w i, RandomGen g) =>
Integer -> Gen g b w i
randomWord Integer
n)
(TC TCSeq, [TCon (TC (TCNum n :: Integer
n)) [], el :: Type
el]) ->
do Gen g b w i
mk <- Type -> Maybe (Gen g b w i)
forall b w i g.
(BitWord b w i, RandomGen g) =>
Type -> Maybe (Gen g b w i)
randomValue Type
el
Gen g b w i -> Maybe (Gen g b w i)
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Gen g b w i -> Gen g b w i
forall g b w i.
RandomGen g =>
Integer -> Gen g b w i -> Gen g b w i
randomSequence Integer
n Gen g b w i
mk)
(TC (TCTuple _), els :: [Type]
els) ->
do [Gen g b w i]
mks <- (Type -> Maybe (Gen g b w i)) -> [Type] -> Maybe [Gen g b w i]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Type -> Maybe (Gen g b w i)
forall b w i g.
(BitWord b w i, RandomGen g) =>
Type -> Maybe (Gen g b w i)
randomValue [Type]
els
Gen g b w i -> Maybe (Gen g b w i)
forall (m :: * -> *) a. Monad m => a -> m a
return ([Gen g b w i] -> Gen g b w i
forall g b w i. RandomGen g => [Gen g b w i] -> Gen g b w i
randomTuple [Gen g b w i]
mks)
_ -> Maybe (Gen g b w i)
forall a. Maybe a
Nothing
TVar _ -> Maybe (Gen g b w i)
forall a. Maybe a
Nothing
TUser _ _ t :: Type
t -> Type -> Maybe (Gen g b w i)
forall b w i g.
(BitWord b w i, RandomGen g) =>
Type -> Maybe (Gen g b w i)
randomValue Type
t
TRec fs :: [(Ident, Type)]
fs -> do [(Ident, Gen g b w i)]
gs <- [(Ident, Type)]
-> ((Ident, Type) -> Maybe (Ident, Gen g b w i))
-> Maybe [(Ident, Gen g b w i)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(Ident, Type)]
fs (((Ident, Type) -> Maybe (Ident, Gen g b w i))
-> Maybe [(Ident, Gen g b w i)])
-> ((Ident, Type) -> Maybe (Ident, Gen g b w i))
-> Maybe [(Ident, Gen g b w i)]
forall a b. (a -> b) -> a -> b
$ \(l :: Ident
l,t :: Type
t) -> do Gen g b w i
g <- Type -> Maybe (Gen g b w i)
forall b w i g.
(BitWord b w i, RandomGen g) =>
Type -> Maybe (Gen g b w i)
randomValue Type
t
(Ident, Gen g b w i) -> Maybe (Ident, Gen g b w i)
forall (m :: * -> *) a. Monad m => a -> m a
return (Ident
l,Gen g b w i
g)
Gen g b w i -> Maybe (Gen g b w i)
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Ident, Gen g b w i)] -> Gen g b w i
forall g b w i.
RandomGen g =>
[(Ident, Gen g b w i)] -> Gen g b w i
randomRecord [(Ident, Gen g b w i)]
gs)
randomBit :: (BitWord b w i, RandomGen g) => Gen g b w i
randomBit :: Gen g b w i
randomBit _ g :: g
g =
let (b :: Bool
b,g1 :: g
g1) = g -> (Bool, g)
forall a g. (Random a, RandomGen g) => g -> (a, g)
random g
g
in (b -> GenValue b w i
forall b w i. b -> GenValue b w i
VBit (Bool -> b
forall b w i. BitWord b w i => Bool -> b
bitLit Bool
b), g
g1)
randomSize :: RandomGen g => Int -> Int -> g -> (Int, g)
randomSize :: Int -> Int -> g -> (Int, g)
randomSize k :: Int
k n :: Int
n g :: g
g
| Int
p Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1 = (Int
n, g
g')
| Bool
otherwise = Int -> Int -> g -> (Int, g)
forall g. RandomGen g => Int -> Int -> g -> (Int, g)
randomSize Int
k (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) g
g'
where (p :: Int
p, g' :: g
g') = (Int, Int) -> g -> (Int, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (1, Int
k) g
g
randomInteger :: (BitWord b w i, RandomGen g) => Gen g b w i
randomInteger :: Gen g b w i
randomInteger w :: Integer
w g :: g
g =
let (n :: Int
n, g1 :: g
g1) = if Integer
w Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< 100 then (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
w, g
g) else Int -> Int -> g -> (Int, g)
forall g. RandomGen g => Int -> Int -> g -> (Int, g)
randomSize 8 100 g
g
(x :: Integer
x, g2 :: g
g2) = (Integer, Integer) -> g -> (Integer, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (- 256Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Int
n, 256Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Int
n) g
g1
in (i -> GenValue b w i
forall b w i. i -> GenValue b w i
VInteger (Integer -> i
forall b w i. BitWord b w i => Integer -> i
integerLit Integer
x), g
g2)
randomIntMod :: (BitWord b w i, RandomGen g) => Integer -> Gen g b w i
randomIntMod :: Integer -> Gen g b w i
randomIntMod modulus :: Integer
modulus _ g :: g
g =
let (x :: Integer
x, g' :: g
g') = (Integer, Integer) -> g -> (Integer, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (0, Integer
modulusInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-1) g
g
in (i -> GenValue b w i
forall b w i. i -> GenValue b w i
VInteger (Integer -> i
forall b w i. BitWord b w i => Integer -> i
integerLit Integer
x), g
g')
randomWord :: (BitWord b w i, RandomGen g) => Integer -> Gen g b w i
randomWord :: Integer -> Gen g b w i
randomWord w :: Integer
w _sz :: Integer
_sz g :: g
g =
let (val :: Integer
val, g1 :: g
g1) = (Integer, Integer) -> g -> (Integer, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (0,2Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
wInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-1) g
g
in (Integer -> Eval (WordValue b w i) -> GenValue b w i
forall b w i. Integer -> Eval (WordValue b w i) -> GenValue b w i
VWord Integer
w (WordValue b w i -> Eval (WordValue b w i)
forall a. a -> Eval a
ready (w -> WordValue b w i
forall b w i. w -> WordValue b w i
WordVal (Integer -> Integer -> w
forall b w i. BitWord b w i => Integer -> Integer -> w
wordLit Integer
w Integer
val))), g
g1)
randomStream :: RandomGen g => Gen g b w i -> Gen g b w i
randomStream :: Gen g b w i -> Gen g b w i
randomStream mkElem :: Gen g b w i
mkElem sz :: Integer
sz g :: g
g =
let (g1 :: g
g1,g2 :: g
g2) = g -> (g, g)
forall g. RandomGen g => g -> (g, g)
split g
g
in (SeqMap b w i -> GenValue b w i
forall b w i. SeqMap b w i -> GenValue b w i
VStream (SeqMap b w i -> GenValue b w i) -> SeqMap b w i -> GenValue b w i
forall a b. (a -> b) -> a -> b
$ (Integer -> Eval (GenValue b w i)) -> SeqMap b w i
forall b w i. (Integer -> Eval (GenValue b w i)) -> SeqMap b w i
IndexSeqMap ((Integer -> Eval (GenValue b w i)) -> SeqMap b w i)
-> (Integer -> Eval (GenValue b w i)) -> SeqMap b w i
forall a b. (a -> b) -> a -> b
$ [Eval (GenValue b w i)] -> Integer -> Eval (GenValue b w i)
forall i a. Integral i => [a] -> i -> a
genericIndex ((GenValue b w i -> Eval (GenValue b w i))
-> [GenValue b w i] -> [Eval (GenValue b w i)]
forall a b. (a -> b) -> [a] -> [b]
map GenValue b w i -> Eval (GenValue b w i)
forall a. a -> Eval a
ready ((g -> Maybe (GenValue b w i, g)) -> g -> [GenValue b w i]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr ((GenValue b w i, g) -> Maybe (GenValue b w i, g)
forall a. a -> Maybe a
Just ((GenValue b w i, g) -> Maybe (GenValue b w i, g))
-> (g -> (GenValue b w i, g)) -> g -> Maybe (GenValue b w i, g)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Gen g b w i
mkElem Integer
sz) g
g1)), g
g2)
randomSequence :: RandomGen g => Integer -> Gen g b w i -> Gen g b w i
randomSequence :: Integer -> Gen g b w i -> Gen g b w i
randomSequence w :: Integer
w mkElem :: Gen g b w i
mkElem sz :: Integer
sz g0 :: g
g0 = do
let (g1 :: g
g1,g2 :: g
g2) = g -> (g, g)
forall g. RandomGen g => g -> (g, g)
split g
g0
let f :: g -> Maybe (Eval (GenValue b w i), g)
f g :: g
g = let (x :: GenValue b w i
x,g' :: g
g') = Gen g b w i
mkElem Integer
sz g
g
in GenValue b w i
-> Maybe (Eval (GenValue b w i), g)
-> Maybe (Eval (GenValue b w i), g)
forall a b. a -> b -> b
seq GenValue b w i
x ((Eval (GenValue b w i), g) -> Maybe (Eval (GenValue b w i), g)
forall a. a -> Maybe a
Just (GenValue b w i -> Eval (GenValue b w i)
forall a. a -> Eval a
ready GenValue b w i
x, g
g'))
let xs :: Seq (Eval (GenValue b w i))
xs = [Eval (GenValue b w i)] -> Seq (Eval (GenValue b w i))
forall a. [a] -> Seq a
Seq.fromList ([Eval (GenValue b w i)] -> Seq (Eval (GenValue b w i)))
-> [Eval (GenValue b w i)] -> Seq (Eval (GenValue b w i))
forall a b. (a -> b) -> a -> b
$ Integer -> [Eval (GenValue b w i)] -> [Eval (GenValue b w i)]
forall i a. Integral i => i -> [a] -> [a]
genericTake Integer
w ([Eval (GenValue b w i)] -> [Eval (GenValue b w i)])
-> [Eval (GenValue b w i)] -> [Eval (GenValue b w i)]
forall a b. (a -> b) -> a -> b
$ (g -> Maybe (Eval (GenValue b w i), g))
-> g -> [Eval (GenValue b w i)]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr g -> Maybe (Eval (GenValue b w i), g)
f g
g1
Seq (Eval (GenValue b w i))
-> (GenValue b w i, g) -> (GenValue b w i, g)
forall a b. a -> b -> b
seq Seq (Eval (GenValue b w i))
xs (Integer -> SeqMap b w i -> GenValue b w i
forall b w i. Integer -> SeqMap b w i -> GenValue b w i
VSeq Integer
w (SeqMap b w i -> GenValue b w i) -> SeqMap b w i -> GenValue b w i
forall a b. (a -> b) -> a -> b
$ (Integer -> Eval (GenValue b w i)) -> SeqMap b w i
forall b w i. (Integer -> Eval (GenValue b w i)) -> SeqMap b w i
IndexSeqMap ((Integer -> Eval (GenValue b w i)) -> SeqMap b w i)
-> (Integer -> Eval (GenValue b w i)) -> SeqMap b w i
forall a b. (a -> b) -> a -> b
$ (Seq (Eval (GenValue b w i)) -> Int -> Eval (GenValue b w i)
forall a. Seq a -> Int -> a
Seq.index Seq (Eval (GenValue b w i))
xs (Int -> Eval (GenValue b w i))
-> (Integer -> Int) -> Integer -> Eval (GenValue b w i)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int
forall a. Num a => Integer -> a
fromInteger), g
g2)
randomTuple :: RandomGen g => [Gen g b w i] -> Gen g b w i
randomTuple :: [Gen g b w i] -> Gen g b w i
randomTuple gens :: [Gen g b w i]
gens sz :: Integer
sz = [Eval (GenValue b w i)]
-> [Gen g b w i] -> g -> (GenValue b w i, g)
forall b w i t.
[Eval (GenValue b w i)]
-> [Integer -> t -> (GenValue b w i, t)]
-> t
-> (GenValue b w i, t)
go [] [Gen g b w i]
gens
where
go :: [Eval (GenValue b w i)]
-> [Integer -> t -> (GenValue b w i, t)]
-> t
-> (GenValue b w i, t)
go els :: [Eval (GenValue b w i)]
els [] g :: t
g = ([Eval (GenValue b w i)] -> GenValue b w i
forall b w i. [Eval (GenValue b w i)] -> GenValue b w i
VTuple ([Eval (GenValue b w i)] -> [Eval (GenValue b w i)]
forall a. [a] -> [a]
reverse [Eval (GenValue b w i)]
els), t
g)
go els :: [Eval (GenValue b w i)]
els (mkElem :: Integer -> t -> (GenValue b w i, t)
mkElem : more :: [Integer -> t -> (GenValue b w i, t)]
more) g :: t
g =
let (v :: GenValue b w i
v, g1 :: t
g1) = Integer -> t -> (GenValue b w i, t)
mkElem Integer
sz t
g
in GenValue b w i -> (GenValue b w i, t) -> (GenValue b w i, t)
forall a b. a -> b -> b
seq GenValue b w i
v ([Eval (GenValue b w i)]
-> [Integer -> t -> (GenValue b w i, t)]
-> t
-> (GenValue b w i, t)
go (GenValue b w i -> Eval (GenValue b w i)
forall a. a -> Eval a
ready GenValue b w i
v Eval (GenValue b w i)
-> [Eval (GenValue b w i)] -> [Eval (GenValue b w i)]
forall a. a -> [a] -> [a]
: [Eval (GenValue b w i)]
els) [Integer -> t -> (GenValue b w i, t)]
more t
g1)
randomRecord :: RandomGen g => [(Ident, Gen g b w i)] -> Gen g b w i
randomRecord :: [(Ident, Gen g b w i)] -> Gen g b w i
randomRecord gens :: [(Ident, Gen g b w i)]
gens sz :: Integer
sz = [(Ident, Eval (GenValue b w i))]
-> [(Ident, Gen g b w i)] -> g -> (GenValue b w i, g)
forall b w i t.
[(Ident, Eval (GenValue b w i))]
-> [(Ident, Integer -> t -> (GenValue b w i, t))]
-> t
-> (GenValue b w i, t)
go [] [(Ident, Gen g b w i)]
gens
where
go :: [(Ident, Eval (GenValue b w i))]
-> [(Ident, Integer -> t -> (GenValue b w i, t))]
-> t
-> (GenValue b w i, t)
go els :: [(Ident, Eval (GenValue b w i))]
els [] g :: t
g = ([(Ident, Eval (GenValue b w i))] -> GenValue b w i
forall b w i. [(Ident, Eval (GenValue b w i))] -> GenValue b w i
VRecord ([(Ident, Eval (GenValue b w i))]
-> [(Ident, Eval (GenValue b w i))]
forall a. [a] -> [a]
reverse [(Ident, Eval (GenValue b w i))]
els), t
g)
go els :: [(Ident, Eval (GenValue b w i))]
els ((l :: Ident
l,mkElem :: Integer -> t -> (GenValue b w i, t)
mkElem) : more :: [(Ident, Integer -> t -> (GenValue b w i, t))]
more) g :: t
g =
let (v :: GenValue b w i
v, g1 :: t
g1) = Integer -> t -> (GenValue b w i, t)
mkElem Integer
sz t
g
in GenValue b w i -> (GenValue b w i, t) -> (GenValue b w i, t)
forall a b. a -> b -> b
seq GenValue b w i
v ([(Ident, Eval (GenValue b w i))]
-> [(Ident, Integer -> t -> (GenValue b w i, t))]
-> t
-> (GenValue b w i, t)
go ((Ident
l,GenValue b w i -> Eval (GenValue b w i)
forall a. a -> Eval a
ready GenValue b w i
v) (Ident, Eval (GenValue b w i))
-> [(Ident, Eval (GenValue b w i))]
-> [(Ident, Eval (GenValue b w i))]
forall a. a -> [a] -> [a]
: [(Ident, Eval (GenValue b w i))]
els) [(Ident, Integer -> t -> (GenValue b w i, t))]
more t
g1)