module Autolib.Util.Generate where
import Autolib.Util.Zufall
import System.Random
type Generator a = Int -> IO ( a )
type Operator a = ( Int, [ a ] -> a )
data Config a =
Config { forall a. Config a -> [Generator a]
base :: [ Generator a ]
, forall a. Config a -> [Operator a]
ops :: [ Operator a ]
, forall a. Config a -> Int
depth :: Int
, forall a. Config a -> Int
size :: Int
}
generate :: Config a -> IO ( a )
generate :: forall a. Config a -> IO a
generate Config a
conf | Config a -> Int
forall a. Config a -> Int
depth Config a
conf Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = do
gen <- [Generator a] -> IO (Generator a)
forall (m :: * -> *) a. RandomC m => [a] -> m a
eins ([Generator a] -> IO (Generator a))
-> [Generator a] -> IO (Generator a)
forall a b. (a -> b) -> a -> b
$ Config a -> [Generator a]
forall a. Config a -> [Generator a]
base Config a
conf
gen $ size conf
generate Config a
conf = do
( arity, op ) <- [(Int, [a] -> a)] -> IO (Int, [a] -> a)
forall (m :: * -> *) a. RandomC m => [a] -> m a
eins ([(Int, [a] -> a)] -> IO (Int, [a] -> a))
-> [(Int, [a] -> a)] -> IO (Int, [a] -> a)
forall a b. (a -> b) -> a -> b
$ Config a -> [(Int, [a] -> a)]
forall a. Config a -> [Operator a]
ops Config a
conf
if arity > size conf
then generate conf { depth = 0 }
else do
xs <- summe arity $ size conf
gs <- sequence $ do
x <- xs
return $ do
generate $ conf { depth = pred $ depth conf , size = x }
return $ op gs