-- |Conversion to 'GenericData' with time and space limit.
module Data.Data.Eval 
    ( eval
    , evalWithBudget
    ) where

import Data.Data.GenRep (GenericData, constructor)
import System.IO.Parallel (manyParallel)
import System.SimpleTimeout.Limits

import Data.Data (Data, gmapQ)

-------------------------

-- |Evaluation with time an size limit.
eval :: Data a => TimeLimit -> SizeLimit -> a -> IO GenericData
eval :: TimeLimit -> SizeLimit -> a -> IO GenericData
eval TimeLimit
seconds SizeLimit
chars a
x = do
    Budget
b <- TimeLimit -> SizeLimit -> IO Budget
newBudget TimeLimit
seconds SizeLimit
chars
    Budget -> a -> IO GenericData
forall a. Data a => Budget -> a -> IO GenericData
evalWithBudget Budget
b a
x

-- |Gives more control over the resources
evalWithBudget :: Data a => Budget -> a -> IO GenericData
evalWithBudget :: Budget -> a -> IO GenericData
evalWithBudget Budget
b a
x
    = Budget -> a -> IO [GenericData] -> IO GenericData
forall a.
Data a =>
Budget -> a -> IO [GenericData] -> IO GenericData
constructor Budget
b a
x
    (IO [GenericData] -> IO GenericData)
-> IO [GenericData] -> IO GenericData
forall a b. (a -> b) -> a -> b
$ [IO GenericData] -> IO [GenericData]
forall a. [IO a] -> IO [a]
manyParallel
    ([IO GenericData] -> IO [GenericData])
-> [IO GenericData] -> IO [GenericData]
forall a b. (a -> b) -> a -> b
$ (forall d. Data d => d -> IO GenericData) -> a -> [IO GenericData]
forall a u. Data a => (forall d. Data d => d -> u) -> a -> [u]
gmapQ (Budget -> d -> IO GenericData
forall a. Data a => Budget -> a -> IO GenericData
evalWithBudget Budget
b) a
x