{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Test.Control.State.Transition.Trace.Generator.QuickCheck (
  HasTrace (BaseEnv, envGen, sigGen, shrinkSignal, interpretSTS),
  traceFrom,
  traceFromInitState,
  trace,
  shrinkTrace,
  
  forAllTrace,
  forAllTraceFromInitState,
  onlyValidSignalsAreGenerated,
  onlyValidSignalsAreGeneratedFromInitState,
  
  traceLengthsAreClassified,
  classifyTraceLength,
  classifySize,
  
  mkIntervals,
) where
import Control.State.Transition (Environment, IRC (IRC), STS, Signal, State, TRC (TRC))
import qualified Control.State.Transition.Extended as STS
import Data.Functor.Identity (Identity (..))
import Data.Kind (Type)
import Data.List.NonEmpty (NonEmpty)
import Data.Maybe (fromMaybe)
import Data.Word (Word64)
import GHC.Stack
import Test.Control.State.Transition.Trace (Trace)
import qualified Test.Control.State.Transition.Trace as Trace
import qualified Test.QuickCheck as QuickCheck
class STS sts => HasTrace sts traceGenEnv where
  type BaseEnv sts :: Type
  type BaseEnv s = ()
  
  
  
  interpretSTS :: forall a. HasCallStack => (BaseEnv sts -> STS.BaseM sts a -> a)
  default interpretSTS :: STS.BaseM sts ~ Identity => forall a. BaseEnv sts -> STS.BaseM sts a -> a
  interpretSTS BaseEnv sts
_ (Identity a
x) = a
x
  envGen :: HasCallStack => traceGenEnv -> QuickCheck.Gen (Environment sts)
  sigGen ::
    HasCallStack =>
    traceGenEnv ->
    Environment sts ->
    State sts ->
    QuickCheck.Gen (Signal sts)
  shrinkSignal :: HasCallStack => Signal sts -> [Signal sts]
traceFrom ::
  forall sts traceGenEnv.
  HasTrace sts traceGenEnv =>
  BaseEnv sts ->
  
  Word64 ->
  traceGenEnv ->
  Environment sts ->
  State sts ->
  QuickCheck.Gen (Trace sts)
traceFrom :: forall sts traceGenEnv.
HasTrace sts traceGenEnv =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Environment sts
-> State sts
-> Gen (Trace sts)
traceFrom BaseEnv sts
traceEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Environment sts
env State sts
st0 = do
  Word64
chosenTraceLength <- (Word64, Word64) -> Gen Word64
forall a. Random a => (a, a) -> Gen a
QuickCheck.choose (Word64
0, Word64
maxTraceLength)
  Environment sts
-> State sts -> [(State sts, Signal sts)] -> Trace sts
forall s.
Environment s -> State s -> [(State s, Signal s)] -> Trace s
Trace.mkTrace Environment sts
env State sts
st0 ([(State sts, Signal sts)] -> Trace sts)
-> Gen [(State sts, Signal sts)] -> Gen (Trace sts)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word64
-> State sts
-> [(State sts, Signal sts)]
-> Gen [(State sts, Signal sts)]
loop Word64
chosenTraceLength State sts
st0 []
  where
    loop ::
      Word64 ->
      State sts ->
      [(State sts, Signal sts)] ->
      QuickCheck.Gen [(State sts, Signal sts)]
    loop :: Word64
-> State sts
-> [(State sts, Signal sts)]
-> Gen [(State sts, Signal sts)]
loop Word64
0 State sts
_ ![(State sts, Signal sts)]
acc = [(State sts, Signal sts)] -> Gen [(State sts, Signal sts)]
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(State sts, Signal sts)]
acc
    loop Word64
d !State sts
sti ![(State sts, Signal sts)]
stSigs = do
      Signal sts
sig <- forall sts traceGenEnv.
(HasTrace sts traceGenEnv, HasCallStack) =>
traceGenEnv -> Environment sts -> State sts -> Gen (Signal sts)
sigGen @sts @traceGenEnv traceGenEnv
traceGenEnv Environment sts
env State sts
sti
      case forall sts traceGenEnv a.
