% Depth Monitoring for Non-Deterministic Computations % Sebastian Fischer (sebf@informatik.uni-kiel.de) This module provides a strategy transformer that extends the evaluation context with a counter for the search depth. > {-# LANGUAGE > GeneralizedNewtypeDeriving, > MultiParamTypeClasses, > OverlappingInstances, > FlexibleInstances, > TypeFamilies > #-} > > module CFLP.Strategies.DepthCounter ( > > DepthCounter(..), Depth, DepthCtx, countDepth > > ) where > > import Control.Monad > > import CFLP.Control.Monad.Update > > import CFLP.Control.Strategy The interface of an evaluation context that can store a depth counter is given by the following type class. > class DepthCounter c > where > currentDepth :: c -> Int > incrementDepth :: c -> c -> c The first argument of `incrementDepth` will always be ignored and is only used to support the type checker. We define uniform liftings for depth counters over arbitrary context transformers. > instance (DepthCounter c, Transformer t) => DepthCounter (t c) > where > currentDepth = currentDepth . project > > incrementDepth _ c = replace c (incrementDepth undefined (project c)) A depth context adds a counter for the depth. > data DepthCtx c = DepthCtx Int c It is an instance of `DepthCounter`. > instance DepthCounter (DepthCtx c) > where > currentDepth (DepthCtx d _) = d > incrementDepth _ (DepthCtx d c) = DepthCtx (d+1) c It also is a transformer for evaluation contexts > instance Transformer DepthCtx > where > project (DepthCtx _ c) = c > replace (DepthCtx d _) = DepthCtx d We define a strategy transformer for depth counting. > newtype Depth s a = Depth { fromDepth :: s a } > deriving (Monad, MonadPlus, Enumerable) > > type instance Ctx (Depth s) = DepthCtx (Ctx s) > type instance Res (Depth s) = Depth (Res s) The strategy-transformer instance increments the counter at each non-deterministic choice. > instance DepthCounter c => StrategyT c Depth > where > liftStrategy _ = Depth > baseStrategy _ = fromDepth > > extendChoices c _ = map (update (return . incrementDepth c)>>) The operation `countDepth` adds a depth counter to a strategy. > countDepth :: Monad s => s c -> Depth s (DepthCtx c) > countDepth = Depth . liftM (DepthCtx 0)