module Test.Falsify.Internal.Generator.Compound (
choose
, oneof
, list
, elem
, pick
, pickBiased
, shuffle
, permutation
, frequency
, tree
, bst
, IsValidShrink(..)
, path
, pathAny
, shrinkToNothing
, mark
) where
import Prelude hiding (either, elem)
import Control.Monad
import Control.Selective
import Data.Either (either)
import Data.List.NonEmpty (NonEmpty(..))
import Data.Maybe (catMaybes)
import Data.Void
import qualified Data.List.NonEmpty as NE
import qualified Data.Tree as Rose
import Data.Falsify.Permutation (Permutation)
import Data.Falsify.Tree (Tree(..))
import Test.Falsify.Internal.Generator
import Test.Falsify.Internal.Generator.Shrinking
import Test.Falsify.Internal.Generator.Simple
import Test.Falsify.Internal.Range
import Test.Falsify.Internal.Shrinking (IsValidShrink(..))
import Test.Falsify.Marked (Mark(..), Marked(..))
import Test.Falsify.ShrinkTree (ShrinkTree(..))
import qualified Data.Falsify.Internal.List as List
import qualified Data.Falsify.Permutation as Permutation
import qualified Test.Falsify.Internal.Marked.Tree as MarkedTree
import qualified Test.Falsify.Marked as Marked
import qualified Test.Falsify.Range as Range
choose :: Gen a -> Gen a -> Gen a
choose :: forall a. Gen a -> Gen a -> Gen a
choose = Gen Bool -> Gen a -> Gen a -> Gen a
forall (f :: * -> *) a. Selective f => f Bool -> f a -> f a -> f a
ifS (Bool -> Gen Bool
bool Bool
True)
oneof :: NonEmpty (Gen a) -> Gen a
oneof :: forall a. NonEmpty (Gen a) -> Gen a
oneof NonEmpty (Gen a)
gens = [(Word, Gen a)] -> Gen a
forall a. [(Word, Gen a)] -> Gen a
frequency ([(Word, Gen a)] -> Gen a) -> [(Word, Gen a)] -> Gen a
forall a b. (a -> b) -> a -> b
$ (Gen a -> (Word, Gen a)) -> [Gen a] -> [(Word, Gen a)]
forall a b. (a -> b) -> [a] -> [b]
map (Word
1,) ([Gen a] -> [(Word, Gen a)]) -> [Gen a] -> [(Word, Gen a)]
forall a b. (a -> b) -> a -> b
$ NonEmpty (Gen a) -> [Gen a]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty (Gen a)
gens
shrinkToNothing :: Gen a -> Gen (Maybe a)
shrinkToNothing :: forall a. Gen a -> Gen (Maybe a)
shrinkToNothing Gen a
g = (a -> Maybe a) -> (a -> Maybe a) -> Gen (a -> Maybe a)
forall a. a -> a -> Gen a
firstThen a -> Maybe a
forall a. a -> Maybe a
Just (Maybe a -> a -> Maybe a
forall a b. a -> b -> a
const Maybe a
forall a. Maybe a
Nothing) Gen (a -> Maybe a) -> Gen a -> Gen (Maybe a)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen a
g
mark :: Gen a -> Gen (Marked Gen a)
mark :: forall a. Gen a -> Gen (Marked Gen a)
mark Gen a
x = (Mark -> Gen a -> Marked Gen a) -> Gen a -> Mark -> Marked Gen a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Mark -> Gen a -> Marked Gen a
forall (f :: * -> *) a. Mark -> f a -> Marked f a
Marked Gen a
x (Mark -> Marked Gen a) -> Gen Mark -> Gen (Marked Gen a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mark -> Mark -> Gen Mark
forall a. a -> a -> Gen a
firstThen Mark
Keep Mark
Drop
list :: Range Word -> Gen a -> Gen [a]
list :: forall a. Range Word -> Gen a -> Gen [a]
list Range Word
len Gen a
gen = do
Word
n <- Range Word -> Gen Word
forall a. Range a -> Gen a
inRange Range Word
len
[Marked Gen a]
marks <- ([Marked Gen a] -> [Marked Gen a])
-> Gen [Marked Gen a] -> Gen [Marked Gen a]
forall a b. (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Word -> [Marked Gen a] -> [Marked Gen a]
forall (f :: * -> *) a. Word -> [Marked f a] -> [Marked f a]
List.keepAtLeast (Range Word -> Word
forall a. Range a -> a
Range.origin Range Word
len) ([Marked Gen a] -> [Marked Gen a])
-> ([Marked Gen a] -> [Marked Gen a])
-> [Marked Gen a]
-> [Marked Gen a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Marked Gen a] -> [Marked Gen a]
forall a. [a] -> [a]
reverse) (Gen [Marked Gen a] -> Gen [Marked Gen a])
-> Gen [Marked Gen a] -> Gen [Marked Gen a]
forall a b. (a -> b) -> a -> b
$
Int -> Gen (Marked Gen a) -> Gen [Marked Gen a]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
n) (Gen (Marked Gen a) -> Gen [Marked Gen a])
-> Gen (Marked Gen a) -> Gen [Marked Gen a]
forall a b. (a -> b) -> a -> b
$ Gen a -> Gen (Marked Gen a)
forall a. Gen a -> Gen (Marked Gen a)
mark Gen a
gen
[Maybe a] -> [a]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe a] -> [a]) -> Gen [Maybe a] -> Gen [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Marked Gen a] -> Gen [Maybe a]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Selective f) =>
t (Marked f a) -> f (t (Maybe a))
Marked.selectAllKept [Marked Gen a]
marks
elem :: NonEmpty a -> Gen a
elem :: forall a. NonEmpty a -> Gen a
elem = (([a], a, [a]) -> a) -> Gen ([a], a, [a]) -> Gen a
forall a b. (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\([a]
_before, a
x, [a]
_after) -> a
x) (Gen ([a], a, [a]) -> Gen a)
-> (NonEmpty a -> Gen ([a], a, [a])) -> NonEmpty a -> Gen a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> Gen ([a], a, [a])
forall a. NonEmpty a -> Gen ([a], a, [a])
pick
pick :: NonEmpty a -> Gen ([a], a, [a])
pick :: forall a. NonEmpty a -> Gen ([a], a, [a])
pick = \NonEmpty a
xs ->
[a] -> [a] -> Int -> ([a], a, [a])
forall a. [a] -> [a] -> Int -> ([a], a, [a])
aux [] (NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty a
xs) (Int -> ([a], a, [a])) -> Gen Int -> Gen ([a], a, [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Range Int -> Gen Int
forall a. Range a -> Gen a
inRange ((Int, Int) -> Range Int
forall a. (Integral a, FiniteBits a) => (a, a) -> Range a
Range.inclusive (Int
0, NonEmpty a -> Int
forall a. NonEmpty a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length NonEmpty a
xs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
where
aux :: [a] -> [a] -> Int -> ([a], a, [a])
aux :: forall a. [a] -> [a] -> Int -> ([a], a, [a])
aux [a]
_ [] Int
_ = [Char] -> ([a], a, [a])
forall a. HasCallStack => [Char] -> a
error [Char]
"pick: impossible"
aux [a]
prev (a
x:[a]
xs) Int
0 = ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
prev, a
x, [a]
xs)
aux [a]
prev (a
x:[a]
xs) Int
i = [a] -> [a] -> Int -> ([a], a, [a])
forall a. [a] -> [a] -> Int -> ([a], a, [a])
aux (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
prev) [a]
xs (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
pickBiased :: NonEmpty a -> Gen ([a], a, [a])
pickBiased :: forall a. NonEmpty a -> Gen ([a], a, [a])
pickBiased = \NonEmpty a
xs -> [NonEmpty a] -> NonEmpty (NonEmpty a) -> Gen ([a], a, [a])
forall a.
[NonEmpty a] -> NonEmpty (NonEmpty a) -> Gen ([a], a, [a])
pickChunk [] (Word -> NonEmpty a -> NonEmpty (NonEmpty a)
forall a. Word -> NonEmpty a -> NonEmpty (NonEmpty a)
List.chunksOfNonEmpty Word
chunkSize NonEmpty a
xs)
where
chunkSize :: Word
chunkSize :: Word
chunkSize = Word
1_000
pickChunk :: [NonEmpty a] -> NonEmpty (NonEmpty a) -> Gen ([a], a, [a])
pickChunk :: forall a.
[NonEmpty a] -> NonEmpty (NonEmpty a) -> Gen ([a], a, [a])
pickChunk [NonEmpty a]
prev (NonEmpty a
chunk :| []) = do
[NonEmpty a] -> NonEmpty a -> [NonEmpty a] -> Gen ([a], a, [a])
forall a.
[NonEmpty a] -> NonEmpty a -> [NonEmpty a] -> Gen ([a], a, [a])
withChunk [NonEmpty a]
prev NonEmpty a
chunk []
pickChunk [NonEmpty a]
prev (NonEmpty a
chunk :| next :: [NonEmpty a]
next@(NonEmpty a
n:[NonEmpty a]
ns)) = do
Bool
useChunk <- Bool -> Gen Bool
bool Bool
True
if Bool
useChunk
then [NonEmpty a] -> NonEmpty a -> [NonEmpty a] -> Gen ([a], a, [a])
forall a.
[NonEmpty a] -> NonEmpty a -> [NonEmpty a] -> Gen ([a], a, [a])
withChunk [NonEmpty a]
prev NonEmpty a
chunk [NonEmpty a]
next
else [NonEmpty a] -> NonEmpty (NonEmpty a) -> Gen ([a], a, [a])
forall a.
[NonEmpty a] -> NonEmpty (NonEmpty a) -> Gen ([a], a, [a])
pickChunk (NonEmpty a
chunkNonEmpty a -> [NonEmpty a] -> [NonEmpty a]
forall a. a -> [a] -> [a]
:[NonEmpty a]
prev) (NonEmpty a
n NonEmpty a -> [NonEmpty a] -> NonEmpty (NonEmpty a)
forall a. a -> [a] -> NonEmpty a
:| [NonEmpty a]
ns)
withChunk :: [NonEmpty a] -> NonEmpty a -> [NonEmpty a] -> Gen ([a], a, [a])
withChunk :: forall a.
[NonEmpty a] -> NonEmpty a -> [NonEmpty a] -> Gen ([a], a, [a])
withChunk [NonEmpty a]
prev NonEmpty a
chunk [NonEmpty a]
next = do
([a]
chunkBefore, a
chunkElem, [a]
chunkAfter) <- NonEmpty a -> Gen ([a], a, [a])
forall a. NonEmpty a -> Gen ([a], a, [a])
pick NonEmpty a
chunk
([a], a, [a]) -> Gen ([a], a, [a])
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (
[[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[a]] -> [a]) -> [[a]] -> [a]
forall a b. (a -> b) -> a -> b
$ [[a]] -> [[a]]
forall a. [a] -> [a]
reverse ([[a]] -> [[a]]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> a -> b
$ [a]
chunkBefore [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: (NonEmpty a -> [a]) -> [NonEmpty a] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NE.toList [NonEmpty a]
prev
, a
chunkElem
, [a]
chunkAfter [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ (NonEmpty a -> [a]) -> [NonEmpty a] -> [a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NE.toList [NonEmpty a]
next
)
frequency :: forall a. [(Word, Gen a)] -> Gen a
frequency :: forall a. [(Word, Gen a)] -> Gen a
frequency [(Word, Gen a)]
gens =
case ((Word, (Gen a, Word)) -> Bool)
-> [(Word, (Gen a, Word))] -> [(Word, (Gen a, Word))]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
/= Word
0) (Word -> Bool)
-> ((Word, (Gen a, Word)) -> Word) -> (Word, (Gen a, Word)) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word, (Gen a, Word)) -> Word
forall a b. (a, b) -> a
fst) [(Word, (Gen a, Word))]
indexedGens of
[] -> [Char] -> Gen a
forall a. HasCallStack => [Char] -> a
error [Char]
"frequency: no generators with non-zero frequency"
[(Word, (Gen a, Word))]
gens' -> do
let r :: Range Word
r :: Range Word
r = (Word, Word) -> Range Word
forall a. (Integral a, FiniteBits a) => (a, a) -> Range a
Range.inclusive (Word
0, [Word] -> Word
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (((Word, (Gen a, Word)) -> Word)
-> [(Word, (Gen a, Word))] -> [Word]
forall a b. (a -> b) -> [a] -> [b]
map (Word, (Gen a, Word)) -> Word
forall a b. (a, b) -> a
fst [(Word, (Gen a, Word))]
gens') Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
1)
(Gen a
gen, Word
genIx) <- (\Word
i -> Word -> [(Word, (Gen a, Word))] -> (Gen a, Word)
forall x. Word -> [(Word, x)] -> x
frequencyLookup Word
i [(Word, (Gen a, Word))]
gens') (Word -> (Gen a, Word)) -> Gen Word -> Gen (Gen a, Word)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Word -> Gen Word
forall a. Range a -> Gen a
inRange Range Word
r
Word -> Gen a -> Gen a
forall a b. Integral a => a -> Gen b -> Gen b
perturb Word
genIx Gen a
gen
where
indexedGens :: [(Word, (Gen a, Word))]
indexedGens :: [(Word, (Gen a, Word))]
indexedGens = ((Word, Gen a) -> Word -> (Word, (Gen a, Word)))
-> [(Word, Gen a)] -> [Word] -> [(Word, (Gen a, Word))]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\(Word
f, Gen a
g) Word
i -> (Word
f, (Gen a
g, Word
i))) [(Word, Gen a)]
gens [Word
0..]
frequencyLookup :: Word -> [(Word, x)] -> x
frequencyLookup :: forall x. Word -> [(Word, x)] -> x
frequencyLookup = \Word
i [(Word, x)]
xs ->
case Word -> [(Word, x)] -> Maybe x
forall x. Word -> [(Word, x)] -> Maybe x
go Word
i [(Word, x)]
xs of
Just x
x -> x
x
Maybe x
Nothing ->
[Char] -> x
forall a. HasCallStack => [Char] -> a
error ([Char] -> x) -> [Char] -> x
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [
[Char]
"frequencyLookup: index "
, Word -> [Char]
forall a. Show a => a -> [Char]
show Word
i
, [Char]
" out of range of "
, [Word] -> [Char]
forall a. Show a => a -> [Char]
show (((Word, x) -> Word) -> [(Word, x)] -> [Word]
forall a b. (a -> b) -> [a] -> [b]
map (Word, x) -> Word
forall a b. (a, b) -> a
fst [(Word, x)]
xs)
]
where
go :: Word -> [(Word, x)] -> Maybe x
go :: forall x. Word -> [(Word, x)] -> Maybe x
go Word
_ [] = Maybe x
forall a. Maybe a
Nothing
go Word
i ((Word
n, x
x):[(Word, x)]
xs)
| Word
i Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
n = x -> Maybe x
forall a. a -> Maybe a
Just x
x
| Bool
otherwise = Word -> [(Word, x)] -> Maybe x
forall x. Word -> [(Word, x)] -> Maybe x
go (Word
i Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
n) [(Word, x)]
xs
shuffle :: [a] -> Gen [a]
shuffle :: forall a. [a] -> Gen [a]
shuffle [a]
xs =
(Permutation -> [a] -> [a]) -> [a] -> Permutation -> [a]
forall a b c. (a -> b -> c) -> b -> a -> c
flip Permutation -> [a] -> [a]
forall a. Permutation -> [a] -> [a]
Permutation.apply [a]
xs (Permutation -> [a]) -> Gen Permutation -> Gen [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Word -> Gen Permutation
permutation (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> Int -> Word
forall a b. (a -> b) -> a -> b
$ [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)
permutation :: Word -> Gen Permutation
permutation :: Word -> Gen Permutation
permutation Word
0 = Permutation -> Gen Permutation
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return Permutation
Permutation.identity
permutation Word
1 = Permutation -> Gen Permutation
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return Permutation
Permutation.identity
permutation Word
n = do
[Marked Gen (Word, Word)]
swaps <- (Word -> Gen (Marked Gen (Word, Word)))
-> [Word] -> Gen [Marked Gen (Word, Word)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Gen (Word, Word) -> Gen (Marked Gen (Word, Word))
forall a. Gen a -> Gen (Marked Gen a)
mark (Gen (Word, Word) -> Gen (Marked Gen (Word, Word)))
-> (Word -> Gen (Word, Word))
-> Word
-> Gen (Marked Gen (Word, Word))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Gen (Word, Word)
genSwap) [Word
n Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
1, Word
n Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
2 .. Word
1]
[(Word, Word)] -> Permutation
Permutation.fromSwaps ([(Word, Word)] -> Permutation)
-> ([Maybe (Word, Word)] -> [(Word, Word)])
-> [Maybe (Word, Word)]
-> Permutation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (Word, Word)] -> [(Word, Word)]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe (Word, Word)] -> Permutation)
-> Gen [Maybe (Word, Word)] -> Gen Permutation
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Marked Gen (Word, Word)] -> Gen [Maybe (Word, Word)]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Selective f) =>
t (Marked f a) -> f (t (Maybe a))
Marked.selectAllKept [Marked Gen (Word, Word)]
swaps
where
genSwap :: Word -> Gen (Word, Word)
genSwap :: Word -> Gen (Word, Word)
genSwap Word
i = do
Word
i' <- Range Word -> Gen Word
forall a. Range a -> Gen a
inRange (Range Word -> Gen Word) -> Range Word -> Gen Word
forall a b. (a -> b) -> a -> b
$ (Word, Word) -> Range Word
forall a. (Integral a, FiniteBits a) => (a, a) -> Range a
Range.inclusive (Word
1, Word
i)
Word
j <- Range Word -> Gen Word
forall a. Range a -> Gen a
inRange (Range Word -> Gen Word) -> Range Word -> Gen Word
forall a b. (a -> b) -> a -> b
$ (Word, Word) -> Range Word
forall a. (Integral a, FiniteBits a) => (a, a) -> Range a
Range.inclusive (Word
i, Word
0)
(Word, Word) -> Gen (Word, Word)
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (Word
i', Word -> Word -> Word
forall a. Ord a => a -> a -> a
min Word
i' Word
j)
tree :: forall a. Range Word -> Gen a -> Gen (Tree a)
tree :: forall a. Range Word -> Gen a -> Gen (Tree a)
tree Range Word
size Gen a
gen = do
Word
n <- Range Word -> Gen Word
forall a. Range a -> Gen a
inRange Range Word
size
Tree (Marked Gen a)
t <- Word -> Tree (Marked Gen a) -> Tree (Marked Gen a)
forall (f :: * -> *) a.
Word -> Tree (Marked f a) -> Tree (Marked f a)
MarkedTree.keepAtLeast (Range Word -> Word
forall a. Range a -> a
Range.origin Range Word
size) (Tree (Marked Gen a) -> Tree (Marked Gen a))
-> (Tree (Marked Gen a) -> Tree (Marked Gen a))
-> Tree (Marked Gen a)
-> Tree (Marked Gen a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tree (Marked Gen a) -> Tree (Marked Gen a)
forall (f :: * -> *) a. Tree (Marked f a) -> Tree (Marked f a)
MarkedTree.propagate (Tree (Marked Gen a) -> Tree (Marked Gen a))
-> Gen (Tree (Marked Gen a)) -> Gen (Tree (Marked Gen a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Word -> Gen (Tree (Marked Gen a))
go Word
n
Tree (Marked Gen a) -> Gen (Tree a)
forall (f :: * -> *) a.
Selective f =>
Tree (Marked f a) -> f (Tree a)
MarkedTree.apply Tree (Marked Gen a)
t
where
go :: Word -> Gen (Tree (Marked Gen a))
go :: Word -> Gen (Tree (Marked Gen a))
go Word
0 = Tree (Marked Gen a) -> Gen (Tree (Marked Gen a))
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return Tree (Marked Gen a)
forall a. Tree a
Leaf
go Word
n = do
Marked Gen a
x <- Gen a -> Gen (Marked Gen a)
forall a. Gen a -> Gen (Marked Gen a)
mark Gen a
gen
Word
inLeft <- Range Word -> Gen Word
forall a. Range a -> Gen a
inRange (Range Word -> Gen Word) -> Range Word -> Gen Word
forall a b. (a -> b) -> a -> b
$ (Word, Word) -> Word -> Range Word
forall a. (Integral a, FiniteBits a) => (a, a) -> a -> Range a
Range.withOrigin (Word
0, Word
n Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
1) ((Word
n Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
1) Word -> Word -> Word
forall a. Integral a => a -> a -> a
`div` Word
2)
let inRight :: Word
inRight = (Word
n Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
1) Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
inLeft
Marked Gen a
-> Tree (Marked Gen a)
-> Tree (Marked Gen a)
-> Tree (Marked Gen a)
forall a. a -> Tree a -> Tree a -> Tree a
Branch Marked Gen a
x (Tree (Marked Gen a) -> Tree (Marked Gen a) -> Tree (Marked Gen a))
-> Gen (Tree (Marked Gen a))
-> Gen (Tree (Marked Gen a) -> Tree (Marked Gen a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word -> Gen (Tree (Marked Gen a))
go Word
inLeft Gen (Tree (Marked Gen a) -> Tree (Marked Gen a))
-> Gen (Tree (Marked Gen a)) -> Gen (Tree (Marked Gen a))
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word -> Gen (Tree (Marked Gen a))
go Word
inRight
bst :: forall a b.
Integral a
=> (a -> Gen b)
-> (a, a)
-> Gen (Tree (a, b))
bst :: forall a b.
Integral a =>
(a -> Gen b) -> (a, a) -> Gen (Tree (a, b))
bst a -> Gen b
gen = (a, a) -> Gen (Tree a)
go ((a, a) -> Gen (Tree a))
-> (Tree a -> Gen (Tree (a, b))) -> (a, a) -> Gen (Tree (a, b))
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Gen (a, b)) -> Tree a -> Gen (Tree (a, b))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tree a -> f (Tree b)
traverse (\a
a -> (a
a,) (b -> (a, b)) -> Gen b -> Gen (a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> Gen b
gen a
a)
where
go :: (a, a) -> Gen (Tree a)
go :: (a, a) -> Gen (Tree a)
go (a
lo, a
hi)
| a
lo a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
hi = Tree a -> Gen (Tree a)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tree a -> Gen (Tree a)) -> Tree a -> Gen (Tree a)
forall a b. (a -> b) -> a -> b
$ a -> Tree a -> Tree a -> Tree a
forall a. a -> Tree a -> Tree a -> Tree a
Branch a
lo Tree a
forall a. Tree a
Leaf Tree a
forall a. Tree a
Leaf
| a
lo a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
hi = Tree a -> Gen (Tree a)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Tree a
forall a. Tree a
Leaf
| Bool
otherwise = (Tree a -> Tree a) -> (Tree a -> Tree a) -> Gen (Tree a -> Tree a)
forall a. a -> a -> Gen a
firstThen Tree a -> Tree a
forall a. a -> a
id (Tree a -> Tree a -> Tree a
forall a b. a -> b -> a
const Tree a
forall a. Tree a
Leaf) Gen (Tree a -> Tree a) -> Gen (Tree a) -> Gen (Tree a)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> a -> Gen (Tree a)
go' a
lo a
hi
go' :: a -> a -> Gen (Tree a)
go' :: a -> a -> Gen (Tree a)
go' a
lo a
hi =
a -> Tree a -> Tree a -> Tree a
forall a. a -> Tree a -> Tree a -> Tree a
Branch a
mid
(Tree a -> Tree a -> Tree a)
-> Gen (Tree a) -> Gen (Tree a -> Tree a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a, a) -> Gen (Tree a)
go (a
lo, a -> a
forall a. Enum a => a -> a
pred a
mid)
Gen (Tree a -> Tree a) -> Gen (Tree a) -> Gen (Tree a)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (a, a) -> Gen (Tree a)
go (a -> a
forall a. Enum a => a -> a
succ a
mid, a
hi)
where
mid' :: Integer
mid' :: Integer
mid' = a -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
lo Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ ((a -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
hi Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- a -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
lo) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
2)
mid :: a
mid :: a
mid = Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
mid'
path :: forall a p n.
(a -> Either n p)
-> ShrinkTree a
-> Gen (Either n (NonEmpty p))
path :: forall a p n.
(a -> Either n p) -> ShrinkTree a -> Gen (Either n (NonEmpty p))
path a -> Either n p
validShrink = \(WrapShrinkTree (Rose.Node a
a [Tree a]
as)) ->
case a -> Either n p
validShrink a
a of
Left n
n -> Either n (NonEmpty p) -> Gen (Either n (NonEmpty p))
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either n (NonEmpty p) -> Gen (Either n (NonEmpty p)))
-> Either n (NonEmpty p) -> Gen (Either n (NonEmpty p))
forall a b. (a -> b) -> a -> b
$ n -> Either n (NonEmpty p)
forall a b. a -> Either a b
Left n
n
Right p
p -> NonEmpty p -> Either n (NonEmpty p)
forall a b. b -> Either a b
Right (NonEmpty p -> Either n (NonEmpty p))
-> Gen (NonEmpty p) -> Gen (Either n (NonEmpty p))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p -> [Tree a] -> Gen (NonEmpty p)
go p
p [Tree a]
as
where
go :: p -> [Rose.Tree a] -> Gen (NonEmpty p)
go :: p -> [Tree a] -> Gen (NonEmpty p)
go p
p [] = NonEmpty p -> Gen (NonEmpty p)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (p
p p -> [p] -> NonEmpty p
forall a. a -> [a] -> NonEmpty a
:| [])
go p
p (Tree a
a:[Tree a]
as) = do
([Tree a]
before, Tree a
a', [Tree a]
after) <- NonEmpty (Tree a) -> Gen ([Tree a], Tree a, [Tree a])
forall a. NonEmpty a -> Gen ([a], a, [a])
pickBiased (Tree a
a Tree a -> [Tree a] -> NonEmpty (Tree a)
forall a. a -> [a] -> NonEmpty a
:| [Tree a]
as)
case Tree a -> Maybe (p, [Tree a])
checkPred Tree a
a' of
Maybe (p, [Tree a])
Nothing ->
p -> [Tree a] -> Gen (NonEmpty p)
go p
p ([Tree a]
before [Tree a] -> [Tree a] -> [Tree a]
forall a. [a] -> [a] -> [a]
++ [Tree a]
after)
Just (p
p', [Tree a]
as') ->
Gen (NonEmpty p) -> Gen (NonEmpty p) -> Gen (NonEmpty p)
forall a. Gen a -> Gen a -> Gen a
choose
(NonEmpty p -> Gen (NonEmpty p)
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (p
p p -> [p] -> NonEmpty p
forall a. a -> [a] -> NonEmpty a
:| []))
(p -> NonEmpty p -> NonEmpty p
forall a. a -> NonEmpty a -> NonEmpty a
NE.cons p
p (NonEmpty p -> NonEmpty p) -> Gen (NonEmpty p) -> Gen (NonEmpty p)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p -> [Tree a] -> Gen (NonEmpty p)
go p
p' [Tree a]
as')
checkPred :: Rose.Tree a -> Maybe (p, [Rose.Tree a])
checkPred :: Tree a -> Maybe (p, [Tree a])
checkPred (Rose.Node a
a [Tree a]
as) =
case a -> Either n p
validShrink a
a of
Left n
_ -> Maybe (p, [Tree a])
forall a. Maybe a
Nothing
Right p
b -> (p, [Tree a]) -> Maybe (p, [Tree a])
forall a. a -> Maybe a
Just (p
b, [Tree a]
as)
pathAny :: ShrinkTree a -> Gen (NonEmpty a)
pathAny :: forall a. ShrinkTree a -> Gen (NonEmpty a)
pathAny = (Either Void (NonEmpty a) -> NonEmpty a)
-> Gen (Either Void (NonEmpty a)) -> Gen (NonEmpty a)
forall a b. (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Void -> NonEmpty a)
-> (NonEmpty a -> NonEmpty a)
-> Either Void (NonEmpty a)
-> NonEmpty a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Void -> NonEmpty a
forall a. Void -> a
absurd NonEmpty a -> NonEmpty a
forall a. a -> a
id) (Gen (Either Void (NonEmpty a)) -> Gen (NonEmpty a))
-> (ShrinkTree a -> Gen (Either Void (NonEmpty a)))
-> ShrinkTree a
-> Gen (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Either Void a)
-> ShrinkTree a -> Gen (Either Void (NonEmpty a))
forall a p n.
(a -> Either n p) -> ShrinkTree a -> Gen (Either n (NonEmpty p))
path a -> Either Void a
forall a b. b -> Either a b
Right