g2-0.2.0.0: src/G2/Liquid/Inference/InfStack.hs
{-# LANGUAGE LambdaCase #-}
module G2.Liquid.Inference.InfStack ( InfStack
, runInfStack
, execInfStack
, infLiftIO
, incrMaxDepthI
, incrMaxCExI
, incrMaxTimeI
, incrMaxSynthSizeI
, extraMaxDepthI
, extraMaxCExI
, extraMaxTimeI
, maxSynthCoeffSizeI
, setMaxSynthCoeffSizeI
, logEventStartM
, logEventEndM
, getLogM
, startLevelTimer
, endLevelTimer
, withConfigs
, Event (..)
, mapEvent
, Counters (..)
, incrLoopCountLog
, incrBackTrackLog
, incrSearchBelowLog
, incrNegatedModelLog ) where
import G2.Data.Timer
import G2.Language
import G2.Liquid.Inference.Config
import Control.Monad.Reader
import Control.Monad.State.Lazy as S
import qualified Data.HashSet as HS
import qualified Data.HashMap.Strict as HM
import qualified Data.Text as T
import Data.Time.Clock
data Event n = CExSE
| InfSE n
| Verify
| Synth
| UpdateMeasures
| UpdateEvals
deriving (Eq, Read, Show)
mapEvent :: (a -> b) -> Event a -> Event b
mapEvent _ CExSE = CExSE
mapEvent f (InfSE n) = InfSE (f n)
mapEvent _ Verify = Verify
mapEvent _ Synth = Synth
mapEvent _ UpdateMeasures = UpdateMeasures
mapEvent _ UpdateEvals = UpdateEvals
data Counters = Counters { loop_count :: HM.HashMap (HS.HashSet Name) Int
, backtracks :: Int
, searched_below :: Int
, negated_models :: Int }
type InfStack m = StateT (Timer (Event Name))
(StateT (Timer (HS.HashSet Name))
(StateT Counters (ReaderT Configs (StateT Progress m)))
)
runInfStack :: MonadIO m => Configs -> Progress -> InfStack m a
-> m (a, Timer (Event Name), Timer (HS.HashSet Name), Counters)
runInfStack configs prog m = do
ev_timer <- liftIO $ newTimer
lvl_timer <- liftIO $ newTimer
(((a, ev_tm), lvl_tm), loops) <- runProgresser
(runConfigs
(runStateT
(runTimer (runTimer m ev_timer) lvl_timer)
newCounter
) configs
) prog
return (a, ev_tm, lvl_tm, loops)
execInfStack :: MonadIO m => Configs -> Progress -> InfStack m a -> m a
execInfStack configs prog s = return . (\(x, _, _, _) -> x) =<< runInfStack configs prog s
infLiftIO :: MonadIO m => IO a -> InfStack m a
infLiftIO = lift . lift . lift . liftIO
incrMaxDepthI :: Monad m => InfStack m ()
incrMaxDepthI = lift . lift . lift $ incrMaxDepthM
incrMaxCExI :: Monad m => (T.Text, Maybe T.Text) -> InfStack m ()
incrMaxCExI = lift . lift . lift . incrMaxCExM
incrMaxTimeI :: Monad m => (T.Text, Maybe T.Text) -> InfStack m ()
incrMaxTimeI = lift . lift . lift . incrMaxTimeM
extraMaxCExI :: Monad m => (T.Text, Maybe T.Text) -> InfStack m Int
extraMaxCExI n = lift . lift . lift $ gets (extraMaxCEx n)
extraMaxDepthI :: Monad m => InfStack m Int
extraMaxDepthI = lift . lift . lift $ gets extraMaxDepth
extraMaxTimeI :: Monad m => (T.Text, Maybe T.Text) -> InfStack m NominalDiffTime
extraMaxTimeI n = lift . lift . lift $ gets (extraMaxTime n)
incrMaxSynthSizeI :: Monad m => InfStack m ()
incrMaxSynthSizeI = do
lift . lift . lift $ incrMaxSynthFormSizeM
lift . lift . lift $ incrMaxSynthCoeffSizeM
maxSynthCoeffSizeI :: Monad m => InfStack m MaxSize
maxSynthCoeffSizeI = lift . lift . lift $ maxSynthCoeffSizeM
setMaxSynthCoeffSizeI :: Monad m => MaxSize -> InfStack m ()
setMaxSynthCoeffSizeI max_size = do
lift . lift . lift $ setMaxSynthCoeffSizeM max_size
startLevelTimer :: MonadIO m => [Name] -> InfStack m ()
startLevelTimer = lift . logEventStartM . HS.fromList
endLevelTimer :: MonadIO m => InfStack m ()
endLevelTimer = lift $ logEventEndM
-- Configurations
withConfigs :: Monad m =>
(Configs -> Configs)
-> InfStack m a
-> InfStack m a
withConfigs f m = do
mapStateT (mapStateT (mapStateT (withReaderT f))) m
-- Counters
newCounter :: Counters
newCounter = Counters { loop_count = HM.empty, backtracks = 0, searched_below = 0, negated_models = 0 }
incrLoopCountLog :: Monad m => [Name] -> InfStack m ()
incrLoopCountLog ns =
let
hs_ns = HS.fromList ns
in
lift . lift $ S.modify (\c@(Counters { loop_count = lcs }) ->
c { loop_count = HM.alter (\case (Just i) -> Just (i + 1)
Nothing -> Just 0) hs_ns lcs
}
)
incrBackTrackLog :: Monad m => InfStack m ()
incrBackTrackLog =
lift . lift $ S.modify (\c@(Counters { backtracks = i }) -> c { backtracks = i + 1 })
incrSearchBelowLog :: Monad m => InfStack m ()
incrSearchBelowLog =
lift . lift $ S.modify (\c@(Counters { searched_below = i }) -> c { searched_below = i + 1 })
incrNegatedModelLog :: Monad m => InfStack m ()
incrNegatedModelLog =
lift . lift $ S.modify (\c@(Counters { negated_models = i }) -> c { negated_models = i + 1 })