(HasTrace sts traceGenEnv, HasCallStack) =>
BaseEnv sts -> BaseM sts a -> a
interpretSTS @sts @traceGenEnv BaseEnv sts
traceEnv (forall s (m :: * -> *) (rtype :: RuleType).
(STS s, RuleTypeRep rtype, m ~ BaseM s) =>
RuleContext rtype s
-> m (Either (NonEmpty (PredicateFailure s)) (State s))
Trace.applySTSTest @sts ((Environment sts, State sts, Signal sts) -> TRC sts
forall sts. (Environment sts, State sts, Signal sts) -> TRC sts
TRC (Environment sts
env, State sts
sti, Signal sts
sig))) of
        Left NonEmpty (PredicateFailure sts)
_predicateFailures ->
          Word64
-> State sts
-> [(State sts, Signal sts)]
-> Gen [(State sts, Signal sts)]
loop (Word64
d Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1) State sts
sti [(State sts, Signal sts)]
stSigs
        Right State sts
sti' ->
          Word64
-> State sts
-> [(State sts, Signal sts)]
-> Gen [(State sts, Signal sts)]
loop (Word64
d Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1) State sts
sti' ((State sts
sti', Signal sts
sig) (State sts, Signal sts)
-> [(State sts, Signal sts)] -> [(State sts, Signal sts)]
forall a. a -> [a] -> [a]
: [(State sts, Signal sts)]
stSigs)
trace ::
  forall sts traceGenEnv.
  ( HasTrace sts traceGenEnv
  , Show (Environment sts)
  ) =>
  BaseEnv sts ->
  
  Word64 ->
  traceGenEnv ->
  QuickCheck.Gen (Trace sts)
trace :: forall sts traceGenEnv.
(HasTrace sts traceGenEnv, Show (Environment sts)) =>
BaseEnv sts -> Word64 -> traceGenEnv -> Gen (Trace sts)
trace BaseEnv sts
traceEnv Word64
maxTraceLength traceGenEnv
traceGenEnv =
  BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> Gen (Trace sts)
forall sts traceGenEnv.
(HasTrace sts traceGenEnv, Show (Environment sts), HasCallStack) =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> Gen (Trace sts)
traceFromInitState BaseEnv sts
traceEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
forall a. Maybe a
Nothing
traceFromInitState ::
  forall sts traceGenEnv.
  ( HasTrace sts traceGenEnv
  , Show (Environment sts)
  , HasCallStack
  ) =>
  BaseEnv sts ->
  
  Word64 ->
  traceGenEnv ->
  
  Maybe (IRC sts -> QuickCheck.Gen (Either (NonEmpty (STS.PredicateFailure sts)) (State sts))) ->
  QuickCheck.Gen (Trace sts)
traceFromInitState :: forall sts traceGenEnv.
(HasTrace sts traceGenEnv, Show (Environment sts), HasCallStack) =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> Gen (Trace sts)
traceFromInitState BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
genSt0 = do
  Environment sts
env <- forall sts traceGenEnv.
(HasTrace sts traceGenEnv, HasCallStack) =>
traceGenEnv -> Gen (Environment sts)
envGen @sts @traceGenEnv traceGenEnv
traceGenEnv
  Either (NonEmpty (PredicateFailure sts)) (State sts)
