{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}
module Test.Verification
(
assuming
, (==>)
, property
, chooseBool
, chooseInt
, chooseInteger
, Gen
, getSize
, Verifiable(..)
, Property(..)
, Assumption(..)
, GenEnv(..)
, toNativeProperty
)
where
import Control.Monad.Trans (lift)
import Control.Monad.Trans.Reader
data Property = BoolProperty Bool
| AssumptionProp Assumption
deriving Int -> Property -> ShowS
[Property] -> ShowS
Property -> String
(Int -> Property -> ShowS)
-> (Property -> String) -> ([Property] -> ShowS) -> Show Property
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Property] -> ShowS
$cshowList :: [Property] -> ShowS
show :: Property -> String
$cshow :: Property -> String
showsPrec :: Int -> Property -> ShowS
$cshowsPrec :: Int -> Property -> ShowS
Show
class Verifiable prop where
verifying :: prop -> Property
instance Verifiable Bool where verifying :: Bool -> Property
verifying = Bool -> Property
BoolProperty
property :: Bool -> Property
property :: Bool -> Property
property = Bool -> Property
forall prop. Verifiable prop => prop -> Property
verifying
data Assumption = Assuming { Assumption -> Bool
preCondition :: Bool,
Assumption -> Property
assumedProp :: Property }
deriving Int -> Assumption -> ShowS
[Assumption] -> ShowS
Assumption -> String
(Int -> Assumption -> ShowS)
-> (Assumption -> String)
-> ([Assumption] -> ShowS)
-> Show Assumption
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Assumption] -> ShowS
$cshowList :: [Assumption] -> ShowS
show :: Assumption -> String
$cshow :: Assumption -> String
showsPrec :: Int -> Assumption -> ShowS
$cshowsPrec :: Int -> Assumption -> ShowS
Show
assuming :: Verifiable t => Bool -> t -> Property
assuming :: Bool -> t -> Property
assuming Bool
precond t
test = Assumption -> Property
AssumptionProp (Assumption -> Property) -> Assumption -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property -> Assumption
Assuming Bool
precond (Property -> Assumption) -> Property -> Assumption
forall a b. (a -> b) -> a -> b
$ t -> Property
forall prop. Verifiable prop => prop -> Property
verifying t
test
(==>) :: Verifiable t => Bool -> t -> Property
==> :: Bool -> t -> Property
(==>) = Bool -> t -> Property
forall t. Verifiable t => Bool -> t -> Property
assuming
infixr 0 ==>
instance Verifiable Property where
verifying :: Property -> Property
verifying = Property -> Property
forall a. a -> a
id
data GenEnv m = GenEnv { GenEnv m -> m Bool
genChooseBool :: m Bool
, GenEnv m -> (Int, Int) -> m Int
genChooseInt :: (Int, Int) -> m Int
, GenEnv m -> (Integer, Integer) -> m Integer
genChooseInteger :: (Integer, Integer) -> m Integer
, GenEnv m -> m Int
genGetSize :: m Int
}
newtype Gen a =
Gen { Gen a
-> forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a
unGen :: forall m. Monad m => ReaderT (GenEnv m) m a }
instance Functor Gen where
fmap :: (a -> b) -> Gen a -> Gen b
fmap a -> b
f (Gen forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a
m) = (forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m b)
-> Gen b
forall a.
(forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
Gen ((a -> b) -> ReaderT (GenEnv m) m a -> ReaderT (GenEnv m) m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f ReaderT (GenEnv m) m a
forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a
m)
instance Applicative Gen where
pure :: a -> Gen a
pure a
x = (forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
forall a.
(forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
Gen (a -> ReaderT (GenEnv m) m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
x)
(Gen forall (m :: Type -> Type).
Monad m =>
ReaderT (GenEnv m) m (a -> b)
f) <*> :: Gen (a -> b) -> Gen a -> Gen b
<*> (Gen forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a
x) = (forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m b)
-> Gen b
forall a.
(forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
Gen (ReaderT (GenEnv m) m (a -> b)
forall (m :: Type -> Type).
Monad m =>
ReaderT (GenEnv m) m (a -> b)
f ReaderT (GenEnv m) m (a -> b)
-> ReaderT (GenEnv m) m a -> ReaderT (GenEnv m) m b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> ReaderT (GenEnv m) m a
forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a
x)
instance Monad Gen where
Gen forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a
x >>= :: Gen a -> (a -> Gen b) -> Gen b
>>= a -> Gen b
f = (forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m b)
-> Gen b
forall a.
(forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
Gen (ReaderT (GenEnv m) m a
forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a
x ReaderT (GenEnv m) m a
-> (a -> ReaderT (GenEnv m) m b) -> ReaderT (GenEnv m) m b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x' -> Gen b
-> forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m b
forall a.
Gen a
-> forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a
unGen (a -> Gen b
f a
x'))
chooseBool :: Gen Bool
chooseBool :: Gen Bool
chooseBool = (forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m Bool)
-> Gen Bool
forall a.
(forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
Gen ((GenEnv m -> m Bool) -> ReaderT (GenEnv m) m (m Bool)
forall (m :: Type -> Type) r a.
Monad m =>
(r -> a) -> ReaderT r m a
asks GenEnv m -> m Bool
forall (m :: Type -> Type). GenEnv m -> m Bool
genChooseBool ReaderT (GenEnv m) m (m Bool)
-> (m Bool -> ReaderT (GenEnv m) m Bool)
-> ReaderT (GenEnv m) m Bool
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= m Bool -> ReaderT (GenEnv m) m Bool
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift)
chooseInt :: (Int, Int) -> Gen Int
chooseInt :: (Int, Int) -> Gen Int
chooseInt (Int, Int)
r = (forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m Int)
-> Gen Int
forall a.
(forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
Gen ((GenEnv m -> (Int, Int) -> m Int)
-> ReaderT (GenEnv m) m ((Int, Int) -> m Int)
forall (m :: Type -> Type) r a.
Monad m =>
(r -> a) -> ReaderT r m a
asks GenEnv m -> (Int, Int) -> m Int
forall (m :: Type -> Type). GenEnv m -> (Int, Int) -> m Int
genChooseInt ReaderT (GenEnv m) m ((Int, Int) -> m Int)
-> (((Int, Int) -> m Int) -> ReaderT (GenEnv m) m Int)
-> ReaderT (GenEnv m) m Int
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= m Int -> ReaderT (GenEnv m) m Int
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Int -> ReaderT (GenEnv m) m Int)
-> (((Int, Int) -> m Int) -> m Int)
-> ((Int, Int) -> m Int)
-> ReaderT (GenEnv m) m Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((Int, Int) -> m Int) -> (Int, Int) -> m Int
forall a b. (a -> b) -> a -> b
$(Int, Int)
r))
chooseInteger :: (Integer, Integer) -> Gen Integer
chooseInteger :: (Integer, Integer) -> Gen Integer
chooseInteger (Integer, Integer)
r = (forall (m :: Type -> Type).
Monad m =>
ReaderT (GenEnv m) m Integer)
-> Gen Integer
forall a.
(forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
Gen ((GenEnv m -> (Integer, Integer) -> m Integer)
-> ReaderT (GenEnv m) m ((Integer, Integer) -> m Integer)
forall (m :: Type -> Type) r a.
Monad m =>
(r -> a) -> ReaderT r m a
asks GenEnv m -> (Integer, Integer) -> m Integer
forall (m :: Type -> Type).
GenEnv m -> (Integer, Integer) -> m Integer
genChooseInteger ReaderT (GenEnv m) m ((Integer, Integer) -> m Integer)
-> (((Integer, Integer) -> m Integer)
-> ReaderT (GenEnv m) m Integer)
-> ReaderT (GenEnv m) m Integer
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= m Integer -> ReaderT (GenEnv m) m Integer
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Integer -> ReaderT (GenEnv m) m Integer)
-> (((Integer, Integer) -> m Integer) -> m Integer)
-> ((Integer, Integer) -> m Integer)
-> ReaderT (GenEnv m) m Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((Integer, Integer) -> m Integer)
-> (Integer, Integer) -> m Integer
forall a b. (a -> b) -> a -> b
$(Integer, Integer)
r))
getSize :: Gen Int
getSize :: Gen Int
getSize = (forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m Int)
-> Gen Int
forall a.
(forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m a)
-> Gen a
Gen ((GenEnv m -> m Int) -> ReaderT (GenEnv m) m (m Int)
forall (m :: Type -> Type) r a.
Monad m =>
(r -> a) -> ReaderT r m a
asks GenEnv m -> m Int
forall (m :: Type -> Type). GenEnv m -> m Int
genGetSize ReaderT (GenEnv m) m (m Int)
-> (m Int -> ReaderT (GenEnv m) m Int) -> ReaderT (GenEnv m) m Int
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= m Int -> ReaderT (GenEnv m) m Int
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift)
toNativeProperty :: Monad m => GenEnv m -> Gen b -> m b
toNativeProperty :: GenEnv m -> Gen b -> m b
toNativeProperty GenEnv m
gens (Gen forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m b
gprops) = ReaderT (GenEnv m) m b -> GenEnv m -> m b
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (GenEnv m) m b
forall (m :: Type -> Type). Monad m => ReaderT (GenEnv m) m b
gprops GenEnv m
gens