{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
module Test.DejaFu.Refinement
(
Sig(..)
, RefinementProperty
, expectFailure
, refines, (=>=)
, strictlyRefines, (->-)
, equivalentTo, (===)
, FailedProperty(..)
, Testable(O,X)
, check
, check'
, checkFor
, counterExamples
, Listable(..)
) where
import Control.Arrow (first)
import Control.Monad.Conc.Class (fork)
import Data.Kind (Type)
import Data.Maybe (isNothing)
import Data.Set (Set)
import qualified Data.Set as S
import Test.LeanCheck (Listable(..), concatMapT, mapT)
import Test.DejaFu.Conc (ConcIO, Condition,
withSetupAndTeardown)
import Test.DejaFu.SCT (runSCT)
import Test.DejaFu.Settings (defaultMemType, defaultWay)
data How = Weak | Equiv | Strict deriving How -> How -> Bool
(How -> How -> Bool) -> (How -> How -> Bool) -> Eq How
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: How -> How -> Bool
== :: How -> How -> Bool
$c/= :: How -> How -> Bool
/= :: How -> How -> Bool
Eq
data RefinementProperty o x where
RP :: Ord o => How -> Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
Neg :: RefinementProperty o x -> RefinementProperty o x
data Sig s o x = Sig
{ forall s o x. Sig s o x -> x -> ConcIO s
initialise :: x -> ConcIO s
, forall s o x. Sig s o x -> s -> x -> ConcIO o
observe :: s -> x -> ConcIO o
, forall s o x. Sig s o x -> s -> x -> ConcIO ()
interfere :: s -> x -> ConcIO ()
, forall s o x. Sig s o x -> s -> ConcIO ()
expression :: s -> ConcIO ()
}
expectFailure :: RefinementProperty o x -> RefinementProperty o x
expectFailure :: forall o x. RefinementProperty o x -> RefinementProperty o x
expectFailure = RefinementProperty o x -> RefinementProperty o x
forall o x. RefinementProperty o x -> RefinementProperty o x
Neg
refines :: Ord o => Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
refines :: forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
refines = How -> Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
forall o s1 x s2.
Ord o =>
How -> Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
RP How
Weak
(=>=) :: Ord o => Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
=>= :: forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
(=>=) = Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
refines
equivalentTo :: Ord o => Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
equivalentTo :: forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
equivalentTo = How -> Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
forall o s1 x s2.
Ord o =>
How -> Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
RP How
Equiv
(===) :: Ord o => Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
=== :: forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
(===) = Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
equivalentTo
strictlyRefines :: Ord o => Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
strictlyRefines :: forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
strictlyRefines = How -> Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
forall o s1 x s2.
Ord o =>
How -> Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
RP How
Strict
(->-) :: Ord o => Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
->- :: forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
(->-) = Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
forall o s1 x s2.
Ord o =>
Sig s1 o x -> Sig s2 o x -> RefinementProperty o x
strictlyRefines
class Testable a where
type O a :: Type
type X a :: Type
rpropTiers :: a -> [[([String], RefinementProperty (O a) (X a))]]
instance Testable (RefinementProperty o x) where
type O (RefinementProperty o x) = o
type X (RefinementProperty o x) = x
rpropTiers :: RefinementProperty o x
-> [[([String],
RefinementProperty
(O (RefinementProperty o x)) (X (RefinementProperty o x)))]]
rpropTiers RefinementProperty o x
p = [[([], RefinementProperty o x
RefinementProperty
(O (RefinementProperty o x)) (X (RefinementProperty o x))
p)]]
instance (Listable a, Show a, Testable b) => Testable (a -> b) where
type O (a -> b) = O b
type X (a -> b) = X b
rpropTiers :: (a -> b)
-> [[([String], RefinementProperty (O (a -> b)) (X (a -> b)))]]
rpropTiers a -> b
p = (a -> [[([String], RefinementProperty (O b) (X b))]])
-> [[a]] -> [[([String], RefinementProperty (O b) (X b))]]
forall a b. (a -> [[b]]) -> [[a]] -> [[b]]
concatMapT a -> [[([String], RefinementProperty (O b) (X b))]]
resultiersFor [[a]]
forall a. Listable a => [[a]]
tiers where
resultiersFor :: a -> [[([String], RefinementProperty (O b) (X b))]]
resultiersFor a
x = ([String] -> [String])
-> ([String], RefinementProperty (O b) (X b))
-> ([String], RefinementProperty (O b) (X b))
forall b c d. (b -> c) -> (b, d) -> (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a -> String
forall a. Show a => a -> String
show a
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:) (([String], RefinementProperty (O b) (X b))
-> ([String], RefinementProperty (O b) (X b)))
-> [[([String], RefinementProperty (O b) (X b))]]
-> [[([String], RefinementProperty (O b) (X b))]]
forall a b. (a -> b) -> [[a]] -> [[b]]
`mapT` b -> [[([String], RefinementProperty (O b) (X b))]]
forall a.
Testable a =>
a -> [[([String], RefinementProperty (O a) (X a))]]
rpropTiers (a -> b
p a
x)
data FailedProperty o x
= CounterExample
{ forall o x. FailedProperty o x -> x
failingSeed :: x
, forall o x. FailedProperty o x -> [String]
failingArgs :: [String]
, forall o x. FailedProperty o x -> Set (Maybe Condition, o)
leftResults :: Set (Maybe Condition, o)
, forall o x. FailedProperty o x -> Set (Maybe Condition, o)
rightResults :: Set (Maybe Condition, o)
}
| NoExpectedFailure
deriving Int -> FailedProperty o x -> ShowS
[FailedProperty o x] -> ShowS
FailedProperty o x -> String
(Int -> FailedProperty o x -> ShowS)
-> (FailedProperty o x -> String)
-> ([FailedProperty o x] -> ShowS)
-> Show (FailedProperty o x)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall o x. (Show x, Show o) => Int -> FailedProperty o x -> ShowS
forall o x. (Show x, Show o) => [FailedProperty o x] -> ShowS
forall o x. (Show x, Show o) => FailedProperty o x -> String
$cshowsPrec :: forall o x. (Show x, Show o) => Int -> FailedProperty o x -> ShowS
showsPrec :: Int -> FailedProperty o x -> ShowS
$cshow :: forall o x. (Show x, Show o) => FailedProperty o x -> String
show :: FailedProperty o x -> String
$cshowList :: forall o x. (Show x, Show o) => [FailedProperty o x] -> ShowS
showList :: [FailedProperty o x] -> ShowS
Show
check :: (Testable p, Listable (X p), Show (X p), Show (O p))
=> p
-> IO Bool
check :: forall p.
(Testable p, Listable (X p), Show (X p), Show (O p)) =>
p -> IO Bool
check p
p = do
Maybe (FailedProperty (O p) (X p))
ce <- p -> IO (Maybe (FailedProperty (O p) (X p)))
forall p.
(Testable p, Listable (X p)) =>
p -> IO (Maybe (FailedProperty (O p) (X p)))
check' p
p
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ case Maybe (FailedProperty (O p) (X p))
ce of
Just FailedProperty (O p) (X p)
NoExpectedFailure -> String
"*** Failure: passed, but expected failure."
Just FailedProperty (O p) (X p)
c -> ShowS
forall a. HasCallStack => [a] -> [a]
init ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ String
"*** Failure: " String -> ShowS
forall a. [a] -> [a] -> [a]
++
(if [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (FailedProperty (O p) (X p) -> [String]
forall o x. FailedProperty o x -> [String]
failingArgs FailedProperty (O p) (X p)
c) then String
"" else [String] -> String
unwords (FailedProperty (O p) (X p) -> [String]
forall o x. FailedProperty o x -> [String]
failingArgs FailedProperty (O p) (X p)
c) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" ") String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
"(seed " String -> ShowS
forall a. [a] -> [a] -> [a]
++ X p -> String
forall a. Show a => a -> String
show (FailedProperty (O p) (X p) -> X p
forall o x. FailedProperty o x -> x
failingSeed FailedProperty (O p) (X p)
c) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
, String
" left: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(Maybe Condition, O p)] -> String
forall a. Show a => a -> String
show (Set (Maybe Condition, O p) -> [(Maybe Condition, O p)]
forall a. Set a -> [a]
S.toList (Set (Maybe Condition, O p) -> [(Maybe Condition, O p)])
-> Set (Maybe Condition, O p) -> [(Maybe Condition, O p)]
forall a b. (a -> b) -> a -> b
$ FailedProperty (O p) (X p) -> Set (Maybe Condition, O p)
forall o x. FailedProperty o x -> Set (Maybe Condition, o)
leftResults FailedProperty (O p) (X p)
c)
, String
" right: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(Maybe Condition, O p)] -> String
forall a. Show a => a -> String
show (Set (Maybe Condition, O p) -> [(Maybe Condition, O p)]
forall a. Set a -> [a]
S.toList (Set (Maybe Condition, O p) -> [(Maybe Condition, O p)])
-> Set (Maybe Condition, O p) -> [(Maybe Condition, O p)]
forall a b. (a -> b) -> a -> b
$ FailedProperty (O p) (X p) -> Set (Maybe Condition, O p)
forall o x. FailedProperty o x -> Set (Maybe Condition, o)
rightResults FailedProperty (O p) (X p)
c)
]
Maybe (FailedProperty (O p) (X p))
Nothing -> String
"+++ OK"
Bool -> IO Bool
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (FailedProperty (O p) (X p)) -> Bool
forall a. Maybe a -> Bool
isNothing Maybe (FailedProperty (O p) (X p))
ce)
check' :: (Testable p, Listable (X p))
=> p
-> IO (Maybe (FailedProperty (O p) (X p)))
check' :: forall p.
(Testable p, Listable (X p)) =>
p -> IO (Maybe (FailedProperty (O p) (X p)))
check' = Int -> Int -> p -> IO (Maybe (FailedProperty (O p) (X p)))
forall p.
(Testable p, Listable (X p)) =>
Int -> Int -> p -> IO (Maybe (FailedProperty (O p) (X p)))
checkFor Int
10 Int
100
checkFor :: (Testable p, Listable (X p))
=> Int
-> Int
-> p
-> IO (Maybe (FailedProperty (O p) (X p)))
checkFor :: forall p.
(Testable p, Listable (X p)) =>
Int -> Int -> p -> IO (Maybe (FailedProperty (O p) (X p)))
checkFor Int
sn Int
vn p
p = do
let seeds :: [X p]
seeds = Int -> [X p] -> [X p]
forall a. Int -> [a] -> [a]
take Int
sn ([X p] -> [X p]) -> [X p] -> [X p]
forall a b. (a -> b) -> a -> b
$ [[X p]] -> [X p]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[X p]]
forall a. Listable a => [[a]]
tiers
let cases :: [([String], RefinementProperty (O p) (X p))]
cases = Int
-> [([String], RefinementProperty (O p) (X p))]
-> [([String], RefinementProperty (O p) (X p))]
forall a. Int -> [a] -> [a]
take Int
vn ([([String], RefinementProperty (O p) (X p))]
-> [([String], RefinementProperty (O p) (X p))])
-> [([String], RefinementProperty (O p) (X p))]
-> [([String], RefinementProperty (O p) (X p))]
forall a b. (a -> b) -> a -> b
$ [[([String], RefinementProperty (O p) (X p))]]
-> [([String], RefinementProperty (O p) (X p))]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (p -> [[([String], RefinementProperty (O p) (X p))]]
forall a.
Testable a =>
a -> [[([String], RefinementProperty (O a) (X a))]]
rpropTiers p
p)
[X p]
-> [([String], RefinementProperty (O p) (X p))]
-> IO (Maybe (FailedProperty (O p) (X p)))
forall {x} {o}.
[x]
-> [([String], RefinementProperty o x)]
-> IO (Maybe (FailedProperty o x))
go [X p]
seeds [([String], RefinementProperty (O p) (X p))]
cases
where
go :: [x]
-> [([String], RefinementProperty o x)]
-> IO (Maybe (FailedProperty o x))
go [x]
seeds (([String]
vs, RefinementProperty o x
p'):[([String], RefinementProperty o x)]
rest) = do
Maybe ([String] -> FailedProperty o x)
r <- [x]
-> RefinementProperty o x
-> IO (Maybe ([String] -> FailedProperty o x))
forall x o.
[x]
-> RefinementProperty o x
-> IO (Maybe ([String] -> FailedProperty o x))
checkWithSeeds [x]
seeds RefinementProperty o x
p'
case Maybe ([String] -> FailedProperty o x)
r of
Just [String] -> FailedProperty o x
cf -> Maybe (FailedProperty o x) -> IO (Maybe (FailedProperty o x))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FailedProperty o x -> Maybe (FailedProperty o x)
forall a. a -> Maybe a
Just ([String] -> FailedProperty o x
cf [String]
vs))
Maybe ([String] -> FailedProperty o x)
Nothing -> [x]
-> [([String], RefinementProperty o x)]
-> IO (Maybe (FailedProperty o x))
go [x]
seeds [([String], RefinementProperty o x)]
rest
go [x]
_ [] = Maybe (FailedProperty o x) -> IO (Maybe (FailedProperty o x))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (FailedProperty o x)
forall a. Maybe a
Nothing
counterExamples :: (Testable p, Listable (X p))
=> Int
-> Int
-> p
-> IO [FailedProperty (O p) (X p)]
counterExamples :: forall p.
(Testable p, Listable (X p)) =>
Int -> Int -> p -> IO [FailedProperty (O p) (X p)]
counterExamples Int
sn Int
vn p
p = do
let seeds :: [X p]
seeds = Int -> [X p] -> [X p]
forall a. Int -> [a] -> [a]
take Int
sn ([X p] -> [X p]) -> [X p] -> [X p]
forall a b. (a -> b) -> a -> b
$ [[X p]] -> [X p]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[X p]]
forall a. Listable a => [[a]]
tiers
let cases :: [([String], RefinementProperty (O p) (X p))]
cases = Int
-> [([String], RefinementProperty (O p) (X p))]
-> [([String], RefinementProperty (O p) (X p))]
forall a. Int -> [a] -> [a]
take Int
vn ([([String], RefinementProperty (O p) (X p))]
-> [([String], RefinementProperty (O p) (X p))])
-> [([String], RefinementProperty (O p) (X p))]
-> [([String], RefinementProperty (O p) (X p))]
forall a b. (a -> b) -> a -> b
$ [[([String], RefinementProperty (O p) (X p))]]
-> [([String], RefinementProperty (O p) (X p))]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (p -> [[([String], RefinementProperty (O p) (X p))]]
forall a.
Testable a =>
a -> [[([String], RefinementProperty (O a) (X a))]]
rpropTiers p
p)
[([String], Maybe ([String] -> FailedProperty (O p) (X p)))]
rs <- (([String], RefinementProperty (O p) (X p))
-> IO ([String], Maybe ([String] -> FailedProperty (O p) (X p))))
-> [([String], RefinementProperty (O p) (X p))]
-> IO [([String], Maybe ([String] -> FailedProperty (O p) (X p)))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\([String]
vs, RefinementProperty (O p) (X p)
p') -> ([String]
vs,) (Maybe ([String] -> FailedProperty (O p) (X p))
-> ([String], Maybe ([String] -> FailedProperty (O p) (X p))))
-> IO (Maybe ([String] -> FailedProperty (O p) (X p)))
-> IO ([String], Maybe ([String] -> FailedProperty (O p) (X p)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [X p]
-> RefinementProperty (O p) (X p)
-> IO (Maybe ([String] -> FailedProperty (O p) (X p)))
forall x o.
[x]
-> RefinementProperty o x
-> IO (Maybe ([String] -> FailedProperty o x))
checkWithSeeds [X p]
seeds RefinementProperty (O p) (X p)
p') [([String], RefinementProperty (O p) (X p))]
cases
[FailedProperty (O p) (X p)] -> IO [FailedProperty (O p) (X p)]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [ [String] -> FailedProperty (O p) (X p)
cf [String]
vs | ([String]
vs, Just [String] -> FailedProperty (O p) (X p)
cf) <- [([String], Maybe ([String] -> FailedProperty (O p) (X p)))]
rs ]
data F x = Failing x | Unknown | Refuted
checkWithSeeds
:: [x]
-> RefinementProperty o x
-> IO (Maybe ([String] -> FailedProperty o x))
checkWithSeeds :: forall x o.
[x]
-> RefinementProperty o x
-> IO (Maybe ([String] -> FailedProperty o x))
checkWithSeeds [x]
seeds (RP How
how Sig s1 o x
l Sig s2 o x
r) = case How
how of
How
Weak -> (Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool)
-> [x] -> IO (Maybe ([String] -> FailedProperty o x))
go1 Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool
forall a. Ord a => Set a -> Set a -> Bool
S.isSubsetOf [x]
seeds
How
Equiv -> (Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool)
-> [x] -> IO (Maybe ([String] -> FailedProperty o x))
go1 Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool
forall a. Eq a => a -> a -> Bool
(==) [x]
seeds
How
Strict -> F ([String] -> FailedProperty o x)
-> [x] -> IO (Maybe ([String] -> FailedProperty o x))
go2 F ([String] -> FailedProperty o x)
forall x. F x
Unknown [x]
seeds
where
go1 :: (Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool)
-> [x] -> IO (Maybe ([String] -> FailedProperty o x))
go1 Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool
f (x
x:[x]
xs) = do
Set (Maybe Condition, o)
lrs <- Sig s1 o x -> x -> IO (Set (Maybe Condition, o))
forall o s x.
Ord o =>
Sig s o x -> x -> IO (Set (Maybe Condition, o))
evalSigWithSeed Sig s1 o x
l x
x
Set (Maybe Condition, o)
rrs <- Sig s2 o x -> x -> IO (Set (Maybe Condition, o))
forall o s x.
Ord o =>
Sig s o x -> x -> IO (Set (Maybe Condition, o))
evalSigWithSeed Sig s2 o x
r x
x
if Set (Maybe Condition, o)
lrs Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool
`f` Set (Maybe Condition, o)
rrs
then (Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool)
-> [x] -> IO (Maybe ([String] -> FailedProperty o x))
go1 Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool
f [x]
xs
else Maybe ([String] -> FailedProperty o x)
-> IO (Maybe ([String] -> FailedProperty o x))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (([String] -> FailedProperty o x)
-> Maybe ([String] -> FailedProperty o x)
forall a. a -> Maybe a
Just (([String] -> FailedProperty o x)
-> Maybe ([String] -> FailedProperty o x))
-> ([String] -> FailedProperty o x)
-> Maybe ([String] -> FailedProperty o x)
forall a b. (a -> b) -> a -> b
$ x
-> Set (Maybe Condition, o)
-> Set (Maybe Condition, o)
-> [String]
-> FailedProperty o x
forall {x} {o}.
x
-> Set (Maybe Condition, o)
-> Set (Maybe Condition, o)
-> [String]
-> FailedProperty o x
toCE x
x Set (Maybe Condition, o)
lrs Set (Maybe Condition, o)
rrs)
go1 Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool
_ [] = Maybe ([String] -> FailedProperty o x)
-> IO (Maybe ([String] -> FailedProperty o x))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ([String] -> FailedProperty o x)
forall a. Maybe a
Nothing
go2 :: F ([String] -> FailedProperty o x)
-> [x] -> IO (Maybe ([String] -> FailedProperty o x))
go2 F ([String] -> FailedProperty o x)
eq (x
x:[x]
xs) = do
Set (Maybe Condition, o)
lrs <- Sig s1 o x -> x -> IO (Set (Maybe Condition, o))
forall o s x.
Ord o =>
Sig s o x -> x -> IO (Set (Maybe Condition, o))
evalSigWithSeed Sig s1 o x
l x
x
Set (Maybe Condition, o)
rrs <- Sig s2 o x -> x -> IO (Set (Maybe Condition, o))
forall o s x.
Ord o =>
Sig s o x -> x -> IO (Set (Maybe Condition, o))
evalSigWithSeed Sig s2 o x
r x
x
let ce :: [String] -> FailedProperty o x
ce = x
-> Set (Maybe Condition, o)
-> Set (Maybe Condition, o)
-> [String]
-> FailedProperty o x
forall {x} {o}.
x
-> Set (Maybe Condition, o)
-> Set (Maybe Condition, o)
-> [String]
-> FailedProperty o x
toCE x
x Set (Maybe Condition, o)
lrs Set (Maybe Condition, o)
rrs
if | Set (Maybe Condition, o)
lrs Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool
forall a. Eq a => a -> a -> Bool
== Set (Maybe Condition, o)
rrs -> F ([String] -> FailedProperty o x)
-> [x] -> IO (Maybe ([String] -> FailedProperty o x))
go2 (case F ([String] -> FailedProperty o x)
eq of F ([String] -> FailedProperty o x)
Unknown -> ([String] -> FailedProperty o x)
-> F ([String] -> FailedProperty o x)
forall x. x -> F x
Failing [String] -> FailedProperty o x
ce; F ([String] -> FailedProperty o x)
_ -> F ([String] -> FailedProperty o x)
eq) [x]
xs
| Set (Maybe Condition, o)
lrs Set (Maybe Condition, o) -> Set (Maybe Condition, o) -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`S.isSubsetOf` Set (Maybe Condition, o)
rrs -> F ([String] -> FailedProperty o x)
-> [x] -> IO (Maybe ([String] -> FailedProperty o x))
go2 F ([String] -> FailedProperty o x)
forall x. F x
Refuted [x]
xs
| Bool
otherwise -> Maybe ([String] -> FailedProperty o x)
-> IO (Maybe ([String] -> FailedProperty o x))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (([String] -> FailedProperty o x)
-> Maybe ([String] -> FailedProperty o x)
forall a. a -> Maybe a
Just [String] -> FailedProperty o x
ce)
go2 (Failing [String] -> FailedProperty o x
cf) [] = Maybe ([String] -> FailedProperty o x)
-> IO (Maybe ([String] -> FailedProperty o x))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (([String] -> FailedProperty o x)
-> Maybe ([String] -> FailedProperty o x)
forall a. a -> Maybe a
Just [String] -> FailedProperty o x
cf)
go2 F ([String] -> FailedProperty o x)
_ [] = Maybe ([String] -> FailedProperty o x)
-> IO (Maybe ([String] -> FailedProperty o x))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ([String] -> FailedProperty o x)
forall a. Maybe a
Nothing
toCE :: x
-> Set (Maybe Condition, o)
-> Set (Maybe Condition, o)
-> [String]
-> FailedProperty o x
toCE x
x Set (Maybe Condition, o)
lrs Set (Maybe Condition, o)
rrs [String]
args = CounterExample
{ failingSeed :: x
failingSeed = x
x
, failingArgs :: [String]
failingArgs = [String]
args
, leftResults :: Set (Maybe Condition, o)
leftResults = Set (Maybe Condition, o)
lrs
, rightResults :: Set (Maybe Condition, o)
rightResults = Set (Maybe Condition, o)
rrs
}
checkWithSeeds [x]
seeds (Neg RefinementProperty o x
rp) = do
Maybe ([String] -> FailedProperty o x)
r <- [x]
-> RefinementProperty o x
-> IO (Maybe ([String] -> FailedProperty o x))
forall x o.
[x]
-> RefinementProperty o x
-> IO (Maybe ([String] -> FailedProperty o x))
checkWithSeeds [x]
seeds RefinementProperty o x
rp
Maybe ([String] -> FailedProperty o x)
-> IO (Maybe ([String] -> FailedProperty o x))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe ([String] -> FailedProperty o x)
-> IO (Maybe ([String] -> FailedProperty o x)))
-> Maybe ([String] -> FailedProperty o x)
-> IO (Maybe ([String] -> FailedProperty o x))
forall a b. (a -> b) -> a -> b
$ case Maybe ([String] -> FailedProperty o x)
r of
Just [String] -> FailedProperty o x
_ -> Maybe ([String] -> FailedProperty o x)
forall a. Maybe a
Nothing
Maybe ([String] -> FailedProperty o x)
Nothing -> ([String] -> FailedProperty o x)
-> Maybe ([String] -> FailedProperty o x)
forall a. a -> Maybe a
Just (FailedProperty o x -> [String] -> FailedProperty o x
forall a b. a -> b -> a
const FailedProperty o x
forall o x. FailedProperty o x
NoExpectedFailure)
evalSigWithSeed :: Ord o
=> Sig s o x
-> x
-> IO (Set (Maybe Condition, o))
evalSigWithSeed :: forall o s x.
Ord o =>
Sig s o x -> x -> IO (Set (Maybe Condition, o))
evalSigWithSeed Sig s o x
sig x
x = do
[(Either Condition (Maybe Condition, o), Trace)]
results <- Way
-> MemType
-> Program (WithSetupAndTeardown s ()) IO (Maybe Condition, o)
-> IO [(Either Condition (Maybe Condition, o), Trace)]
forall (n :: * -> *) pty a.
MonadDejaFu n =>
Way
-> MemType -> Program pty n a -> n [(Either Condition a, Trace)]
runSCT Way
defaultWay MemType
defaultMemType (Program (WithSetupAndTeardown s ()) IO (Maybe Condition, o)
-> IO [(Either Condition (Maybe Condition, o), Trace)])
-> Program (WithSetupAndTeardown s ()) IO (Maybe Condition, o)
-> IO [(Either Condition (Maybe Condition, o), Trace)]
forall a b. (a -> b) -> a -> b
$
Program Basic IO s
-> (s
-> Either Condition () -> Program Basic IO (Maybe Condition, o))
-> (s -> ConcIO ())
-> Program (WithSetupAndTeardown s ()) IO (Maybe Condition, o)
forall (n :: * -> *) x y a.
Program Basic n x
-> (x -> Either Condition y -> Program Basic n a)
-> (x -> Program Basic n y)
-> Program (WithSetupAndTeardown x y) n a
withSetupAndTeardown
(Sig s o x -> x -> Program Basic IO s
forall s o x. Sig s o x -> x -> ConcIO s
initialise Sig s o x
sig x
x)
(\s
s Either Condition ()
r -> do
o
o <- Sig s o x -> s -> x -> ConcIO o
forall s o x. Sig s o x -> s -> x -> ConcIO o
observe Sig s o x
sig s
s x
x
(Maybe Condition, o) -> Program Basic IO (Maybe Condition, o)
forall a. a -> Program Basic IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Condition -> Maybe Condition)
-> (() -> Maybe Condition)
-> Either Condition ()
-> Maybe Condition
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Condition -> Maybe Condition
forall a. a -> Maybe a
Just (Maybe Condition -> () -> Maybe Condition
forall a b. a -> b -> a
const Maybe Condition
forall a. Maybe a
Nothing) Either Condition ()
r, o
o))
(\s
s -> do
ThreadId
_ <- ConcIO () -> Program Basic IO (ThreadId (Program Basic IO))
forall (m :: * -> *). MonadConc m => m () -> m (ThreadId m)
fork (Sig s o x -> s -> x -> ConcIO ()
forall s o x. Sig s o x -> s -> x -> ConcIO ()
interfere Sig s o x
sig s
s x
x)
()
_ <- Sig s o x -> s -> ConcIO ()
forall s o x. Sig s o x -> s -> ConcIO ()
expression Sig s o x
sig s
s
() -> ConcIO ()
forall a. a -> Program Basic IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
Set (Maybe Condition, o) -> IO (Set (Maybe Condition, o))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set (Maybe Condition, o) -> IO (Set (Maybe Condition, o)))
-> ([(Maybe Condition, o)] -> Set (Maybe Condition, o))
-> [(Maybe Condition, o)]
-> IO (Set (Maybe Condition, o))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Maybe Condition, o)] -> Set (Maybe Condition, o)
forall a. Ord a => [a] -> Set a
S.fromList ([(Maybe Condition, o)] -> IO (Set (Maybe Condition, o)))
-> [(Maybe Condition, o)] -> IO (Set (Maybe Condition, o))
forall a b. (a -> b) -> a -> b
$ ((Either Condition (Maybe Condition, o), Trace)
-> (Maybe Condition, o))
-> [(Either Condition (Maybe Condition, o), Trace)]
-> [(Maybe Condition, o)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Right (Maybe Condition, o)
a, Trace
_) -> (Maybe Condition, o)
a) [(Either Condition (Maybe Condition, o), Trace)]
results