quickspec-2.2: src/QuickSpec/Internal/Pruning.hs
-- A type of pruners.
{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE FunctionalDependencies, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, DefaultSignatures, GADTs, TypeOperators, DeriveFunctor, DeriveTraversable #-}
module QuickSpec.Internal.Pruning where
import QuickSpec.Internal.Prop
import QuickSpec.Internal.Testing
import QuickSpec.Internal.Type(Type)
import Twee.Pretty
import Control.Monad.Trans.Class
import Control.Monad.IO.Class
import Control.Monad.Trans.State.Strict
import Control.Monad.Trans.Reader
import Data.Maybe
data Theorem norm =
Theorem {
prop :: Prop norm,
axiomsUsed :: [(Prop norm, [Prop norm])] }
deriving (Functor, Foldable, Traversable)
instance Pretty norm => Pretty (Theorem norm) where
pPrint thm =
(text "prop =" <+> pPrint (prop thm)) $$
(text "axioms used =" <+> pPrint (axiomsUsed thm))
class Monad m => MonadPruner term norm m | m -> term norm where
normaliser :: m (term -> norm)
add :: Prop term -> m Bool
decodeNormalForm :: (Type -> Maybe term) -> norm -> m (Maybe term)
normTheorems :: m [Theorem norm]
default normaliser :: (MonadTrans t, MonadPruner term norm m', m ~ t m') => m (term -> norm)
normaliser = lift normaliser
default add :: (MonadTrans t, MonadPruner term norm m', m ~ t m') => Prop term -> m Bool
add = lift . add
default normTheorems :: (MonadTrans t, MonadPruner term' norm m', m ~ t m') => m [Theorem norm]
normTheorems = lift normTheorems
default decodeNormalForm :: (MonadTrans t, MonadPruner term norm m', m ~ t m') => (Type -> Maybe term) -> norm -> m (Maybe term)
decodeNormalForm hole t = lift (decodeNormalForm hole t)
decodeTheorem :: MonadPruner term norm m => (Type -> Maybe term) -> Theorem norm -> m (Maybe (Theorem term))
decodeTheorem hole thm = elimMaybeThm <$> mapM (decodeNormalForm hole) thm
where
elimMaybeThm (Theorem prop axs) =
case sequence prop of
Nothing -> Nothing
Just prop -> Just (Theorem prop (mapMaybe elimMaybeAx axs))
elimMaybeAx (ax, insts) =
case sequence ax of
Nothing -> Nothing
Just ax -> Just (ax, mapMaybe elimMaybeInst insts)
elimMaybeInst = sequence
theorems :: MonadPruner term norm m => (Type -> Maybe term) -> m [Theorem term]
theorems hole = do
thms <- normTheorems
catMaybes <$> mapM (decodeTheorem hole) thms
instance MonadPruner term norm m => MonadPruner term norm (StateT s m)
instance MonadPruner term norm m => MonadPruner term norm (ReaderT r m)
normalise :: MonadPruner term norm m => term -> m norm
normalise t = do
norm <- normaliser
return (norm t)
newtype ReadOnlyPruner m a = ReadOnlyPruner { withReadOnlyPruner :: m a }
deriving (Functor, Applicative, Monad, MonadIO, MonadTester testcase term)
instance MonadTrans ReadOnlyPruner where
lift = ReadOnlyPruner
instance MonadPruner term norm m => MonadPruner term norm (ReadOnlyPruner m) where
normaliser = ReadOnlyPruner normaliser
add _ = return True
newtype WatchPruner term m a = WatchPruner (StateT [Prop term] m a)
deriving (Functor, Applicative, Monad, MonadTrans, MonadIO, MonadTester testcase term)
instance MonadPruner term norm m => MonadPruner term norm (WatchPruner term m) where
normaliser = lift normaliser
add prop = do
res <- lift (add prop)
WatchPruner (modify (prop:))
return res
watchPruner :: Monad m => WatchPruner term m a -> m (a, [Prop term])
watchPruner (WatchPruner mx) = do
(x, props) <- runStateT mx []
return (x, reverse props)