{-# LANGUAGE AllowAmbiguousTypes #-}{-# LANGUAGE FunctionalDependencies #-}{-# LANGUAGE QuantifiedConstraints #-}{-# LANGUAGE RecordWildCards #-}{-# LANGUAGE UndecidableInstances #-}-- | Model-Based Testing library for use with Haskell QuickCheck.---- This module provides the basic machinery to define a `StateModel` from which /traces/ can-- be generated and executed against some /actual/ implementation code to define monadic `Property`-- to be asserted by QuickCheck.moduleTest.QuickCheck.StateModel(moduleTest.QuickCheck.StateModel.Variables,StateModel(..),RunModel(..),PostconditionM(..),WithUsedVars(..),Annotated(..),Step(..),Polarity(..),ActionWithPolarity(..),LookUp,Actions(..),patternActions,EnvEntry(..),pattern(:=?),Env,Generic,IsPerformResult,Options(..),monitorPost,counterexamplePost,stateAfter,runActions,lookUpVar,lookUpVarMaybe,viewAtType,initialAnnotatedState,computeNextState,computePrecondition,computeArbitraryAction,computeShrinkAction,generateActionsWithOptions,shrinkActionsWithOptions,defaultOptions,moreActions,)whereimportControl.MonadimportControl.Monad.ReaderimportControl.Monad.Writer(WriterT,runWriterT,tell)importData.DataimportData.KindimportData.ListimportData.Monoid(Endo(..))importData.SetqualifiedasSetimportData.VoidimportGHC.GenericsimportTest.QuickCheck(Arbitrary,Gen,Property,Smart(..),Testable,counterexample,forAllShrink,frequency,property,resize,shrinkList,sized,tabulate)importTest.QuickCheckqualifiedasQCimportTest.QuickCheck.DynamicLogic.SmartShrinkingimportTest.QuickCheck.MonadicimportTest.QuickCheck.StateModel.Variables-- | The typeclass users implement to define a model against which to validate some implementation.---- To implement a `StateModel`, user needs to provide at least the following:---- * A datatype for `Action`s: Each test case is a sequence of `Action`s that's supposed to lead from-- some `initialState` to some end state,-- * A generator for traces of `Action`s, the `arbitraryAction` function,-- * An `initialState`,-- * A /transition/ function, `nextState`, that "interprets" each `Action` and producing some new `state`.---- For finer grained control over the testing process, one can also define:---- * `shrinkAction`: Shrinking is an important part of MBT as it allows QuickCheck engine to look for simpler-- test cases when something goes wrong which makes troubleshooting easier,-- * `precondition`: Filters generated `Action` depending on the `state`. When `precondition` is False then-- the action is /rejected/ and a new one is tried. This is also useful when shrinking a trace-- in order to ensure that removing some `Action` still produces a valid trace. The `precondition` can be-- somewhat redundant with the generator's conditions,-- * `validFailingAction`: Specifies when an action that fails it's `precondition` can still run as what is-- called a _negative_ action. This means that the action is (1) expected to fail and (2) not expected to-- change the model state. This is very useful for testing the checks and failure conditions in the SUT-- are implemented correctly. Should it be necessary to update the model state with e.g. book-keeping for-- a negative action one can define `failureNextState` - but it is generally recommended to let this be-- as simple an action as possible.class(foralla.Show(Actionstatea),foralla.HasVariables(Actionstatea),Showstate,HasVariablesstate)=>StateModelstatewhere-- | The type of `Action` relevant for this `state`.---- This is expected to be defined as a GADT where the `a` parameter is instantiated to some-- observable output from the SUT a given action is expected to produce. For example, here-- is a fragment of the `Action RegState` (taken from the `Spec.Dynamic.RegistryModel` module) :---- @-- data Action RegState a where-- Spawn :: Action RegState ThreadId-- Register :: String -> Var ThreadId -> Action RegState ()-- KillThread :: Var ThreadId -> Action RegState ()-- @---- The @Spawn@ action should produce a @ThreadId@, whereas the @KillThread@ action does not return-- anything.dataActionstatea-- | Display name for `Action`.-- This is useful to provide sensible statistics about the distribution of `Action`s run-- when checking a property.---- Default implementation uses a poor-man's string manipulation method to extract the-- constructor name from the value.actionName::Actionstatea->StringactionName=[String] -> String
forall a. HasCallStack => [a] -> a
head([String] -> String)
-> (Action state a -> [String]) -> Action state a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.String -> [String]
words(String -> [String])
-> (Action state a -> String) -> Action state a -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Action state a -> String
forall a. Show a => a -> String
show-- | Generator for `Action` depending on `state`.arbitraryAction::VarContext->state->Gen(Any(Actionstate))-- | Shrinker for `Action`.-- Defaults to no-op but as usual, defining a good shrinker greatly enhances the usefulness-- of property-based testing.shrinkAction::Typeablea=>VarContext->state->Actionstatea->[Any(Actionstate)]shrinkActionVarContext
_state
_Action state a
_=[]-- | Initial state of generated traces.initialState::state-- | Transition function for the model.-- The `Var a` parameter is useful to keep reference to actual value of type `a` produced-- by `perform`ing the `Action` inside the `state` so that further actions can use `Lookup`-- to retrieve that data. This allows the model to be ignorant of those values yet maintain-- some references that can be compared and looked for.nextState::Typeablea=>state->Actionstatea->Vara->statenextStatestate
sAction state a
_Var a
_=state
s-- | Transition function for negative actions. Note that most negative testing applications-- should not require an implementation of this function!failureNextState::Typeablea=>state->Actionstatea->statefailureNextStatestate
sAction state a
_=state
s-- | Precondition for filtering generated `Action`.-- This function is applied before the action is performed, it is useful to refine generators that-- can produce more values than are useful.precondition::state->Actionstatea->Boolpreconditionstate
_Action state a
_=Bool
True-- | Precondition for filtering an `Action` that can meaningfully run but is supposed to fail.-- An action will run as a _negative_ action if the `precondition` fails and `validFailingAction` succeeds.-- A negative action should have _no effect_ on the model state. This may not be desierable in all-- situations - in which case one can override this semantics for book-keeping in `failureNextState`.validFailingAction::state->Actionstatea->BoolvalidFailingActionstate
_Action state a
_=Bool
Falsederivinginstance(foralla.Show(Actionstatea))=>Show(Any(Actionstate))newtypePostconditionMma=PostconditionM{forall (m :: * -> *) a.
PostconditionM m a -> WriterT (Endo Property, Endo Property) m a
runPost::WriterT(EndoProperty,EndoProperty)ma}deriving((forall a b. (a -> b) -> PostconditionM m a -> PostconditionM m b)
-> (forall a b. a -> PostconditionM m b -> PostconditionM m a)
-> Functor (PostconditionM m)
forall a b. a -> PostconditionM m b -> PostconditionM m a
forall a b. (a -> b) -> PostconditionM m a -> PostconditionM m b
forall (m :: * -> *) a b.
Functor m =>
a -> PostconditionM m b -> PostconditionM m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> PostconditionM m a -> PostconditionM m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> PostconditionM m a -> PostconditionM m b
fmap :: forall a b. (a -> b) -> PostconditionM m a -> PostconditionM m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> PostconditionM m b -> PostconditionM m a
<$ :: forall a b. a -> PostconditionM m b -> PostconditionM m a
Functor,Functor (PostconditionM m)
Functor (PostconditionM m) =>
(forall a. a -> PostconditionM m a)
-> (forall a b.
PostconditionM m (a -> b)
-> PostconditionM m a -> PostconditionM m b)
-> (forall a b c.
(a -> b -> c)
-> PostconditionM m a -> PostconditionM m b -> PostconditionM m c)
-> (forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m b)
-> (forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m a)
-> Applicative (PostconditionM m)
forall a. a -> PostconditionM m a
forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m a
forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m b
forall a b.
PostconditionM m (a -> b)
-> PostconditionM m a -> PostconditionM m b
forall a b c.
(a -> b -> c)
-> PostconditionM m a -> PostconditionM m b -> PostconditionM m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (PostconditionM m)
forall (m :: * -> *) a. Applicative m => a -> PostconditionM m a
forall (m :: * -> *) a b.
Applicative m =>
PostconditionM m a -> PostconditionM m b -> PostconditionM m a
forall (m :: * -> *) a b.
Applicative m =>
PostconditionM m a -> PostconditionM m b -> PostconditionM m b
forall (m :: * -> *) a b.
Applicative m =>
PostconditionM m (a -> b)
-> PostconditionM m a -> PostconditionM m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> PostconditionM m a -> PostconditionM m b -> PostconditionM m c
$cpure :: forall (m :: * -> *) a. Applicative m => a -> PostconditionM m a
pure :: forall a. a -> PostconditionM m a
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
PostconditionM m (a -> b)
-> PostconditionM m a -> PostconditionM m b
<*> :: forall a b.
PostconditionM m (a -> b)
-> PostconditionM m a -> PostconditionM m b
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> PostconditionM m a -> PostconditionM m b -> PostconditionM m c
liftA2 :: forall a b c.
(a -> b -> c)
-> PostconditionM m a -> PostconditionM m b -> PostconditionM m c
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
PostconditionM m a -> PostconditionM m b -> PostconditionM m b
*> :: forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m b
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
PostconditionM m a -> PostconditionM m b -> PostconditionM m a
<* :: forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m a
Applicative,Applicative (PostconditionM m)
Applicative (PostconditionM m) =>
(forall a b.
PostconditionM m a
-> (a -> PostconditionM m b) -> PostconditionM m b)
-> (forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m b)
-> (forall a. a -> PostconditionM m a)
-> Monad (PostconditionM m)
forall a. a -> PostconditionM m a
forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m b
forall a b.
PostconditionM m a
-> (a -> PostconditionM m b) -> PostconditionM m b
forall (m :: * -> *). Monad m => Applicative (PostconditionM m)
forall (m :: * -> *) a. Monad m => a -> PostconditionM m a
forall (m :: * -> *) a b.
Monad m =>
PostconditionM m a -> PostconditionM m b -> PostconditionM m b
forall (m :: * -> *) a b.
Monad m =>
PostconditionM m a
-> (a -> PostconditionM m b) -> PostconditionM m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
PostconditionM m a
-> (a -> PostconditionM m b) -> PostconditionM m b
>>= :: forall a b.
PostconditionM m a
-> (a -> PostconditionM m b) -> PostconditionM m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
PostconditionM m a -> PostconditionM m b -> PostconditionM m b
>> :: forall a b.
PostconditionM m a -> PostconditionM m b -> PostconditionM m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> PostconditionM m a
return :: forall a. a -> PostconditionM m a
Monad)instanceMonadTransPostconditionMwherelift :: forall (m :: * -> *) a. Monad m => m a -> PostconditionM m a
lift=WriterT (Endo Property, Endo Property) m a -> PostconditionM m a
forall (m :: * -> *) a.
WriterT (Endo Property, Endo Property) m a -> PostconditionM m a
PostconditionM(WriterT (Endo Property, Endo Property) m a -> PostconditionM m a)
-> (m a -> WriterT (Endo Property, Endo Property) m a)
-> m a
-> PostconditionM m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.m a -> WriterT (Endo Property, Endo Property) m a
forall (m :: * -> *) a.
Monad m =>
m a -> WriterT (Endo Property, Endo Property) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
liftevaluatePostCondition::Monadm=>PostconditionMmBool->PropertyMm()evaluatePostCondition :: forall (m :: * -> *).
Monad m =>
PostconditionM m Bool -> PropertyM m ()
evaluatePostConditionPostconditionM m Bool
post=do(Bool
b,(EndoProperty -> Property
mon,EndoProperty -> Property
onFail))<-m (Bool, (Endo Property, Endo Property))
-> PropertyM m (Bool, (Endo Property, Endo Property))
forall (m :: * -> *) a. Monad m => m a -> PropertyM m a
run(m (Bool, (Endo Property, Endo Property))
-> PropertyM m (Bool, (Endo Property, Endo Property)))
-> (PostconditionM m Bool
-> m (Bool, (Endo Property, Endo Property)))
-> PostconditionM m Bool
-> PropertyM m (Bool, (Endo Property, Endo Property))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.WriterT (Endo Property, Endo Property) m Bool
-> m (Bool, (Endo Property, Endo Property))
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT(WriterT (Endo Property, Endo Property) m Bool
-> m (Bool, (Endo Property, Endo Property)))
-> (PostconditionM m Bool
-> WriterT (Endo Property, Endo Property) m Bool)
-> PostconditionM m Bool
-> m (Bool, (Endo Property, Endo Property))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PostconditionM m Bool
-> WriterT (Endo Property, Endo Property) m Bool
forall (m :: * -> *) a.
PostconditionM m a -> WriterT (Endo Property, Endo Property) m a
runPost(PostconditionM m Bool
-> PropertyM m (Bool, (Endo Property, Endo Property)))
-> PostconditionM m Bool
-> PropertyM m (Bool, (Endo Property, Endo Property))
forall a b. (a -> b) -> a -> b
$PostconditionM m Bool
post(Property -> Property) -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PropertyM m ()
monitorProperty -> Property
monBool -> PropertyM m () -> PropertyM m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unlessBool
b(PropertyM m () -> PropertyM m ())
-> PropertyM m () -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$(Property -> Property) -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PropertyM m ()
monitorProperty -> Property
onFailBool -> PropertyM m ()
forall (m :: * -> *). Monad m => Bool -> PropertyM m ()
assertBool
b-- | Apply the property transformation to the property after evaluating-- the postcondition. Useful for collecting statistics while avoiding-- duplication between `monitoring` and `postcondition`.monitorPost::Monadm=>(Property->Property)->PostconditionMm()monitorPost :: forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PostconditionM m ()
monitorPostProperty -> Property
m=WriterT (Endo Property, Endo Property) m () -> PostconditionM m ()
forall (m :: * -> *) a.
WriterT (Endo Property, Endo Property) m a -> PostconditionM m a
PostconditionM(WriterT (Endo Property, Endo Property) m ()
-> PostconditionM m ())
-> WriterT (Endo Property, Endo Property) m ()
-> PostconditionM m ()
forall a b. (a -> b) -> a -> b
$(Endo Property, Endo Property)
-> WriterT (Endo Property, Endo Property) m ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell((Property -> Property) -> Endo Property
forall a. (a -> a) -> Endo a
EndoProperty -> Property
m,Endo Property
forall a. Monoid a => a
mempty)-- | Acts as `Test.QuickCheck.counterexample` if the postcondition fails.counterexamplePost::Monadm=>String->PostconditionMm()counterexamplePost :: forall (m :: * -> *). Monad m => String -> PostconditionM m ()
counterexamplePostString
c=WriterT (Endo Property, Endo Property) m () -> PostconditionM m ()
forall (m :: * -> *) a.
WriterT (Endo Property, Endo Property) m a -> PostconditionM m a
PostconditionM(WriterT (Endo Property, Endo Property) m ()
-> PostconditionM m ())
-> WriterT (Endo Property, Endo Property) m ()
-> PostconditionM m ()
forall a b. (a -> b) -> a -> b
$(Endo Property, Endo Property)
-> WriterT (Endo Property, Endo Property) m ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell(Endo Property
forall a. Monoid a => a
mempty,(Property -> Property) -> Endo Property
forall a. (a -> a) -> Endo a
Endo((Property -> Property) -> Endo Property)
-> (Property -> Property) -> Endo Property
forall a b. (a -> b) -> a -> b
$String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexampleString
c)-- | The result required of `perform` depending on the `Error` type.-- If there are no errors, `Error state = Void`, and-- so we don't need to specify if the action failed or not.typefamilyPerformResultstate(m::Type->Type)awherePerformResultstatema=EitherIsh(Errorstatem)atypefamilyEitherIsheawhereEitherIshVoida=aEitherIshea=EithereaclassIsPerformResulteawhereperformResultToEither::EitherIshea->Eithereainstance{-# OVERLAPPING#-}IsPerformResultVoidawhereperformResultToEither :: EitherIsh Void a -> Either Void a
performResultToEither=a -> Either Void a
EitherIsh Void a -> Either Void a
forall a b. b -> Either a b
Rightinstance{-# OVERLAPPABLE#-}(EitherIshea~Eitherea)=>IsPerformResulteawhereperformResultToEither :: EitherIsh e a -> Either e a
performResultToEither=Either e a -> Either e a
EitherIsh e a -> Either e a
forall a. a -> a
idclass(foralla.Show(Actionstatea),Monadm)=>RunModelstatemwhere-- | The type of errors that actions can throw. If this is defined as anything-- other than `Void` `perform` is required to return `Either (Error state) a`-- instead of `a`.typeErrorstatemtypeErrorstatem=Void-- | Perform an `Action` in some `state` in the `Monad` `m`. This-- is the function that's used to exercise the actual stateful-- implementation, usually through various side-effects as permitted-- by `m`. It produces a value of type `a`, eg. some observable-- output from the `Action` that should later be kept in the-- environment through a `Var a` also passed to the `nextState`-- function.---- The `Lookup` parameter provides an /environment/ to lookup `Var-- a` instances from previous steps.perform::Typeablea=>state->Actionstatea->LookUp->m(PerformResultstatema)-- | Postcondition on the `a` value produced at some step.-- The result is `assert`ed and will make the property fail should it be `False`. This is useful-- to check the implementation produces expected values.postcondition::(state,state)->Actionstatea->LookUp->a->PostconditionMmBoolpostcondition(state, state)
_Action state a
_LookUp
_a
_=Bool -> PostconditionM m Bool
forall a. a -> PostconditionM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pureBool
True-- | Postcondition on the result of running a _negative_ `Action`.-- The result is `assert`ed and will make the property fail should it be `False`. This is useful-- to check the implementation produces e.g. the expected errors or to check that the SUT hasn't-- been updated during the execution of the negative action.postconditionOnFailure::(state,state)->Actionstatea->LookUp->Either(Errorstatem)a->PostconditionMmBoolpostconditionOnFailure(state, state)
_Action state a
_LookUp
_Either (Error state m) a
_=Bool -> PostconditionM m Bool
forall a. a -> PostconditionM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pureBool
True-- | Allows the user to attach additional information to the `Property` at each step of the process.-- This function is given the full transition that's been executed, including the start and ending-- `state`, the `Action`, the current environment to `Lookup` and the value produced by `perform`-- while executing this step.monitoring::(state,state)->Actionstatea->LookUp->Either(Errorstatem)a->Property->Propertymonitoring(state, state)
_Action state a
_LookUp
_Either (Error state m) a
_Property
prop=Property
prop-- | Allows the user to attach additional information to the `Property` if a positive action fails.monitoringFailure::state->Actionstatea->LookUp->Errorstatem->Property->PropertymonitoringFailurestate
_Action state a
_LookUp
_Error state m
_Property
prop=Property
proptypeLookUp=foralla.Typeablea=>Vara->atypeEnv=[EnvEntry]dataEnvEntrywhere(:==)::Typeablea=>Vara->a->EnvEntryinfix5:==pattern(:=?)::foralla.Typeablea=>Vara->a->EnvEntrypatternv$m:=? :: forall {r} {a}.
Typeable a =>
EnvEntry -> (Var a -> a -> r) -> ((# #) -> r) -> r
:=?val<-(viewAtType->Just(v,val))viewAtType::foralla.Typeablea=>EnvEntry->Maybe(Vara,a)viewAtType :: forall a. Typeable a => EnvEntry -> Maybe (Var a, a)
viewAtType((Var a
v::Varb):==a
val)|Justa :~: a
Refl<-forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT@a@b=(Var a, a) -> Maybe (Var a, a)
forall a. a -> Maybe a
Just(Var a
Var a
v,a
a
val)|Bool
otherwise=Maybe (Var a, a)
forall a. Maybe a
NothinglookUpVarMaybe::foralla.Typeablea=>Env->Vara->MaybealookUpVarMaybe :: forall a. Typeable a => Env -> Var a -> Maybe a
lookUpVarMaybe[]Var a
_=Maybe a
forall a. Maybe a
NothinglookUpVarMaybe(((Var a
v'::Varb):==a
a):Env
env)Var a
v=caseforall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT@a@bofJusta :~: a
Refl|Var a
vVar a -> Var a -> Bool
forall a. Eq a => a -> a -> Bool
==Var a
Var a
v'->a -> Maybe a
forall a. a -> Maybe a
Justa
a
aMaybe (a :~: a)
_->Env -> Var a -> Maybe a
forall a. Typeable a => Env -> Var a -> Maybe a
lookUpVarMaybeEnv
envVar a
vlookUpVar::Typeablea=>Env->Vara->alookUpVar :: forall a. Typeable a => Env -> Var a -> a
lookUpVarEnv
envVar a
v=caseEnv -> Var a -> Maybe a
forall a. Typeable a => Env -> Var a -> Maybe a
lookUpVarMaybeEnv
envVar a
vofMaybe a
Nothing->String -> a
forall a. HasCallStack => String -> a
error(String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$String
"Variable "String -> ShowS
forall a. [a] -> [a] -> [a]
++Var a -> String
forall a. Show a => a -> String
showVar a
vString -> ShowS
forall a. [a] -> [a] -> [a]
++String
" is not bound at type "String -> ShowS
forall a. [a] -> [a] -> [a]
++TypeRep -> String
forall a. Show a => a -> String
show(Var a -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRepVar a
v)String -> ShowS
forall a. [a] -> [a] -> [a]
++String
"!"Justa
a->a
adataWithUsedVarsa=WithUsedVarsVarContextadataPolarity=PosPolarity|NegPolarityderiving(Eq Polarity
Eq Polarity =>
(Polarity -> Polarity -> Ordering)
-> (Polarity -> Polarity -> Bool)
-> (Polarity -> Polarity -> Bool)
-> (Polarity -> Polarity -> Bool)
-> (Polarity -> Polarity -> Bool)
-> (Polarity -> Polarity -> Polarity)
-> (Polarity -> Polarity -> Polarity)
-> Ord Polarity
Polarity -> Polarity -> Bool
Polarity -> Polarity -> Ordering
Polarity -> Polarity -> Polarity
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
$ccompare :: Polarity -> Polarity -> Ordering
compare :: Polarity -> Polarity -> Ordering
$c< :: Polarity -> Polarity -> Bool
< :: Polarity -> Polarity -> Bool
$c<= :: Polarity -> Polarity -> Bool
<= :: Polarity -> Polarity -> Bool
$c> :: Polarity -> Polarity -> Bool
> :: Polarity -> Polarity -> Bool
$c>= :: Polarity -> Polarity -> Bool
>= :: Polarity -> Polarity -> Bool
$cmax :: Polarity -> Polarity -> Polarity
max :: Polarity -> Polarity -> Polarity
$cmin :: Polarity -> Polarity -> Polarity
min :: Polarity -> Polarity -> Polarity
Ord,Polarity -> Polarity -> Bool
(Polarity -> Polarity -> Bool)
-> (Polarity -> Polarity -> Bool) -> Eq Polarity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Polarity -> Polarity -> Bool
== :: Polarity -> Polarity -> Bool
$c/= :: Polarity -> Polarity -> Bool
/= :: Polarity -> Polarity -> Bool
Eq)instanceShowPolaritywhereshow :: Polarity -> String
showPolarity
PosPolarity=String
"+"showPolarity
NegPolarity=String
"-"dataActionWithPolaritystatea=Eq(Actionstatea)=>ActionWithPolarity{forall state a. ActionWithPolarity state a -> Action state a
polarAction::Actionstatea,forall state a. ActionWithPolarity state a -> Polarity
polarity::Polarity}instanceHasVariables(Actionstatea)=>HasVariables(ActionWithPolaritystatea)wheregetAllVariables :: ActionWithPolarity state a -> Set (Any Var)
getAllVariables=Action state a -> Set (Any Var)
forall a. HasVariables a => a -> Set (Any Var)
getAllVariables(Action state a -> Set (Any Var))
-> (ActionWithPolarity state a -> Action state a)
-> ActionWithPolarity state a
-> Set (Any Var)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionderivinginstanceEq(Actionstatea)=>Eq(ActionWithPolaritystatea)dataStepstatewhere(:=)::(Typeablea,Eq(Actionstatea),Show(Actionstatea))=>Vara->ActionWithPolaritystatea->Stepstateinfix5:=instance(foralla.HasVariables(Actionstatea))=>HasVariables(Stepstate)wheregetAllVariables :: Step state -> Set (Any Var)
getAllVariables(Var a
var:=ActionWithPolarity state a
act)=Any Var -> Set (Any Var) -> Set (Any Var)
forall a. Ord a => a -> Set a -> Set a
Set.insert(Var a -> Any Var
forall a (f :: * -> *). (Typeable a, Eq (f a)) => f a -> Any f
SomeVar a
var)(Set (Any Var) -> Set (Any Var)) -> Set (Any Var) -> Set (Any Var)
forall a b. (a -> b) -> a -> b
$Action state a -> Set (Any Var)
forall a. HasVariables a => a -> Set (Any Var)
getAllVariables(ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
act)funName::Polarity->StringfunName :: Polarity -> String
funNamePolarity
PosPolarity=String
"action"funNamePolarity
_=String
"failingAction"instanceShow(Stepstate)whereshow :: Step state -> String
show(Var a
var:=ActionWithPolarity state a
act)=Var a -> String
forall a. Show a => a -> String
showVar a
varString -> ShowS
forall a. [a] -> [a] -> [a]
++String
" <- "String -> ShowS
forall a. [a] -> [a] -> [a]
++Polarity -> String
funName(ActionWithPolarity state a -> Polarity
forall state a. ActionWithPolarity state a -> Polarity
polarityActionWithPolarity state a
act)String -> ShowS
forall a. [a] -> [a] -> [a]
++String
" $ "String -> ShowS
forall a. [a] -> [a] -> [a]
++Action state a -> String
forall a. Show a => a -> String
show(ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
act)instanceShow(WithUsedVars(Stepstate))whereshow :: WithUsedVars (Step state) -> String
show(WithUsedVarsVarContext
ctx(Var a
var:=ActionWithPolarity state a
act))=ifVar a -> VarContext -> Bool
forall a. Typeable a => Var a -> VarContext -> Bool
isWellTypedVar a
varVarContext
ctxthenVar a -> String
forall a. Show a => a -> String
showVar a
varString -> ShowS
forall a. [a] -> [a] -> [a]
++String
" <- "String -> ShowS
forall a. [a] -> [a] -> [a]
++Polarity -> String
funName(ActionWithPolarity state a -> Polarity
forall state a. ActionWithPolarity state a -> Polarity
polarityActionWithPolarity state a
act)String -> ShowS
forall a. [a] -> [a] -> [a]
++String
" $ "String -> ShowS
forall a. [a] -> [a] -> [a]
++Action state a -> String
forall a. Show a => a -> String
show(ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
act)elsePolarity -> String
funName(ActionWithPolarity state a -> Polarity
forall state a. ActionWithPolarity state a -> Polarity
polarityActionWithPolarity state a
act)String -> ShowS
forall a. [a] -> [a] -> [a]
++String
" $ "String -> ShowS
forall a. [a] -> [a] -> [a]
++Action state a -> String
forall a. Show a => a -> String
show(ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
act)instanceEq(Stepstate)where(Var a
v:=ActionWithPolarity state a
act)== :: Step state -> Step state -> Bool
==(Var a
v':=ActionWithPolarity state a
act')=Var a -> Var a
forall a b. Var a -> Var b
unsafeCoerceVarVar a
vVar a -> Var a -> Bool
forall a. Eq a => a -> a -> Bool
==Var a
v'Bool -> Bool -> Bool
&&ActionWithPolarity state a -> Any (ActionWithPolarity state)
forall a (f :: * -> *). (Typeable a, Eq (f a)) => f a -> Any f
SomeActionWithPolarity state a
actAny (ActionWithPolarity state)
-> Any (ActionWithPolarity state) -> Bool
forall a. Eq a => a -> a -> Bool
==ActionWithPolarity state a -> Any (ActionWithPolarity state)
forall a (f :: * -> *). (Typeable a, Eq (f a)) => f a -> Any f
SomeActionWithPolarity state a
act'-- Action sequences use Smart shrinking, but this is invisible to-- client code because the extra Smart constructor is concealed by a-- pattern synonym.-- We also collect a list of names of actions which were generated,-- but were then rejected by their precondition.dataActionsstate=Actions_[String](Smart[Stepstate])deriving((forall x. Actions state -> Rep (Actions state) x)
-> (forall x. Rep (Actions state) x -> Actions state)
-> Generic (Actions state)
forall x. Rep (Actions state) x -> Actions state
forall x. Actions state -> Rep (Actions state) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall state x. Rep (Actions state) x -> Actions state
forall state x. Actions state -> Rep (Actions state) x
$cfrom :: forall state x. Actions state -> Rep (Actions state) x
from :: forall x. Actions state -> Rep (Actions state) x
$cto :: forall state x. Rep (Actions state) x -> Actions state
to :: forall x. Rep (Actions state) x -> Actions state
Generic)patternActions::[Stepstate]->Actionsstatepattern$mActions :: forall {r} {state}.
Actions state -> ([Step state] -> r) -> ((# #) -> r) -> r
$bActions :: forall state. [Step state] -> Actions state
Actionsas<-Actions__(Smart_as)whereActions[Step state]
as=[String] -> Smart [Step state] -> Actions state
forall state. [String] -> Smart [Step state] -> Actions state
Actions_[](Int -> [Step state] -> Smart [Step state]
forall a. Int -> a -> Smart a
SmartInt
0[Step state]
as){-# COMPLETEActions#-}instanceSemigroup(Actionsstate)whereActions_[String]
rs(SmartInt
k[Step state]
as)<> :: Actions state -> Actions state -> Actions state
<>Actions_[String]
rs'(SmartInt
_[Step state]
as')=[String] -> Smart [Step state] -> Actions state
forall state. [String] -> Smart [Step state] -> Actions state
Actions_([String]
rs[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++[String]
rs')(Int -> [Step state] -> Smart [Step state]
forall a. Int -> a -> Smart a
SmartInt
k([Step state]
as[Step state] -> [Step state] -> [Step state]
forall a. Semigroup a => a -> a -> a
<>[Step state]
as'))instanceEq(Actionsstate)whereActions[Step state]
as== :: Actions state -> Actions state -> Bool
==Actions[Step state]
as'=[Step state]
as[Step state] -> [Step state] -> Bool
forall a. Eq a => a -> a -> Bool
==[Step state]
as'instanceStateModelstate=>Show(Actionsstate)whereshow :: Actions state -> String
show(Actions[Step state]
as)=letas' :: [WithUsedVars (Step state)]
as'=VarContext -> Step state -> WithUsedVars (Step state)
forall a. VarContext -> a -> WithUsedVars a
WithUsedVars(Actions state -> VarContext
forall state. StateModel state => Actions state -> VarContext
usedVariables([Step state] -> Actions state
forall state. [Step state] -> Actions state
Actions[Step state]
as))(Step state -> WithUsedVars (Step state))
-> [Step state] -> [WithUsedVars (Step state)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>[Step state]
asinString -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalateString
"\n"([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$(String -> ShowS) -> [String] -> [String] -> [String]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWithString -> ShowS
forall a. [a] -> [a] -> [a]
(++)(String
"do "String -> [String] -> [String]
forall a. a -> [a] -> [a]
:String -> [String]
forall a. a -> [a]
repeatString
" ")((WithUsedVars (Step state) -> String)
-> [WithUsedVars (Step state)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
mapWithUsedVars (Step state) -> String
forall a. Show a => a -> String
show[WithUsedVars (Step state)]
as'[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++[String
"pure ()"])usedVariables::forallstate.StateModelstate=>Actionsstate->VarContextusedVariables :: forall state. StateModel state => Actions state -> VarContext
usedVariables(Actions[Step state]
as)=Annotated state -> [Step state] -> VarContext
goAnnotated state
forall state. StateModel state => Annotated state
initialAnnotatedState[Step state]
aswherego::Annotatedstate->[Stepstate]->VarContextgo :: Annotated state -> [Step state] -> VarContext
goAnnotated state
aState[]=state -> VarContext
forall a. HasVariables a => a -> VarContext
allVariables(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
aState)goAnnotated state
aState((Var a
var:=ActionWithPolarity state a
act):[Step state]
steps)=Action state a -> VarContext
forall a. HasVariables a => a -> VarContext
allVariables(ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
act)VarContext -> VarContext -> VarContext
forall a. Semigroup a => a -> a -> a
<>state -> VarContext
forall a. HasVariables a => a -> VarContext
allVariables(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
aState)VarContext -> VarContext -> VarContext
forall a. Semigroup a => a -> a -> a
<>Annotated state -> [Step state] -> VarContext
go(Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
forall state a.
(StateModel state, Typeable a) =>
Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
computeNextStateAnnotated state
aStateActionWithPolarity state a
actVar a
var)[Step state]
stepsinstanceforallstate.StateModelstate=>Arbitrary(Actionsstate)wherearbitrary :: Gen (Actions state)
arbitrary=Options state -> Gen (Actions state)
forall state.
StateModel state =>
Options state -> Gen (Actions state)
generateActionsWithOptionsOptions state
forall state. Options state
defaultOptionsshrink :: Actions state -> [Actions state]
shrink=Options state -> Actions state -> [Actions state]
forall state.
StateModel state =>
Options state -> Actions state -> [Actions state]
shrinkActionsWithOptionsOptions state
forall state. Options state
defaultOptionsdataQCDPropertystate=QCDProperty{forall state. QCDProperty state -> Actions state -> Property
runQCDProperty::Actionsstate->Property,forall state. QCDProperty state -> Options state
qcdPropertyOptions::Optionsstate}instanceStateModelstate=>Testable(QCDPropertystate)whereproperty :: QCDProperty state -> Property
propertyQCDProperty{Options state
Actions state -> Property
runQCDProperty :: forall state. QCDProperty state -> Actions state -> Property
qcdPropertyOptions :: forall state. QCDProperty state -> Options state
runQCDProperty :: Actions state -> Property
qcdPropertyOptions :: Options state
..}=Gen (Actions state)
-> (Actions state -> [Actions state])
-> (Actions state -> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink(Options state -> Gen (Actions state)
forall state.
StateModel state =>
Options state -> Gen (Actions state)
generateActionsWithOptionsOptions state
qcdPropertyOptions)(Options state -> Actions state -> [Actions state]
forall state.
StateModel state =>
Options state -> Actions state -> [Actions state]
shrinkActionsWithOptionsOptions state
qcdPropertyOptions)Actions state -> Property
runQCDPropertyclassQCDPropstatep|p->statewhereqcdProperty::p->QCDPropertystateinstanceQCDPropstate(QCDPropertystate)whereqcdProperty :: QCDProperty state -> QCDProperty state
qcdProperty=QCDProperty state -> QCDProperty state
forall a. a -> a
idinstanceTestablep=>QCDPropstate(Actionsstate->p)whereqcdProperty :: (Actions state -> p) -> QCDProperty state
qcdPropertyActions state -> p
p=(Actions state -> Property) -> Options state -> QCDProperty state
forall state.
(Actions state -> Property) -> Options state -> QCDProperty state
QCDProperty(p -> Property
forall prop. Testable prop => prop -> Property
property(p -> Property)
-> (Actions state -> p) -> Actions state -> Property
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Actions state -> p
p)Options state
forall state. Options state
defaultOptionsmodifyOptions::QCDPropertystate->(Optionsstate->Optionsstate)->QCDPropertystatemodifyOptions :: forall state.
QCDProperty state
-> (Options state -> Options state) -> QCDProperty state
modifyOptionsQCDProperty state
pOptions state -> Options state
f=letopts :: Options state
opts=QCDProperty state -> Options state
forall state. QCDProperty state -> Options state
qcdPropertyOptionsQCDProperty state
pinQCDProperty state
p{qcdPropertyOptions=fopts}moreActions::QCDPropstatep=>Rational->p->QCDPropertystatemoreActions :: forall state p.
QCDProp state p =>
Rational -> p -> QCDProperty state
moreActionsRational
rp
p=QCDProperty state
-> (Options state -> Options state) -> QCDProperty state
forall state.
QCDProperty state
-> (Options state -> Options state) -> QCDProperty state
modifyOptions(p -> QCDProperty state
forall state p. QCDProp state p => p -> QCDProperty state
qcdPropertyp
p)((Options state -> Options state) -> QCDProperty state)
-> (Options state -> Options state) -> QCDProperty state
forall a b. (a -> b) -> a -> b
$\Options state
opts->Options state
opts{actionLengthMultiplier=actionLengthMultiplieropts*r}-- NOTE: indexed on state for forwards compatibility, e.g. when we-- want to give an explicit initial statedataOptionsstate=Options{forall state. Options state -> Rational
actionLengthMultiplier::Rational}defaultOptions::OptionsstatedefaultOptions :: forall state. Options state
defaultOptions=Options{actionLengthMultiplier :: Rational
actionLengthMultiplier=Rational
1}-- | Generate arbitrary actions with the `GenActionsOptions`. More flexible than using the type-based-- modifiers.generateActionsWithOptions::forallstate.StateModelstate=>Optionsstate->Gen(Actionsstate)generateActionsWithOptions :: forall state.
StateModel state =>
Options state -> Gen (Actions state)
generateActionsWithOptionsOptions{Rational
actionLengthMultiplier :: forall state. Options state -> Rational
actionLengthMultiplier :: Rational
..}=do([Step state]
as,[String]
rejected)<-[Step state]
-> [String]
-> Annotated state
-> Int
-> Gen ([Step state], [String])
arbActions[][]Annotated state
forall state. StateModel state => Annotated state
initialAnnotatedStateInt
1Actions state -> Gen (Actions state)
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return(Actions state -> Gen (Actions state))
-> Actions state -> Gen (Actions state)
forall a b. (a -> b) -> a -> b
$[String] -> Smart [Step state] -> Actions state
forall state. [String] -> Smart [Step state] -> Actions state
Actions_[String]
rejected(Int -> [Step state] -> Smart [Step state]
forall a. Int -> a -> Smart a
SmartInt
0[Step state]
as)wherearbActions::[Stepstate]->[String]->Annotatedstate->Int->Gen([Stepstate],[String])arbActions :: [Step state]
-> [String]
-> Annotated state
-> Int
-> Gen ([Step state], [String])
arbActions[Step state]
steps[String]
rejectedAnnotated state
sInt
step=(Int -> Gen ([Step state], [String]))
-> Gen ([Step state], [String])
forall a. (Int -> Gen a) -> Gen a
sized((Int -> Gen ([Step state], [String]))
-> Gen ([Step state], [String]))
-> (Int -> Gen ([Step state], [String]))
-> Gen ([Step state], [String])
forall a b. (a -> b) -> a -> b
$\Int
n->doletw :: Int
w=Rational -> Int
forall b. Integral b => Rational -> b
forall a b. (RealFrac a, Integral b) => a -> b
round(Rational
actionLengthMultiplierRational -> Rational -> Rational
forall a. Num a => a -> a -> a
*Int -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegralInt
n)Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div`Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1Bool
continue<-[(Int, Gen Bool)] -> Gen Bool
forall a. [(Int, Gen a)] -> Gen a
frequency[(Int
1,Bool -> Gen Bool
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pureBool
False),(Int
w,Bool -> Gen Bool
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pureBool
True)]ifBool
continuethendo(Maybe (Any (ActionWithPolarity state))
mact,[String]
rej)<-Gen (Maybe (Any (ActionWithPolarity state)), [String])
satisfyPreconditioncaseMaybe (Any (ActionWithPolarity state))
mactofJust(Someact :: ActionWithPolarity state a
act@ActionWithPolarity{})->doletvar :: Var a
var=Int -> Var a
forall a. Int -> Var a
mkVarInt
step[Step state]
-> [String]
-> Annotated state
-> Int
-> Gen ([Step state], [String])
arbActions((Var a
varVar a -> ActionWithPolarity state a -> Step state
forall a state.
(Typeable a, Eq (Action state a), Show (Action state a)) =>
Var a -> ActionWithPolarity state a -> Step state
:=ActionWithPolarity state a
act)Step state -> [Step state] -> [Step state]
forall a. a -> [a] -> [a]
:[Step state]
steps)([String]
rej[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++[String]
rejected)(Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
forall state a.
(StateModel state, Typeable a) =>
Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
computeNextStateAnnotated state
sActionWithPolarity state a
actVar a
var)(Int
stepInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)Maybe (Any (ActionWithPolarity state))
Nothing->([Step state], [String]) -> Gen ([Step state], [String])
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return([Step state] -> [Step state]
forall a. [a] -> [a]
reverse[Step state]
steps,[String]
rejected)else([Step state], [String]) -> Gen ([Step state], [String])
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return([Step state] -> [Step state]
forall a. [a] -> [a]
reverse[Step state]
steps,[String]
rejected)wheresatisfyPrecondition :: Gen (Maybe (Any (ActionWithPolarity state)), [String])
satisfyPrecondition=(Int -> Gen (Maybe (Any (ActionWithPolarity state)), [String]))
-> Gen (Maybe (Any (ActionWithPolarity state)), [String])
forall a. (Int -> Gen a) -> Gen a
sized((Int -> Gen (Maybe (Any (ActionWithPolarity state)), [String]))
-> Gen (Maybe (Any (ActionWithPolarity state)), [String]))
-> (Int -> Gen (Maybe (Any (ActionWithPolarity state)), [String]))
-> Gen (Maybe (Any (ActionWithPolarity state)), [String])
forall a b. (a -> b) -> a -> b
$\Int
n->Int
-> Int
-> [String]
-> Gen (Maybe (Any (ActionWithPolarity state)), [String])
goInt
n(Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
n)[]-- idea copied from suchThatMaybego :: Int
-> Int
-> [String]
-> Gen (Maybe (Any (ActionWithPolarity state)), [String])
goInt
mInt
n[String]
rej|Int
mInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
n=(Maybe (Any (ActionWithPolarity state)), [String])
-> Gen (Maybe (Any (ActionWithPolarity state)), [String])
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return(Maybe (Any (ActionWithPolarity state))
forall a. Maybe a
Nothing,[String]
rej)|Bool
otherwise=doAny (ActionWithPolarity state)
a<-Int
-> Gen (Any (ActionWithPolarity state))
-> Gen (Any (ActionWithPolarity state))
forall a. Int -> Gen a -> Gen a
resizeInt
m(Gen (Any (ActionWithPolarity state))
-> Gen (Any (ActionWithPolarity state)))
-> Gen (Any (ActionWithPolarity state))
-> Gen (Any (ActionWithPolarity state))
forall a b. (a -> b) -> a -> b
$Annotated state -> Gen (Any (ActionWithPolarity state))
forall state.
StateModel state =>
Annotated state -> Gen (Any (ActionWithPolarity state))
computeArbitraryActionAnnotated state
scaseAny (ActionWithPolarity state)
aofSomeActionWithPolarity state a
act->ifAnnotated state -> ActionWithPolarity state a -> Bool
forall state a.
StateModel state =>
Annotated state -> ActionWithPolarity state a -> Bool
computePreconditionAnnotated state
sActionWithPolarity state a
actthen(Maybe (Any (ActionWithPolarity state)), [String])
-> Gen (Maybe (Any (ActionWithPolarity state)), [String])
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return(Any (ActionWithPolarity state)
-> Maybe (Any (ActionWithPolarity state))
forall a. a -> Maybe a
Just(ActionWithPolarity state a -> Any (ActionWithPolarity state)
forall a (f :: * -> *). (Typeable a, Eq (f a)) => f a -> Any f
SomeActionWithPolarity state a
act),[String]
rej)elseInt
-> Int
-> [String]
-> Gen (Maybe (Any (ActionWithPolarity state)), [String])
go(Int
mInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)Int
n(Action state a -> String
forall state a. StateModel state => Action state a -> String
forall a. Action state a -> String
actionName(ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
act)String -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
rej)shrinkActionsWithOptions::forallstate.StateModelstate=>Optionsstate->Actionsstate->[Actionsstate]shrinkActionsWithOptions :: forall state.
StateModel state =>
Options state -> Actions state -> [Actions state]
shrinkActionsWithOptionsOptions state
_(Actions_[String]
rsSmart [Step state]
as)=(Smart [Step state] -> Actions state)
-> [Smart [Step state]] -> [Actions state]
forall a b. (a -> b) -> [a] -> [b]
map([String] -> Smart [Step state] -> Actions state
forall state. [String] -> Smart [Step state] -> Actions state
Actions_[String]
rs)(([Step state] -> [[Step state]])
-> Smart [Step state] -> [Smart [Step state]]
forall a. (a -> [a]) -> Smart a -> [Smart a]
shrinkSmart(([(Step state, Annotated state)] -> [Step state])
-> [[(Step state, Annotated state)]] -> [[Step state]]
forall a b. (a -> b) -> [a] -> [b]
map([Step state] -> [Step state]
forall state. StateModel state => [Step state] -> [Step state]
prune([Step state] -> [Step state])
-> ([(Step state, Annotated state)] -> [Step state])
-> [(Step state, Annotated state)]
-> [Step state]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.((Step state, Annotated state) -> Step state)
-> [(Step state, Annotated state)] -> [Step state]
forall a b. (a -> b) -> [a] -> [b]
map(Step state, Annotated state) -> Step state
forall a b. (a, b) -> a
fst)([[(Step state, Annotated state)]] -> [[Step state]])
-> ([Step state] -> [[(Step state, Annotated state)]])
-> [Step state]
-> [[Step state]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([(Step state, Annotated state)]
-> [[(Step state, Annotated state)]])
-> [[(Step state, Annotated state)]]
-> [[(Step state, Annotated state)]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap[(Step state, Annotated state)]
-> [[(Step state, Annotated state)]]
customActionsShrinker([[(Step state, Annotated state)]]
-> [[(Step state, Annotated state)]])
-> ([Step state] -> [[(Step state, Annotated state)]])
-> [Step state]
-> [[(Step state, Annotated state)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.((Step state, Annotated state) -> [(Step state, Annotated state)])
-> [(Step state, Annotated state)]
-> [[(Step state, Annotated state)]]
forall a. (a -> [a]) -> [a] -> [[a]]
shrinkList(Step state, Annotated state) -> [(Step state, Annotated state)]
shrinker([(Step state, Annotated state)]
-> [[(Step state, Annotated state)]])
-> ([Step state] -> [(Step state, Annotated state)])
-> [Step state]
-> [[(Step state, Annotated state)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[Step state] -> [(Step state, Annotated state)]
forall state.
StateModel state =>
[Step state] -> [(Step state, Annotated state)]
withStates)Smart [Step state]
as)whereshrinker::(Stepstate,Annotatedstate)->[(Stepstate,Annotatedstate)]shrinker :: (Step state, Annotated state) -> [(Step state, Annotated state)]
shrinker(Var a
v:=ActionWithPolarity state a
act,Annotated state
s)=[(Var a -> Var a
forall a b. Var a -> Var b
unsafeCoerceVarVar a
vVar a -> ActionWithPolarity state a -> Step state
forall a state.
(Typeable a, Eq (Action state a), Show (Action state a)) =>
Var a -> ActionWithPolarity state a -> Step state
:=ActionWithPolarity state a
act',Annotated state
s)|Someact' :: ActionWithPolarity state a
act'@ActionWithPolarity{}<-Annotated state
-> ActionWithPolarity state a -> [Any (ActionWithPolarity state)]
forall state a.
(Typeable a, StateModel state) =>
Annotated state
-> ActionWithPolarity state a -> [Any (ActionWithPolarity state)]
computeShrinkActionAnnotated state
sActionWithPolarity state a
act]customActionsShrinker::[(Stepstate,Annotatedstate)]->[[(Stepstate,Annotatedstate)]]customActionsShrinker :: [(Step state, Annotated state)]
-> [[(Step state, Annotated state)]]
customActionsShrinker[(Step state, Annotated state)]
acts=letusedVars :: Set (Any Var)
usedVars=[Set (Any Var)] -> Set (Any Var)
forall a. Monoid a => [a] -> a
mconcat[ActionWithPolarity state a -> Set (Any Var)
forall a. HasVariables a => a -> Set (Any Var)
getAllVariablesActionWithPolarity state a
aSet (Any Var) -> Set (Any Var) -> Set (Any Var)
forall a. Semigroup a => a -> a -> a
<>state -> Set (Any Var)
forall a. HasVariables a => a -> Set (Any Var)
getAllVariables(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)|(Var a
_:=ActionWithPolarity state a
a,Annotated state
s)<-[(Step state, Annotated state)]
acts]binding :: (Step state, Annotated state) -> Bool
binding(Var a
v:=ActionWithPolarity state a
_,Annotated state
_)=Var a -> Any Var
forall a (f :: * -> *). (Typeable a, Eq (f a)) => f a -> Any f
SomeVar a
vAny Var -> Set (Any Var) -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member`Set (Any Var)
usedVars-- Remove at most one non-binding actiongo :: [(Step state, Annotated state)]
-> [[(Step state, Annotated state)]]
go[]=[[]]go((Step state, Annotated state)
p:[(Step state, Annotated state)]
ps)|(Step state, Annotated state) -> Bool
binding(Step state, Annotated state)
p=([(Step state, Annotated state)]
-> [(Step state, Annotated state)])
-> [[(Step state, Annotated state)]]
-> [[(Step state, Annotated state)]]
forall a b. (a -> b) -> [a] -> [b]
map((Step state, Annotated state)
p(Step state, Annotated state)
-> [(Step state, Annotated state)]
-> [(Step state, Annotated state)]
forall a. a -> [a] -> [a]
:)([(Step state, Annotated state)]
-> [[(Step state, Annotated state)]]
go[(Step state, Annotated state)]
ps)|Bool
otherwise=[(Step state, Annotated state)]
ps[(Step state, Annotated state)]
-> [[(Step state, Annotated state)]]
-> [[(Step state, Annotated state)]]
forall a. a -> [a] -> [a]
:([(Step state, Annotated state)]
-> [(Step state, Annotated state)])
-> [[(Step state, Annotated state)]]
-> [[(Step state, Annotated state)]]
forall a b. (a -> b) -> [a] -> [b]
map((Step state, Annotated state)
p(Step state, Annotated state)
-> [(Step state, Annotated state)]
-> [(Step state, Annotated state)]
forall a. a -> [a] -> [a]
:)([(Step state, Annotated state)]
-> [[(Step state, Annotated state)]]
go[(Step state, Annotated state)]
ps)in[(Step state, Annotated state)]
-> [[(Step state, Annotated state)]]
go[(Step state, Annotated state)]
acts-- Running state modelsdataAnnotatedstate=Metadata{forall state. Annotated state -> VarContext
vars::VarContext,forall state. Annotated state -> state
underlyingState::state}instanceShowstate=>Show(Annotatedstate)whereshow :: Annotated state -> String
show(MetadataVarContext
ctxstate
s)=VarContext -> String
forall a. Show a => a -> String
showVarContext
ctxString -> ShowS
forall a. [a] -> [a] -> [a]
++String
" |- "String -> ShowS
forall a. [a] -> [a] -> [a]
++state -> String
forall a. Show a => a -> String
showstate
sinitialAnnotatedState::StateModelstate=>AnnotatedstateinitialAnnotatedState :: forall state. StateModel state => Annotated state
initialAnnotatedState=VarContext -> state -> Annotated state
forall state. VarContext -> state -> Annotated state
MetadataVarContext
forall a. Monoid a => a
memptystate
forall state. StateModel state => state
initialStateactionWithPolarity::(StateModelstate,Eq(Actionstatea))=>Annotatedstate->Actionstatea->ActionWithPolaritystateaactionWithPolarity :: forall state a.
(StateModel state, Eq (Action state a)) =>
Annotated state -> Action state a -> ActionWithPolarity state a
actionWithPolarityAnnotated state
sAction state a
a=letp :: Polarity
p|state -> Action state a -> Bool
forall a. state -> Action state a -> Bool
forall state a. StateModel state => state -> Action state a -> Bool
precondition(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Action state a
a=Polarity
PosPolarity|state -> Action state a -> Bool
forall a. state -> Action state a -> Bool
forall state a. StateModel state => state -> Action state a -> Bool
validFailingAction(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Action state a
a=Polarity
NegPolarity|Bool
otherwise=Polarity
PosPolarityinAction state a -> Polarity -> ActionWithPolarity state a
forall state a.
Eq (Action state a) =>
Action state a -> Polarity -> ActionWithPolarity state a
ActionWithPolarityAction state a
aPolarity
pcomputePrecondition::StateModelstate=>Annotatedstate->ActionWithPolaritystatea->BoolcomputePrecondition :: forall state a.
StateModel state =>
Annotated state -> ActionWithPolarity state a -> Bool
computePreconditionAnnotated state
s(ActionWithPolarityAction state a
aPolarity
p)=letpolarPrecondition :: Bool
polarPrecondition|Polarity
pPolarity -> Polarity -> Bool
forall a. Eq a => a -> a -> Bool
==Polarity
PosPolarity=state -> Action state a -> Bool
forall a. state -> Action state a -> Bool
forall state a. StateModel state => state -> Action state a -> Bool
precondition(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Action state a
a|Bool
otherwise=state -> Action state a -> Bool
forall a. state -> Action state a -> Bool
forall state a. StateModel state => state -> Action state a -> Bool
validFailingAction(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Action state a
aBool -> Bool -> Bool
&&Bool -> Bool
not(state -> Action state a -> Bool
forall a. state -> Action state a -> Bool
forall state a. StateModel state => state -> Action state a -> Bool
precondition(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Action state a
a)in(Any Var -> Bool) -> Set (Any Var) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all(\(SomeVar a
v)->Var a
vVar a -> VarContext -> Bool
forall a. Typeable a => Var a -> VarContext -> Bool
`isWellTyped`Annotated state -> VarContext
forall state. Annotated state -> VarContext
varsAnnotated state
s)(Action state a -> Set (Any Var)
forall a. HasVariables a => a -> Set (Any Var)
getAllVariablesAction state a
a)Bool -> Bool -> Bool
&&Bool
polarPreconditioncomputeNextState::(StateModelstate,Typeablea)=>Annotatedstate->ActionWithPolaritystatea->Vara->AnnotatedstatecomputeNextState :: forall state a.
(StateModel state, Typeable a) =>
Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
computeNextStateAnnotated state
sActionWithPolarity state a
aVar a
v|ActionWithPolarity state a -> Polarity
forall state a. ActionWithPolarity state a -> Polarity
polarityActionWithPolarity state a
aPolarity -> Polarity -> Bool
forall a. Eq a => a -> a -> Bool
==Polarity
PosPolarity=VarContext -> state -> Annotated state
forall state. VarContext -> state -> Annotated state
Metadata(VarContext -> Var a -> VarContext
forall a. Typeable a => VarContext -> Var a -> VarContext
extendContext(Annotated state -> VarContext
forall state. Annotated state -> VarContext
varsAnnotated state
s)Var a
v)(state -> Action state a -> Var a -> state
forall a. Typeable a => state -> Action state a -> Var a -> state
forall state a.
(StateModel state, Typeable a) =>
state -> Action state a -> Var a -> state
nextState(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)(ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
a)Var a
v)|Bool
otherwise=VarContext -> state -> Annotated state
forall state. VarContext -> state -> Annotated state
Metadata(Annotated state -> VarContext
forall state. Annotated state -> VarContext
varsAnnotated state
s)(state -> Action state a -> state
forall a. Typeable a => state -> Action state a -> state
forall state a.
(StateModel state, Typeable a) =>
state -> Action state a -> state
failureNextState(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)(ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
a))computeArbitraryAction::StateModelstate=>Annotatedstate->Gen(Any(ActionWithPolaritystate))computeArbitraryAction :: forall state.
StateModel state =>
Annotated state -> Gen (Any (ActionWithPolarity state))
computeArbitraryActionAnnotated state
s=doSomeAction state a
a<-VarContext -> state -> Gen (Any (Action state))
forall state.
StateModel state =>
VarContext -> state -> Gen (Any (Action state))
arbitraryAction(Annotated state -> VarContext
forall state. Annotated state -> VarContext
varsAnnotated state
s)(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Any (ActionWithPolarity state)
-> Gen (Any (ActionWithPolarity state))
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Any (ActionWithPolarity state)
-> Gen (Any (ActionWithPolarity state)))
-> Any (ActionWithPolarity state)
-> Gen (Any (ActionWithPolarity state))
forall a b. (a -> b) -> a -> b
$ActionWithPolarity state a -> Any (ActionWithPolarity state)
forall a (f :: * -> *). (Typeable a, Eq (f a)) => f a -> Any f
Some(ActionWithPolarity state a -> Any (ActionWithPolarity state))
-> ActionWithPolarity state a -> Any (ActionWithPolarity state)
forall a b. (a -> b) -> a -> b
$Annotated state -> Action state a -> ActionWithPolarity state a
forall state a.
(StateModel state, Eq (Action state a)) =>
Annotated state -> Action state a -> ActionWithPolarity state a
actionWithPolarityAnnotated state
sAction state a
acomputeShrinkAction::forallstatea.(Typeablea,StateModelstate)=>Annotatedstate->ActionWithPolaritystatea->[Any(ActionWithPolaritystate)]computeShrinkAction :: forall state a.
(Typeable a, StateModel state) =>
Annotated state
-> ActionWithPolarity state a -> [Any (ActionWithPolarity state)]
computeShrinkActionAnnotated state
s(ActionWithPolarityAction state a
aPolarity
_)=[ActionWithPolarity state a -> Any (ActionWithPolarity state)
forall a (f :: * -> *). (Typeable a, Eq (f a)) => f a -> Any f
Some(Annotated state -> Action state a -> ActionWithPolarity state a
forall state a.
(StateModel state, Eq (Action state a)) =>
Annotated state -> Action state a -> ActionWithPolarity state a
actionWithPolarityAnnotated state
sAction state a
a')|SomeAction state a
a'<-VarContext -> state -> Action state a -> [Any (Action state)]
forall a.
Typeable a =>
VarContext -> state -> Action state a -> [Any (Action state)]
forall state a.
(StateModel state, Typeable a) =>
VarContext -> state -> Action state a -> [Any (Action state)]
shrinkAction(Annotated state -> VarContext
forall state. Annotated state -> VarContext
varsAnnotated state
s)(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Action state a
a]prune::forallstate.StateModelstate=>[Stepstate]->[Stepstate]prune :: forall state. StateModel state => [Step state] -> [Step state]
prune=Annotated state -> [Step state] -> [Step state]
loopAnnotated state
forall state. StateModel state => Annotated state
initialAnnotatedStatewhereloop :: Annotated state -> [Step state] -> [Step state]
loopAnnotated state
_s[]=[]loopAnnotated state
s((Var a
var:=ActionWithPolarity state a
act):[Step state]
as)|forall state a.
StateModel state =>
Annotated state -> ActionWithPolarity state a -> Bool
computePrecondition@stateAnnotated state
sActionWithPolarity state a
act=(Var a
varVar a -> ActionWithPolarity state a -> Step state
forall a state.
(Typeable a, Eq (Action state a), Show (Action state a)) =>
Var a -> ActionWithPolarity state a -> Step state
:=ActionWithPolarity state a
act)Step state -> [Step state] -> [Step state]
forall a. a -> [a] -> [a]
:Annotated state -> [Step state] -> [Step state]
loop(Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
forall state a.
(StateModel state, Typeable a) =>
Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
computeNextStateAnnotated state
sActionWithPolarity state a
actVar a
var)[Step state]
as|Bool
otherwise=Annotated state -> [Step state] -> [Step state]
loopAnnotated state
s[Step state]
aswithStates::forallstate.StateModelstate=>[Stepstate]->[(Stepstate,Annotatedstate)]withStates :: forall state.
StateModel state =>
[Step state] -> [(Step state, Annotated state)]
withStates=Annotated state -> [Step state] -> [(Step state, Annotated state)]
loopAnnotated state
forall state. StateModel state => Annotated state
initialAnnotatedStatewhereloop :: Annotated state -> [Step state] -> [(Step state, Annotated state)]
loopAnnotated state
_s[]=[]loopAnnotated state
s((Var a
var:=ActionWithPolarity state a
act):[Step state]
as)=(Var a
varVar a -> ActionWithPolarity state a -> Step state
forall a state.
(Typeable a, Eq (Action state a), Show (Action state a)) =>
Var a -> ActionWithPolarity state a -> Step state
:=ActionWithPolarity state a
act,Annotated state
s)(Step state, Annotated state)
-> [(Step state, Annotated state)]
-> [(Step state, Annotated state)]
forall a. a -> [a] -> [a]
:Annotated state -> [Step state] -> [(Step state, Annotated state)]
loop(forall state a.
(StateModel state, Typeable a) =>
Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
computeNextState@stateAnnotated state
sActionWithPolarity state a
actVar a
var)[Step state]
asstateAfter::forallstate.StateModelstate=>Actionsstate->AnnotatedstatestateAfter :: forall state. StateModel state => Actions state -> Annotated state
stateAfter(Actions[Step state]
actions)=Annotated state -> [Step state] -> Annotated state
loopAnnotated state
forall state. StateModel state => Annotated state
initialAnnotatedState[Step state]
actionswhereloop :: Annotated state -> [Step state] -> Annotated state
loopAnnotated state
s[]=Annotated state
sloopAnnotated state
s((Var a
var:=ActionWithPolarity state a
act):[Step state]
as)=Annotated state -> [Step state] -> Annotated state
loop(forall state a.
(StateModel state, Typeable a) =>
Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
computeNextState@stateAnnotated state
sActionWithPolarity state a
actVar a
var)[Step state]
asrunActions::forallstateme.(StateModelstate,RunModelstatem,e~Errorstatem,foralla.IsPerformResultea)=>Actionsstate->PropertyMm(Annotatedstate,Env)runActions :: forall state (m :: * -> *) e.
(StateModel state, RunModel state m, e ~ Error state m,
forall a. IsPerformResult e a) =>
Actions state -> PropertyM m (Annotated state, Env)
runActions(Actions_[String]
rejected(SmartInt
_[Step state]
actions))=doletbucket :: Int -> String
bucket=\Int
n->let(Int
a,Int
b)=Int -> (Int, Int)
forall {t}. Integral t => t -> (t, t)
goInt
ninInt -> String
forall a. Show a => a -> String
showInt
aString -> ShowS
forall a. [a] -> [a] -> [a]
++String
" - "String -> ShowS
forall a. [a] -> [a] -> [a]
++Int -> String
forall a. Show a => a -> String
showInt
bwherego :: t -> (t, t)
got
n|t
nt -> t -> Bool
forall a. Ord a => a -> a -> Bool
<t
100=(t
dt -> t -> t
forall a. Num a => a -> a -> a
*t
10,t
dt -> t -> t
forall a. Num a => a -> a -> a
*t
10t -> t -> t
forall a. Num a => a -> a -> a
+t
9)|Bool
otherwise=let(t
a,t
b)=t -> (t, t)
got
din(t
at -> t -> t
forall a. Num a => a -> a -> a
*t
10,t
bt -> t -> t
forall a. Num a => a -> a -> a
*t
10t -> t -> t
forall a. Num a => a -> a -> a
+t
9)whered :: t
d=t -> t -> t
forall a. Integral a => a -> a -> a
divt
nt
10(Property -> Property) -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PropertyM m ()
monitor((Property -> Property) -> PropertyM m ())
-> (Property -> Property) -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulateString
"# of actions"[ShowS
forall a. Show a => a -> String
showShowS -> ShowS
forall a b. (a -> b) -> a -> b
$Int -> String
bucket(Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$[Step state] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length[Step state]
actions](Annotated state
finalState,Env
env,[String]
names,[Polarity]
polars)<-Annotated state
-> Env
-> [Step state]
-> PropertyM m (Annotated state, Env, [String], [Polarity])
forall state (m :: * -> *) e.
(StateModel state, RunModel state m, e ~ Error state m,
forall a. IsPerformResult e a) =>
Annotated state
-> Env
-> [Step state]
-> PropertyM m (Annotated state, Env, [String], [Polarity])
runStepsAnnotated state
forall state. StateModel state => Annotated state
initialAnnotatedState[][Step state]
actions(Property -> Property) -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PropertyM m ()
monitor((Property -> Property) -> PropertyM m ())
-> (Property -> Property) -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulateString
"Actions"[String]
names(Property -> Property) -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PropertyM m ()
monitor((Property -> Property) -> PropertyM m ())
-> (Property -> Property) -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulateString
"Action polarity"([String] -> Property -> Property)
-> [String] -> Property -> Property
forall a b. (a -> b) -> a -> b
$(Polarity -> String) -> [Polarity] -> [String]
forall a b. (a -> b) -> [a] -> [b]
mapPolarity -> String
forall a. Show a => a -> String
show[Polarity]
polarsBool -> PropertyM m () -> PropertyM m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null[String]
rejected)(PropertyM m () -> PropertyM m ())
-> PropertyM m () -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$(Property -> Property) -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PropertyM m ()
monitor((Property -> Property) -> PropertyM m ())
-> (Property -> Property) -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulateString
"Actions rejected by precondition"[String]
rejected(Annotated state, Env) -> PropertyM m (Annotated state, Env)
forall a. a -> PropertyM m a
forall (m :: * -> *) a. Monad m => a -> m a
return(Annotated state
finalState,Env
env)-- | Core function to execute a sequence of `Step` given some initial `Env`ironment and `Annotated`-- state. Return the list of action names and polarities to work around-- https://github.com/nick8325/quickcheck/issues/416 causing repeated calls to tabulate being slow.runSteps::forallstateme.(StateModelstate,RunModelstatem,e~Errorstatem,foralla.IsPerformResultea)=>Annotatedstate->Env->[Stepstate]->PropertyMm(Annotatedstate,Env,[String],[Polarity])runSteps :: forall state (m :: * -> *) e.
(StateModel state, RunModel state m, e ~ Error state m,
forall a. IsPerformResult e a) =>
Annotated state
-> Env
-> [Step state]
-> PropertyM m (Annotated state, Env, [String], [Polarity])
runStepsAnnotated state
sEnv
env[]=(Annotated state, Env, [String], [Polarity])
-> PropertyM m (Annotated state, Env, [String], [Polarity])
forall a. a -> PropertyM m a
forall (m :: * -> *) a. Monad m => a -> m a
return(Annotated state
s,Env -> Env
forall a. [a] -> [a]
reverseEnv
env,[],[])runStepsAnnotated state
sEnv
env((Var a
v:=ActionWithPolarity state a
act):[Step state]
as)=doBool -> PropertyM m ()
forall (m :: * -> *). Monad m => Bool -> PropertyM m ()
pre(Bool -> PropertyM m ()) -> Bool -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$Annotated state -> ActionWithPolarity state a -> Bool
forall state a.
StateModel state =>
Annotated state -> ActionWithPolarity state a -> Bool
computePreconditionAnnotated state
sActionWithPolarity state a
actEither e a
ret<-m (Either e a) -> PropertyM m (Either e a)
forall (m :: * -> *) a. Monad m => m a -> PropertyM m a
run(m (Either e a) -> PropertyM m (Either e a))
-> m (Either e a) -> PropertyM m (Either e a)
forall a b. (a -> b) -> a -> b
$EitherIsh e a -> Either e a
forall e a. IsPerformResult e a => EitherIsh e a -> Either e a
performResultToEither(EitherIsh e a -> Either e a)
-> m (EitherIsh e a) -> m (Either e a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>state -> Action state a -> LookUp -> m (PerformResult state m a)
forall a.
Typeable a =>
state -> Action state a -> LookUp -> m (PerformResult state m a)
forall state (m :: * -> *) a.
(RunModel state m, Typeable a) =>
state -> Action state a -> LookUp -> m (PerformResult state m a)
perform(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Action state a
action(Env -> Var a -> a
forall a. Typeable a => Env -> Var a -> a
lookUpVarEnv
env)letname :: String
name=Polarity -> String
forall a. Show a => a -> String
showPolarity
polarString -> ShowS
forall a. [a] -> [a] -> [a]
++Action state a -> String
forall state a. StateModel state => Action state a -> String
forall a. Action state a -> String
actionNameAction state a
actioncase(Polarity
polar,Either e a
ret)of(Polarity
PosPolarity,Lefte
err)->e -> PropertyM m (Annotated state, Env, [String], [Polarity])
positiveActionFailede
err(Polarity
PosPolarity,Righta
val)->do(Annotated state
s',Env
env')<-Either e a -> a -> PropertyM m (Annotated state, Env)
positiveActionSucceededEither e a
reta
val(Annotated state
s'',Env
env'',[String]
names,[Polarity]
polars)<-Annotated state
-> Env
-> [Step state]
-> PropertyM m (Annotated state, Env, [String], [Polarity])
forall state (m :: * -> *) e.
(StateModel state, RunModel state m, e ~ Error state m,
forall a. IsPerformResult e a) =>
Annotated state
-> Env
-> [Step state]
-> PropertyM m (Annotated state, Env, [String], [Polarity])
runStepsAnnotated state
s'Env
env'[Step state]
as(Annotated state, Env, [String], [Polarity])
-> PropertyM m (Annotated state, Env, [String], [Polarity])
forall a. a -> PropertyM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Annotated state
s'',Env
env'',String
nameString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
names,Polarity
polarPolarity -> [Polarity] -> [Polarity]
forall a. a -> [a] -> [a]
:[Polarity]
polars)(Polarity
NegPolarity,Either e a
_)->do(Annotated state
s',Env
env')<-Either e a -> PropertyM m (Annotated state, Env)
negativeActionResultEither e a
ret(Annotated state
s'',Env
env'',[String]
names,[Polarity]
polars)<-Annotated state
-> Env
-> [Step state]
-> PropertyM m (Annotated state, Env, [String], [Polarity])
forall state (m :: * -> *) e.
(StateModel state, RunModel state m, e ~ Error state m,
forall a. IsPerformResult e a) =>
Annotated state
-> Env
-> [Step state]
-> PropertyM m (Annotated state, Env, [String], [Polarity])
runStepsAnnotated state
s'Env
env'[Step state]
as(Annotated state, Env, [String], [Polarity])
-> PropertyM m (Annotated state, Env, [String], [Polarity])
forall a. a -> PropertyM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Annotated state
s'',Env
env'',String
nameString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
names,Polarity
polarPolarity -> [Polarity] -> [Polarity]
forall a. a -> [a] -> [a]
:[Polarity]
polars)wherepolar :: Polarity
polar=ActionWithPolarity state a -> Polarity
forall state a. ActionWithPolarity state a -> Polarity
polarityActionWithPolarity state a
actaction :: Action state a
action=ActionWithPolarity state a -> Action state a
forall state a. ActionWithPolarity state a -> Action state a
polarActionActionWithPolarity state a
actpositiveActionFailed :: e -> PropertyM m (Annotated state, Env, [String], [Polarity])
positiveActionFailede
err=do(Property -> Property) -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PropertyM m ()
monitor((Property -> Property) -> PropertyM m ())
-> (Property -> Property) -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$forall state (m :: * -> *) a.
RunModel state m =>
state
-> Action state a
-> LookUp
-> Error state m
-> Property
-> Property
monitoringFailure@state@m(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s)Action state a
action(Env -> Var a -> a
forall a. Typeable a => Env -> Var a -> a
lookUpVarEnv
env)e
Error state m
errBool -> PropertyM m (Annotated state, Env, [String], [Polarity])
forall prop (m :: * -> *) a.
(Testable prop, Monad m) =>
prop -> PropertyM m a
stopBool
FalsepositiveActionSucceeded :: Either e a -> a -> PropertyM m (Annotated state, Env)
positiveActionSucceededEither e a
reta
val=do(Annotated state
s',Env
env',(state, state)
stateTransition)<-Either e a -> PropertyM m (Annotated state, Env, (state, state))
computeNewStateEither e a
retPostconditionM m Bool -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
PostconditionM m Bool -> PropertyM m ()
evaluatePostCondition(PostconditionM m Bool -> PropertyM m ())
-> PostconditionM m Bool -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$(state, state)
-> Action state a -> LookUp -> a -> PostconditionM m Bool
forall a.
(state, state)
-> Action state a -> LookUp -> a -> PostconditionM m Bool
forall state (m :: * -> *) a.
RunModel state m =>
(state, state)
-> Action state a -> LookUp -> a -> PostconditionM m Bool
postcondition(state, state)
stateTransitionAction state a
action(Env -> Var a -> a
forall a. Typeable a => Env -> Var a -> a
lookUpVarEnv
env)a
val(Annotated state, Env) -> PropertyM m (Annotated state, Env)
forall a. a -> PropertyM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Annotated state
s',Env
env')negativeActionResult :: Either e a -> PropertyM m (Annotated state, Env)
negativeActionResultEither e a
ret=do(Annotated state
s',Env
env',(state, state)
stateTransition)<-Either e a -> PropertyM m (Annotated state, Env, (state, state))
computeNewStateEither e a
retPostconditionM m Bool -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
PostconditionM m Bool -> PropertyM m ()
evaluatePostCondition(PostconditionM m Bool -> PropertyM m ())
-> PostconditionM m Bool -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$(state, state)
-> Action state a
-> LookUp
-> Either (Error state m) a
-> PostconditionM m Bool
forall a.
(state, state)
-> Action state a
-> LookUp
-> Either (Error state m) a
-> PostconditionM m Bool
forall state (m :: * -> *) a.
RunModel state m =>
(state, state)
-> Action state a
-> LookUp
-> Either (Error state m) a
-> PostconditionM m Bool
postconditionOnFailure(state, state)
stateTransitionAction state a
action(Env -> Var a -> a
forall a. Typeable a => Env -> Var a -> a
lookUpVarEnv
env)Either e a
Either (Error state m) a
ret(Annotated state, Env) -> PropertyM m (Annotated state, Env)
forall a. a -> PropertyM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Annotated state
s',Env
env')computeNewState :: Either e a -> PropertyM m (Annotated state, Env, (state, state))
computeNewStateEither e a
ret=doletvar :: Var a
var=Var a -> Var a
forall a b. Var a -> Var b
unsafeCoerceVarVar a
vs' :: Annotated state
s'=Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
forall state a.
(StateModel state, Typeable a) =>
Annotated state
-> ActionWithPolarity state a -> Var a -> Annotated state
computeNextStateAnnotated state
sActionWithPolarity state a
actVar a
varenv' :: Env
env'|Righta
val<-Either e a
ret=(Var a
varVar a -> a -> EnvEntry
forall a. Typeable a => Var a -> a -> EnvEntry
:==a
val)EnvEntry -> Env -> Env
forall a. a -> [a] -> [a]
:Env
env|Bool
otherwise=Env
envstateTransition :: (state, state)
stateTransition=(Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s,Annotated state -> state
forall state. Annotated state -> state
underlyingStateAnnotated state
s')(Property -> Property) -> PropertyM m ()
forall (m :: * -> *).
Monad m =>
(Property -> Property) -> PropertyM m ()
monitor((Property -> Property) -> PropertyM m ())
-> (Property -> Property) -> PropertyM m ()
forall a b. (a -> b) -> a -> b
$forall state (m :: * -> *) a.
RunModel state m =>
(state, state)
-> Action state a
-> LookUp
-> Either (Error state m) a
-> Property
-> Property
monitoring@state@m(state, state)
stateTransitionAction state a
action(Env -> Var a -> a
forall a. Typeable a => Env -> Var a -> a
lookUpVarEnv
env')Either e a
Either (Error state m) a
ret(Annotated state, Env, (state, state))
-> PropertyM m (Annotated state, Env, (state, state))
forall a. a -> PropertyM m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Annotated state
s',Env
env',(state, state)
stateTransition)