{-# LANGUAGE DefaultSignatures         #-}
{-# LANGUAGE DeriveAnyClass            #-}
{-# LANGUAGE DeriveGeneric             #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances         #-}
{-# LANGUAGE TemplateHaskell           #-}
{-# LANGUAGE UndecidableInstances      #-}
module Experimenter.Parameter.Type where

import           Control.DeepSeq
import           Control.Lens
import qualified Data.ByteString as BS
import           Data.Serialize  as S
import qualified Data.Text       as T
import           GHC.Generics


data ExperimentDesign
  = FullFactory
  | SingleInstance
  deriving (ExperimentDesign
forall a. a -> a -> Bounded a
maxBound :: ExperimentDesign
$cmaxBound :: ExperimentDesign
minBound :: ExperimentDesign
$cminBound :: ExperimentDesign
Bounded, Int -> ExperimentDesign
ExperimentDesign -> Int
ExperimentDesign -> [ExperimentDesign]
ExperimentDesign -> ExperimentDesign
ExperimentDesign -> ExperimentDesign -> [ExperimentDesign]
ExperimentDesign
-> ExperimentDesign -> ExperimentDesign -> [ExperimentDesign]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ExperimentDesign
-> ExperimentDesign -> ExperimentDesign -> [ExperimentDesign]
$cenumFromThenTo :: ExperimentDesign
-> ExperimentDesign -> ExperimentDesign -> [ExperimentDesign]
enumFromTo :: ExperimentDesign -> ExperimentDesign -> [ExperimentDesign]
$cenumFromTo :: ExperimentDesign -> ExperimentDesign -> [ExperimentDesign]
enumFromThen :: ExperimentDesign -> ExperimentDesign -> [ExperimentDesign]
$cenumFromThen :: ExperimentDesign -> ExperimentDesign -> [ExperimentDesign]
enumFrom :: ExperimentDesign -> [ExperimentDesign]
$cenumFrom :: ExperimentDesign -> [ExperimentDesign]
fromEnum :: ExperimentDesign -> Int
$cfromEnum :: ExperimentDesign -> Int
toEnum :: Int -> ExperimentDesign
$ctoEnum :: Int -> ExperimentDesign
pred :: ExperimentDesign -> ExperimentDesign
$cpred :: ExperimentDesign -> ExperimentDesign
succ :: ExperimentDesign -> ExperimentDesign
$csucc :: ExperimentDesign -> ExperimentDesign
Enum, ExperimentDesign -> ExperimentDesign -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExperimentDesign -> ExperimentDesign -> Bool
$c/= :: ExperimentDesign -> ExperimentDesign -> Bool
== :: ExperimentDesign -> ExperimentDesign -> Bool
$c== :: ExperimentDesign -> ExperimentDesign -> Bool
Eq, Eq ExperimentDesign
ExperimentDesign -> ExperimentDesign -> Bool
ExperimentDesign -> ExperimentDesign -> Ordering
ExperimentDesign -> ExperimentDesign -> ExperimentDesign
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ExperimentDesign -> ExperimentDesign -> ExperimentDesign
$cmin :: ExperimentDesign -> ExperimentDesign -> ExperimentDesign
max :: ExperimentDesign -> ExperimentDesign -> ExperimentDesign
$cmax :: ExperimentDesign -> ExperimentDesign -> ExperimentDesign
>= :: ExperimentDesign -> ExperimentDesign -> Bool
$c>= :: ExperimentDesign -> ExperimentDesign -> Bool
> :: ExperimentDesign -> ExperimentDesign -> Bool
$c> :: ExperimentDesign -> ExperimentDesign -> Bool
<= :: ExperimentDesign -> ExperimentDesign -> Bool
$c<= :: ExperimentDesign -> ExperimentDesign -> Bool
< :: ExperimentDesign -> ExperimentDesign -> Bool
$c< :: ExperimentDesign -> ExperimentDesign -> Bool
compare :: ExperimentDesign -> ExperimentDesign -> Ordering
$ccompare :: ExperimentDesign -> ExperimentDesign -> Ordering
Ord, forall x. Rep ExperimentDesign x -> ExperimentDesign
forall x. ExperimentDesign -> Rep ExperimentDesign x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ExperimentDesign x -> ExperimentDesign
$cfrom :: forall x. ExperimentDesign -> Rep ExperimentDesign x
Generic, ExperimentDesign -> ()
forall a. (a -> ()) -> NFData a
rnf :: ExperimentDesign -> ()
$crnf :: ExperimentDesign -> ()
NFData)

data ParameterSetup a =
  forall b . (Show b, Ord b, Serialize b) =>
  ParameterSetup
  { forall a. ParameterSetup a -> Text
parameterName         :: !T.Text                          -- ^ Name of parameter.
  , ()
setParameter          :: !(b -> a -> a)                   -- ^ Set the parameter.
  , ()
getParameter          :: !(a -> b)                        -- ^ Get the parameter from the current state.
  , ()
modifyParameter       :: !(Maybe (b -> IO [b]))           -- ^ Either no modification or function.
  , ()
bounds                :: !(Maybe (b, b))                  -- ^ Bounds (inclusive).
  , ()
skipPreparationPhase  :: !(Maybe (b -> Bool))             -- ^ Skip the preparation phase if True (e.g. to skip learning phase). Default: False.
  , ()
alterExperimentDesign :: !(Maybe (b -> ExperimentDesign)) -- ^ Change the experiment design. Default: Full-Factory design.
  }
-- makeLenses ''ParameterSetup  -- does not work with ExistentialQuantification


data ParameterSetting a =
  ParameterSetting
  { forall a. ParameterSetting a -> Text
_parameterSettingName                 :: !T.Text
  , forall a. ParameterSetting a -> ByteString
_parameterSettingValue                :: !BS.ByteString
  , forall a. ParameterSetting a -> Bool
_parameterSettingSkipPreparationPhase :: !Bool
  , forall a. ParameterSetting a -> ExperimentDesign
_parameterSettingExperimentDesign     :: !ExperimentDesign
  } deriving (ParameterSetting a -> ParameterSetting a -> Bool
forall a. ParameterSetting a -> ParameterSetting a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ParameterSetting a -> ParameterSetting a -> Bool
$c/= :: forall a. ParameterSetting a -> ParameterSetting a -> Bool
== :: ParameterSetting a -> ParameterSetting a -> Bool
$c== :: forall a. ParameterSetting a -> ParameterSetting a -> Bool
Eq, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (ParameterSetting a) x -> ParameterSetting a
forall a x. ParameterSetting a -> Rep (ParameterSetting a) x
$cto :: forall a x. Rep (ParameterSetting a) x -> ParameterSetting a
$cfrom :: forall a x. ParameterSetting a -> Rep (ParameterSetting a) x
Generic, forall a. ParameterSetting a -> ()
forall a. (a -> ()) -> NFData a
rnf :: ParameterSetting a -> ()
$crnf :: forall a. ParameterSetting a -> ()
NFData)
makeLenses ''ParameterSetting


getParameterData :: ParameterSetup a -> a -> BS.ByteString
getParameterData :: forall a. ParameterSetup a -> a -> ByteString
getParameterData (ParameterSetup Text
_ b -> a -> a
_ a -> b
getter Maybe (b -> IO [b])
_ Maybe (b, b)
_ Maybe (b -> Bool)
_ Maybe (b -> ExperimentDesign)
_) a
a = Put -> ByteString
runPut forall a b. (a -> b) -> a -> b
$ forall t. Serialize t => Putter t
put forall a b. (a -> b) -> a -> b
$ a -> b
getter a
a


mkParameterSetting :: ParameterSetup a -> a -> ParameterSetting a
mkParameterSetting :: forall a. ParameterSetup a -> a -> ParameterSetting a
mkParameterSetting (ParameterSetup Text
n b -> a -> a
_ a -> b
getter Maybe (b -> IO [b])
_ Maybe (b, b)
_ Maybe (b -> Bool)
drp Maybe (b -> ExperimentDesign)
design) a
a = forall a.
Text
-> ByteString -> Bool -> ExperimentDesign -> ParameterSetting a
ParameterSetting Text
n (Put -> ByteString
runPut forall a b. (a -> b) -> a -> b
$ forall t. Serialize t => Putter t
put b
aVal) (forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (\b -> Bool
x -> b -> Bool
x b
aVal) Maybe (b -> Bool)
drp) (forall b a. b -> (a -> b) -> Maybe a -> b
maybe ExperimentDesign
FullFactory (\b -> ExperimentDesign
x -> b -> ExperimentDesign
x b
aVal) Maybe (b -> ExperimentDesign)
design)
  where aVal :: b
aVal = a -> b
getter a
a