@@ -171,10 +171,10 @@ instance StateModel s => Show (FailingAction s) where
171
171
show (ActionFail (ActionWithPolarity a pol)) = show pol ++ " : " ++ show a
172
172
173
173
data DynLogicTest s
174
- = BadPrecondition (TestSequence s ) (FailingAction s ) (Annotated s )
175
- | Looping (TestSequence s )
176
- | Stuck (TestSequence s ) (Annotated s )
177
- | DLScript (TestSequence s )
174
+ = BadPrecondition (Annotated s ) ( TestSequence s ) (FailingAction s ) (Annotated s )
175
+ | Looping (Annotated s ) ( TestSequence s )
176
+ | Stuck (Annotated s ) ( TestSequence s ) (Annotated s )
177
+ | DLScript (Annotated s ) ( TestSequence s )
178
178
179
179
data Witnesses r where
180
180
Do :: r -> Witnesses r
@@ -295,8 +295,10 @@ prettyWitnesses (Witness a w) = ("_ <- forAllQ $ exactlyQ $ " ++ show a) : prett
295
295
prettyWitnesses Do {} = []
296
296
297
297
instance StateModel s => Show (DynLogicTest s ) where
298
- show (BadPrecondition ss bad s) =
299
- prettyTestSequence (usedVariables ss <> allVariables bad) ss
298
+ show (BadPrecondition is ss bad s) =
299
+ " -- Initial state: "
300
+ ++ show is
301
+ ++ prettyTestSequence (usedVariables is ss <> allVariables bad) ss
300
302
++ " \n -- In state: "
301
303
++ show s
302
304
++ " \n "
@@ -309,12 +311,25 @@ instance StateModel s => Show (DynLogicTest s) where
309
311
f
310
312
| p == PosPolarity = " action"
311
313
| otherwise = " failingAction"
312
- show (Looping ss) = prettyTestSequence (usedVariables ss) ss ++ " \n pure ()\n -- Looping"
313
- show (Stuck ss s) = prettyTestSequence (usedVariables ss) ss ++ " \n pure ()\n -- Stuck in state " ++ show s
314
- show (DLScript ss) = prettyTestSequence (usedVariables ss) ss ++ " \n pure ()\n "
315
-
316
- usedVariables :: forall s . StateModel s => TestSequence s -> VarContext
317
- usedVariables = go initialAnnotatedState
314
+ show (Looping is ss) =
315
+ " -- Initial state: "
316
+ ++ show is
317
+ ++ prettyTestSequence (usedVariables is ss) ss
318
+ ++ " \n pure ()\n -- Looping"
319
+ show (Stuck is ss s) =
320
+ " -- Initial state: "
321
+ ++ show is
322
+ ++ prettyTestSequence (usedVariables is ss) ss
323
+ ++ " \n pure ()\n -- Stuck in state "
324
+ ++ show s
325
+ show (DLScript is ss) =
326
+ " -- Initial state: "
327
+ ++ show is
328
+ ++ prettyTestSequence (usedVariables is ss) ss
329
+ ++ " \n pure ()\n "
330
+
331
+ usedVariables :: forall s . StateModel s => Annotated s -> TestSequence s -> VarContext
332
+ usedVariables s = go s
318
333
where
319
334
go :: Annotated s -> TestSequence s -> VarContext
320
335
go aState TestSeqStop = allVariables (underlyingState aState)
@@ -342,10 +357,11 @@ restrictedPolar (ActionWithPolarity a _) = restricted a
342
357
-- `Actions` sequence into a proper `Property` that can be run by QuickCheck.
343
358
forAllScripts
344
359
:: (DynLogicModel s , Testable a )
345
- => DynFormula s
360
+ => s
361
+ -> DynFormula s
346
362
-> (Actions s -> a )
347
363
-> Property
348
- forAllScripts = forAllMappedScripts id id
364
+ forAllScripts s = forAllMappedScripts s id id
349
365
350
366
-- | `Property` function suitable for formulae without choice.
351
367
forAllUniqueScripts
@@ -365,16 +381,17 @@ forAllUniqueScripts s f k =
365
381
-- | Creates a `Property` from `DynFormula` with some specialised isomorphism for shrinking purpose.
366
382
forAllMappedScripts
367
383
:: (DynLogicModel s , Testable a )
368
- => (rep -> DynLogicTest s )
384
+ => s
385
+ -> (rep -> DynLogicTest s )
369
386
-> (DynLogicTest s -> rep )
370
387
-> DynFormula s
371
388
-> (Actions s -> a )
372
389
-> Property
373
- forAllMappedScripts to from f k =
390
+ forAllMappedScripts s to from f k =
374
391
QC. withSize $ \ n ->
375
392
let d = unDynFormula f n
376
393
in forAllShrinkBlind
377
- (Smart 0 <$> sized ((from <$> ) . generateDLTest d))
394
+ (Smart 0 <$> sized ((from <$> ) . generateDLTest ( Metadata mempty s) d))
378
395
(shrinkSmart ((from <$> ) . shrinkDLTest d . to))
379
396
$ \ (Smart _ script) ->
380
397
withDLScript d k (to script)
@@ -405,17 +422,24 @@ validDLTest test prop =
405
422
Stuck {} -> property Discard
406
423
_other -> counterexample (show test) False
407
424
408
- generateDLTest :: DynLogicModel s => DynLogic s -> Int -> Gen (DynLogicTest s )
409
- generateDLTest d size = generate chooseNextStep d 0 (initialStateFor d) size
425
+ generateDLTest :: DynLogicModel s => Annotated s -> DynLogic s -> Int -> Gen (DynLogicTest s )
426
+ generateDLTest s d size = do
427
+ generate chooseNextStep d 0 s size
410
428
411
429
onDLTestSeq :: (TestSequence s -> TestSequence s ) -> DynLogicTest s -> DynLogicTest s
412
- onDLTestSeq f (BadPrecondition ss bad s) = BadPrecondition (f ss) bad s
413
- onDLTestSeq f (Looping ss) = Looping (f ss)
414
- onDLTestSeq f (Stuck ss s) = Stuck (f ss) s
415
- onDLTestSeq f (DLScript ss) = DLScript (f ss)
430
+ onDLTestSeq f (BadPrecondition is ss bad s) = BadPrecondition is (f ss) bad s
431
+ onDLTestSeq f (Looping is ss) = Looping is (f ss)
432
+ onDLTestSeq f (Stuck is ss s) = Stuck is (f ss) s
433
+ onDLTestSeq f (DLScript is ss) = DLScript is (f ss)
434
+
435
+ setDLTestState :: Annotated s -> DynLogicTest s -> DynLogicTest s
436
+ setDLTestState is (BadPrecondition _ ss bad s) = BadPrecondition is ss bad s
437
+ setDLTestState is (Looping _ ss) = Looping is ss
438
+ setDLTestState is (Stuck _ ss s) = Stuck is ss s
439
+ setDLTestState is (DLScript _ ss) = DLScript is ss
416
440
417
- consDLTest :: TestStep s -> DynLogicTest s -> DynLogicTest s
418
- consDLTest step = onDLTestSeq (step :> )
441
+ consDLTest :: Annotated s -> TestStep s -> DynLogicTest s -> DynLogicTest s
442
+ consDLTest is step = setDLTestState is . onDLTestSeq (step :> )
419
443
420
444
consDLTestW :: Witnesses () -> DynLogicTest s -> DynLogicTest s
421
445
consDLTestW w = onDLTestSeq (addW w)
@@ -433,15 +457,15 @@ generate
433
457
-> m (DynLogicTest s )
434
458
generate chooseNextStepFun d n s size =
435
459
if n > sizeLimit size
436
- then return $ Looping TestSeqStop
460
+ then return $ Looping s TestSeqStop
437
461
else do
438
462
let preferred = if n > size then stopping d else noStopping d
439
- useStep (BadAction (Witnesses ws bad)) _ = return $ BadPrecondition (TestSeqStopW ws) bad s
440
- useStep StoppingStep _ = return $ DLScript TestSeqStop
463
+ useStep (BadAction (Witnesses ws bad)) _ = return $ BadPrecondition s (TestSeqStopW ws) bad s
464
+ useStep StoppingStep _ = return $ DLScript s TestSeqStop
441
465
useStep (Stepping step d') _ =
442
466
case discardWitnesses step of
443
467
var := act ->
444
- consDLTest step
468
+ consDLTest s step
445
469
<$> generate
446
470
chooseNextStepFun
447
471
d'
@@ -451,15 +475,12 @@ generate chooseNextStepFun d n s size =
451
475
useStep NoStep alt = alt
452
476
foldr
453
477
(\ step k -> do try <- chooseNextStepFun s n step; useStep try k)
454
- (return $ Stuck TestSeqStop s)
478
+ (return $ Stuck s TestSeqStop s)
455
479
[preferred, noAny preferred, d, noAny d]
456
480
457
481
sizeLimit :: Int -> Int
458
482
sizeLimit size = 2 * size + 20
459
483
460
- initialStateFor :: StateModel s => DynLogic s -> Annotated s
461
- initialStateFor _ = initialAnnotatedState
462
-
463
484
stopping :: DynLogic s -> DynLogic s
464
485
stopping EmptySpec = EmptySpec
465
486
stopping Stop = Stop
@@ -589,22 +610,28 @@ keepTryingUntil n g p = do
589
610
if p x then return $ Just x else scale (+ 1 ) $ keepTryingUntil (n - 1 ) g p
590
611
591
612
shrinkDLTest :: DynLogicModel s => DynLogic s -> DynLogicTest s -> [DynLogicTest s ]
592
- shrinkDLTest _ (Looping _) = []
613
+ shrinkDLTest _ (Looping _ _ ) = []
593
614
shrinkDLTest d tc =
594
- [ test | as' <- shrinkScript d (getScript tc), let pruned = pruneDLTest d as'
595
- test = makeTestFromPruned d pruned,
596
- -- Don't shrink a non-executable test case to an executable one.
615
+ [ test
616
+ | as' <-
617
+ shrinkScript
618
+ (underlyingState $ getInitialState tc)
619
+ d
620
+ (getScript tc)
621
+ , let pruned = pruneDLTest (getInitialState tc) d as'
622
+ test = makeTestFromPruned (getInitialState tc) d pruned
623
+ , -- Don't shrink a non-executable test case to an executable one.
597
624
case (tc, test) of
598
- (DLScript _, _) -> True
599
- (_, DLScript _) -> False
625
+ (DLScript _ _ , _) -> True
626
+ (_, DLScript _ _ ) -> False
600
627
_ -> True
601
628
]
602
629
603
630
nextStateStep :: StateModel s => Step s -> Annotated s -> Annotated s
604
631
nextStateStep (var := act) s = computeNextState s act var
605
632
606
- shrinkScript :: forall s . DynLogicModel s => DynLogic s -> TestSequence s -> [TestSequence s ]
607
- shrinkScript = shrink' initialAnnotatedState
633
+ shrinkScript :: forall s . DynLogicModel s => s -> DynLogic s -> TestSequence s -> [TestSequence s ]
634
+ shrinkScript is = shrink' ( Metadata mempty is)
608
635
where
609
636
shrink' :: Annotated s -> DynLogic s -> TestSequence s -> [TestSequence s ]
610
637
shrink' s d ss = structural s d ss ++ nonstructural s d ss
@@ -648,8 +675,8 @@ shrinkWitness AfterAny{} _ = []
648
675
649
676
-- The result of pruning a list of actions is a prefix of a list of actions that
650
677
-- could have been generated by the dynamic logic.
651
- pruneDLTest :: forall s . DynLogicModel s => DynLogic s -> TestSequence s -> TestSequence s
652
- pruneDLTest dl = prune [dl] initialAnnotatedState
678
+ pruneDLTest :: forall s . DynLogicModel s => Annotated s -> DynLogic s -> TestSequence s -> TestSequence s
679
+ pruneDLTest is dl = prune [dl] is
653
680
where
654
681
prune [] _ _ = TestSeqStop
655
682
prune _ _ TestSeqStop = TestSeqStop
@@ -710,27 +737,29 @@ demonicAlt ds = foldr1 (Alt Demonic) ds
710
737
711
738
propPruningGeneratedScriptIsNoop :: DynLogicModel s => DynLogic s -> Property
712
739
propPruningGeneratedScriptIsNoop d =
713
- forAll (sized $ \ n -> choose (1 , max 1 n) >>= generateDLTest d) $ \ test ->
714
- let script = case test of
715
- BadPrecondition s _ _ -> s
716
- Looping s -> s
717
- Stuck s _ -> s
718
- DLScript s -> s
719
- in script == pruneDLTest d script
740
+ forAll initialState $ \ s ->
741
+ forAll (sized $ \ n -> choose (1 , max 1 n) >>= generateDLTest (Metadata mempty s) d) $ \ test ->
742
+ getScript test == pruneDLTest (getInitialState test) d (getScript test)
743
+
744
+ getInitialState :: DynLogicTest s -> Annotated s
745
+ getInitialState (BadPrecondition is _ _ _) = is
746
+ getInitialState (Looping is _) = is
747
+ getInitialState (Stuck is _ _) = is
748
+ getInitialState (DLScript is _) = is
720
749
721
750
getScript :: DynLogicTest s -> TestSequence s
722
- getScript (BadPrecondition s _ _) = s
723
- getScript (Looping s) = s
724
- getScript (Stuck s _) = s
725
- getScript (DLScript s) = s
751
+ getScript (BadPrecondition _ s _ _) = s
752
+ getScript (Looping _ s) = s
753
+ getScript (Stuck _ s _) = s
754
+ getScript (DLScript _ s) = s
726
755
727
- makeTestFromPruned :: forall s . DynLogicModel s => DynLogic s -> TestSequence s -> DynLogicTest s
728
- makeTestFromPruned dl = make dl initialAnnotatedState
756
+ makeTestFromPruned :: forall s . DynLogicModel s => Annotated s -> DynLogic s -> TestSequence s -> DynLogicTest s
757
+ makeTestFromPruned st dl = make dl st
729
758
where
730
759
make d s TestSeqStop
731
- | b : _ <- badActions @ s d s = BadPrecondition TestSeqStop b s
732
- | stuck d s = Stuck TestSeqStop s
733
- | otherwise = DLScript TestSeqStop
760
+ | b : _ <- badActions @ s d s = BadPrecondition s TestSeqStop b s
761
+ | stuck d s = Stuck s TestSeqStop s
762
+ | otherwise = DLScript s TestSeqStop
734
763
make d s (TestSeqWitness a ss) =
735
764
onDLTestSeq (TestSeqWitness a) $
736
765
make
@@ -747,13 +776,7 @@ makeTestFromPruned dl = make dl initialAnnotatedState
747
776
-- | If failed, return the prefix up to the failure. Also prunes the test in case the model has
748
777
-- changed.
749
778
unfailDLTest :: DynLogicModel s => DynLogic s -> DynLogicTest s -> DynLogicTest s
750
- unfailDLTest d test = makeTestFromPruned d $ pruneDLTest d steps
751
- where
752
- steps = case test of
753
- BadPrecondition as _ _ -> as
754
- Stuck as _ -> as
755
- DLScript as -> as
756
- Looping as -> as
779
+ unfailDLTest d test = makeTestFromPruned (getInitialState test) d $ pruneDLTest (getInitialState test) d (getScript test)
757
780
758
781
stuck :: DynLogicModel s => DynLogic s -> Annotated s -> Bool
759
782
stuck EmptySpec _ = True
@@ -778,8 +801,8 @@ stuck (ForAll _ _) _ = False
778
801
stuck (Monitor _ d) s = stuck d s
779
802
780
803
scriptFromDL :: DynLogicTest s -> Actions s
781
- scriptFromDL (DLScript s) = Actions $ sequenceSteps s
782
- scriptFromDL _ = Actions []
804
+ scriptFromDL (DLScript is s) = Actions (underlyingState is) $ sequenceSteps s
805
+ scriptFromDL test = Actions (underlyingState $ getInitialState test) []
783
806
784
807
sequenceSteps :: TestSequence s -> [Step s ]
785
808
sequenceSteps (TestSeq ss) =
@@ -818,8 +841,8 @@ badActions (ForAll _ _) _ = []
818
841
badActions (Monitor _ d) s = badActions d s
819
842
820
843
applyMonitoring :: DynLogicModel s => DynLogic s -> DynLogicTest s -> Property -> Property
821
- applyMonitoring d (DLScript s) p =
822
- case findMonitoring d initialAnnotatedState s of
844
+ applyMonitoring d (DLScript is s) p =
845
+ case findMonitoring d is s of
823
846
Just f -> f p
824
847
Nothing -> p
825
848
applyMonitoring _ Stuck {} p = p
0 commit comments