res <-
    (IRC sts
 -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> IRC sts
-> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts))
forall a. a -> Maybe a -> a
fromMaybe
      ( Either (NonEmpty (PredicateFailure sts)) (State sts)
-> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts))
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
          (Either (NonEmpty (PredicateFailure sts)) (State sts)
 -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> (IRC sts
    -> Either (NonEmpty (PredicateFailure sts)) (State sts))
-> IRC sts
-> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall sts traceGenEnv a.
(HasTrace sts traceGenEnv, HasCallStack) =>
BaseEnv sts -> BaseM sts a -> a
interpretSTS @sts @traceGenEnv BaseEnv sts
baseEnv
          (BaseM sts (Either (NonEmpty (PredicateFailure sts)) (State sts))
 -> Either (NonEmpty (PredicateFailure sts)) (State sts))
-> (IRC sts
    -> BaseM
         sts (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> IRC sts
-> Either (NonEmpty (PredicateFailure sts)) (State sts)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RuleContext 'Initial sts
-> BaseM sts (Either (NonEmpty (PredicateFailure sts)) (State sts))
IRC sts
-> BaseM sts (Either (NonEmpty (PredicateFailure sts)) (State sts))
forall s (m :: * -> *) (rtype :: RuleType).
(STS s, RuleTypeRep rtype, m ~ BaseM s) =>
RuleContext rtype s
-> m (Either (NonEmpty (PredicateFailure s)) (State s))
Trace.applySTSTest
      )
      Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
genSt0
      (IRC sts
 -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> IRC sts
-> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts))
forall a b. (a -> b) -> a -> b
$ Environment sts -> IRC sts
forall sts. Environment sts -> IRC sts
IRC Environment sts
env
  case Either (NonEmpty (PredicateFailure sts)) (State sts)
res of
    Left NonEmpty (PredicateFailure sts)
pf ->
      [Char] -> Gen (Trace sts)
forall a. HasCallStack => [Char] -> a
error ([Char] -> Gen (Trace sts)) -> [Char] -> Gen (Trace sts)
forall a b. (a -> b) -> a -> b
$
        [Char]
"Failed to apply the initial rule to the generated environment.\n"
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Generated environment: "
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Environment sts -> [Char]
forall a. Show a => a -> [Char]
show Environment sts
env
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Failure: "
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ NonEmpty (PredicateFailure sts) -> [Char]
forall a. Show a => a -> [Char]
show NonEmpty (PredicateFailure sts)
pf
    Right State sts
st0 -> BaseEnv sts
-> Word64
-> traceGenEnv
-> Environment sts
-> State sts
-> Gen (Trace sts)
forall sts traceGenEnv.
HasTrace sts traceGenEnv =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Environment sts
-> State sts
-> Gen (Trace sts)
traceFrom BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Environment sts
env State sts
st0
forAllTraceFromInitState ::
  forall sts traceGenEnv prop.
  ( HasTrace sts traceGenEnv
  , QuickCheck.Testable prop
  , Show (Environment sts)
  ) =>
  BaseEnv sts ->
  
  Word64 ->
  traceGenEnv ->
  
  Maybe (IRC sts -> QuickCheck.Gen (Either (NonEmpty (STS.PredicateFailure sts)) (State sts))) ->
  (Trace sts -> prop) ->
  QuickCheck.Property
forAllTraceFromInitState :: forall sts traceGenEnv prop.
(HasTrace sts traceGenEnv, Testable prop,
 Show (Environment sts)) =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> (Trace sts -> prop)
-> Property
forAllTraceFromInitState BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
genSt0 Trace sts -> prop
prop =
  Gen (Trace sts)
-> (Trace sts -> [Trace sts]) -> (Trace sts -> prop) -> Property
forall prop a.
Testable prop =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
QuickCheck.forAllShrinkBlind
    (forall sts traceGenEnv.
(HasTrace sts traceGenEnv, Show (Environment sts), HasCallStack) =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> Gen (Trace sts)
traceFromInitState @sts @traceGenEnv BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
genSt0)
    (forall sts traceGenEnv.
HasTrace sts traceGenEnv =>
BaseEnv sts -> Trace sts -> [Trace sts]
shrinkTrace @sts @traceGenEnv BaseEnv sts
baseEnv)
    Trace sts -> prop
prop
forAllTrace ::
  forall sts traceGenEnv prop.
  ( HasTrace sts traceGenEnv
  , QuickCheck.Testable prop
  , Show (Environment sts)
  ) =>
  BaseEnv sts ->
  
  Word64 ->
  traceGenEnv ->
  (Trace sts -> prop) ->
  QuickCheck.Property
forAllTrace :: forall sts traceGenEnv prop.
(HasTrace sts traceGenEnv, Testable prop,
 Show (Environment sts)) =>
BaseEnv sts
-> Word64 -> traceGenEnv -> (Trace sts -> prop) -> Property
forAllTrace BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv =
  BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> (Trace sts -> prop)
-> Property
forall sts traceGenEnv prop.
(HasTrace sts traceGenEnv, Testable prop,
 Show (Environment sts)) =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> (Trace sts -> prop)
-> Property
forAllTraceFromInitState BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
forall a. Maybe a
Nothing
shrinkTrace ::
  forall sts traceGenEnv.
  HasTrace sts traceGenEnv =>
  BaseEnv sts ->
  Trace sts ->
  [Trace sts]
shrinkTrace :: forall sts traceGenEnv.
HasTrace sts traceGenEnv =>
BaseEnv sts -> Trace sts -> [Trace sts]
shrinkTrace BaseEnv sts
baseEnv Trace sts
tr =
  forall sts traceGenEnv a.
(HasTrace sts traceGenEnv, HasCallStack) =>
BaseEnv sts -> BaseM sts a -> a
interpretSTS @sts @traceGenEnv BaseEnv sts
baseEnv (BaseM sts [Trace sts] -> [Trace sts])
-> BaseM sts [Trace sts] -> [Trace sts]
forall a b. (a -> b) -> a -> b
$
    Environment sts
-> State sts -> [Signal sts] -> BaseM sts (Trace sts)
forall s (m :: * -> *).
(STS s, m ~ BaseM s) =>
Environment s -> State s -> [Signal s] -> m (Trace s)
Trace.closure Environment sts
env State sts
st0 ([Signal sts] -> BaseM sts (Trace sts))
-> [[Signal sts]] -> BaseM sts [Trace sts]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
`traverse` [Signal sts] -> [[Signal sts]]
forall {a}. [a] -> [[a]]
shrinkSignals [Signal sts]
signals
  where
    env :: Environment sts
env = Trace sts -> Environment sts
forall s. Trace s -> Environment s
Trace._traceEnv Trace sts
tr
    st0 :: State sts
st0 = Trace sts -> State sts
forall s. Trace s -> State s
Trace._traceInitState Trace sts
tr
    signals :: [Signal sts]
signals = TraceOrder -> Trace sts -> [Signal sts]
forall s. TraceOrder -> Trace s -> [Signal s]
Trace.traceSignals TraceOrder
Trace.NewestFirst Trace sts
tr
    
    
    
    
    
    
    
    shrinkSignals :: [a] -> [[a]]
shrinkSignals (a
sn : a
_last : []) =
      [[a
sn]]
    shrinkSignals (a
sn : a
sm : [a]
sigs) =
      [[a
sn]] 
        [[a]] -> [[a]] -> [[a]]
forall a. [a] -> [a] -> [a]
++ ((a
sn a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) ([a] -> [a]) -> [[a]] -> [[a]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a] -> [[a]]
shrinkSignals (a
sm a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
sigs)) 
        [[a]] -> [[a]] -> [[a]]
forall a. [a] -> [a] -> [a]
++ [a
sn a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
sigs] 
    
    shrinkSignals [a]
_ = []
onlyValidSignalsAreGenerated ::
  forall sts traceGenEnv.
  ( HasTrace sts traceGenEnv
  , Show (Environment sts)
  , Show (Signal sts)
  ) =>
  BaseEnv sts ->
  
  Word64 ->
  traceGenEnv ->
  QuickCheck.Property
onlyValidSignalsAreGenerated :: forall sts traceGenEnv.
(HasTrace sts traceGenEnv, Show (Environment sts),
 Show (Signal sts)) =>
BaseEnv sts -> Word64 -> traceGenEnv -> Property
onlyValidSignalsAreGenerated BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv =
  forall sts traceGenEnv.
(HasTrace sts traceGenEnv, Show (Environment sts),
 Show (Signal sts)) =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> Property
onlyValidSignalsAreGeneratedFromInitState @sts BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
forall a. Maybe a
Nothing
onlyValidSignalsAreGeneratedFromInitState ::
  forall sts traceGenEnv.
  ( HasTrace sts traceGenEnv
  , Show (Environment sts)
  , Show (Signal sts)
  ) =>
  BaseEnv sts ->
  
  Word64 ->
  traceGenEnv ->
  
  Maybe (IRC sts -> QuickCheck.Gen (Either (NonEmpty (STS.PredicateFailure sts)) (State sts))) ->
  QuickCheck.Property
onlyValidSignalsAreGeneratedFromInitState :: forall sts traceGenEnv.
(HasTrace sts traceGenEnv, Show (Environment sts),
 Show (Signal sts)) =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> Property
onlyValidSignalsAreGeneratedFromInitState BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
genSt0 =
  BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> (Trace sts -> Property)
-> Property
forall sts traceGenEnv prop.
(HasTrace sts traceGenEnv, Testable prop,
 Show (Environment sts)) =>
BaseEnv sts
-> Word64
-> traceGenEnv
-> Maybe
     (IRC sts
      -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
-> (Trace sts -> prop)
-> Property
forAllTraceFromInitState BaseEnv sts
baseEnv Word64
maxTraceLength traceGenEnv
traceGenEnv Maybe
  (IRC sts
   -> Gen (Either (NonEmpty (PredicateFailure sts)) (State sts)))
genSt0 Trace sts -> Property
validSignalsAreGenerated
  where
    validSignalsAreGenerated ::
      Trace sts ->
      QuickCheck.Property
    validSignalsAreGenerated :: Trace sts -> Property
validSignalsAreGenerated Trace sts
someTrace =
      Gen (Signal sts)
-> (Signal sts -> [Signal sts])
-> (Signal sts -> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
QuickCheck.forAllShrink
        (forall sts traceGenEnv.
(HasTrace sts traceGenEnv, HasCallStack) =>
traceGenEnv -> Environment sts -> State sts -> Gen (Signal sts)
sigGen @sts @traceGenEnv traceGenEnv
traceGenEnv Environment sts
env State sts
lastState)
        (forall sts traceGenEnv.
(HasTrace sts traceGenEnv, HasCallStack) =>
Signal sts -> [Signal sts]
shrinkSignal @sts @traceGenEnv)
        Signal sts -> Property
signalIsValid
      where
        signalIsValid :: Signal sts -> Property
signalIsValid Signal sts
signal =
          case forall sts traceGenEnv a.
(HasTrace sts traceGenEnv, HasCallStack) =>
BaseEnv sts -> BaseM sts a -> a
interpretSTS @sts @traceGenEnv BaseEnv sts
baseEnv (forall s (m :: * -> *) (rtype :: RuleType).
(STS s, RuleTypeRep rtype, m ~ BaseM s) =>
RuleContext rtype s
-> m (Either (NonEmpty (PredicateFailure s)) (State s))
Trace.applySTSTest @sts ((Environment sts, State sts, Signal sts) -> TRC sts
forall sts. (Environment sts, State sts, Signal sts) -> TRC sts
TRC (Environment sts
env, State sts
lastState, Signal sts
signal))) of
            Left NonEmpty (PredicateFailure sts)
pf -> [Char] -> Bool -> Property
forall prop. Testable prop => [Char] -> prop -> Property
QuickCheck.counterexample (NonEmpty (PredicateFailure sts) -> [Char]
forall a. Show a => a -> [Char]
show NonEmpty (PredicateFailure sts)
pf) Bool
False
            Right State sts
_ -> Bool -> Property
forall prop. Testable prop => prop -> Property
QuickCheck.property Bool
True
        env :: Environment sts
env = Trace sts -> Environment sts
forall s. Trace s -> Environment s
Trace._traceEnv Trace sts
someTrace
        lastState :: State sts
lastState = Trace sts -> State sts
forall s. Trace s -> State s
Trace.lastState Trace sts
someTrace
traceLengthsAreClassified ::
  forall sts traceGenEnv.
  ( HasTrace sts traceGenEnv
  , Show (Environment sts)
  ) =>
  BaseEnv sts ->
  
  Word64 ->
  
  Word64 ->
  
  traceGenEnv ->
  QuickCheck.Property
traceLengthsAreClassified :: forall sts traceGenEnv.
(HasTrace sts traceGenEnv, Show (Environment sts)) =>
BaseEnv sts -> Word64 -> Word64 -> traceGenEnv -> Property
traceLengthsAreClassified BaseEnv sts
baseEnv Word64
maxTraceLength Word64
intervalSize traceGenEnv
traceGenEnv =
  forall sts traceGenEnv prop.
(HasTrace sts traceGenEnv, Testable prop,
 Show (Environment sts)) =>
BaseEnv sts
-> Word64 -> traceGenEnv -> (Trace sts -> prop) -> Property
forAllTrace @sts
    BaseEnv sts
baseEnv
    Word64
maxTraceLength
    traceGenEnv
traceGenEnv
    (Word64 -> Word64 -> Trace sts -> Property
forall s. Word64 -> Word64 -> Trace s -> Property
classifyTraceLength Word64
maxTraceLength Word64
intervalSize)
classifyTraceLength ::
  
  Word64 ->
  
  Word64 ->
  Trace s ->
  QuickCheck.Property
classifyTraceLength :: forall s. Word64 -> Word64 -> Trace s -> Property
classifyTraceLength Word64
maxTraceLength Word64
step Trace s
tr =
  [Char]
-> Trace s -> (Trace s -> Word64) -> Word64 -> Word64 -> Property
forall n a.
(Show n, Integral n) =>
[Char] -> a -> (a -> n) -> n -> n -> Property
classifySize [Char]
"trace length:" Trace s
tr (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word64) -> (Trace s -> Int) -> Trace s -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Trace s -> Int
forall s. Trace s -> Int
Trace.traceLength) Word64
maxTraceLength Word64
step
classifySize ::
  (Show n, Integral n) =>
  
  String ->
  
  a ->
  
  (a -> n) ->
  
  n ->
  
  n ->
  QuickCheck.Property
classifySize :: forall n a.
(Show n, Integral n) =>
[Char] -> a -> (a -> n) -> n -> n -> Property
classifySize [Char]
prefixLabel a
value a -> n
sizeF n
upBound n
step =
  Bool -> [Char] -> Property -> Property
forall prop. Testable prop => Bool -> [Char] -> prop -> Property
QuickCheck.classify (a -> n
sizeF a
value n -> n -> Bool
forall a. Eq a => a -> a -> Bool
== n
0) ([Char] -> [Char]
mkLabel [Char]
"empty") (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
    Bool -> [Char] -> Property -> Property
forall prop. Testable prop => Bool -> [Char] -> prop -> Property
QuickCheck.classify (a -> n
sizeF a
value n -> n -> Bool
forall a. Eq a => a -> a -> Bool
== n
1) ([Char] -> [Char]
mkLabel [Char]
"singleton") (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
      Bool -> [Char] -> Property -> Property
forall prop. Testable prop => Bool -> [Char] -> prop -> Property
QuickCheck.classify (a -> n
sizeF a
value n -> n -> Bool
forall a. Eq a => a -> a -> Bool
== n
upBound) [Char]
upBoundLabel (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
        ((n, n) -> Property -> Property)
-> Property -> [(n, n)] -> Property
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (n, n) -> Property -> Property
classifySizeInterval (Bool -> Property
forall prop. Testable prop => prop -> Property
QuickCheck.property Bool
True) (n -> n -> n -> [(n, n)]
forall n. Integral n => n -> n -> n -> [(n, n)]
mkIntervals n
2 (n
upBound n -> n -> n
forall a. Num a => a -> a -> a
- n
1) n
step)
  where
    upBoundLabel :: [Char]
upBoundLabel = [Char] -> [Char]
mkLabel ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ n -> [Char]
forall a. Show a => a -> [Char]
show n
upBound
    mkLabel :: [Char] -> [Char]
mkLabel = (([Char]
prefixLabel [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" ") [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++)
    classifySizeInterval :: (n, n) -> Property -> Property
classifySizeInterval (n
low, n
high) Property
prop =
      Bool -> [Char] -> Property -> Property
forall prop. Testable prop => Bool -> [Char] -> prop -> Property
QuickCheck.classify (n
low n -> n -> Bool
forall a. Ord a => a -> a -> Bool
<= a -> n
sizeF a
value Bool -> Bool -> Bool
&& a -> n
sizeF a
value n -> n -> Bool
forall a. Ord a => a -> a -> Bool
< n
high) [Char]
desc Property
prop
      where
        desc :: [Char]
desc = [Char]
"[" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ n -> [Char]
forall a. Show a => a -> [Char]
show n
low [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ n -> [Char]
forall a. Show a => a -> [Char]
show n
high [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")"
mkIntervals ::
  Integral n =>
  
  n ->
  
  n ->
  
  
  n ->
  [(n, n)]
mkIntervals :: forall n. Integral n => n -> n -> n -> [(n, n)]
mkIntervals n
low n
high n
step
  | n
0 n -> n -> Bool
forall a. Ord a => a -> a -> Bool
<= n
low Bool -> Bool -> Bool
&& n
low n -> n -> Bool
forall a. Ord a => a -> a -> Bool
<= n
high Bool -> Bool -> Bool
&& n
0 n -> n -> Bool
forall a. Ord a => a -> a -> Bool
< n
step =
      [(n
low n -> n -> n
forall a. Num a => a -> a -> a
+ n
i n -> n -> n
forall a. Num a => a -> a -> a
* n
step, n
high n -> n -> n
forall a. Ord a => a -> a -> a
`min` (n
low n -> n -> n
forall a. Num a => a -> a -> a
+ (n
i n -> n -> n
forall a. Num a => a -> a -> a
+ n
1) n -> n -> n
forall a. Num a => a -> a -> a
* n
step)) | n
i <- [n
0 .. n
n n -> n -> n
forall a. Num a => a -> a -> a
- n
1]]
  | Bool
otherwise = []
  where
    highNorm :: n
highNorm = n
high n -> n -> n
forall a. Num a => a -> a -> a
- n
low
    n :: n
n = n
highNorm n -> n -> n
forall a. Integral a => a -> a -> a
`div` n
step n -> n -> n
forall a. Num a => a -> a -> a
+ n
1 n -> n -> n
forall a. Ord a => a -> a -> a
`min` (n
highNorm n -> n -> n
forall a. Integral a => a -> a -> a
`mod` n
step)