dtmc-0.2.0.0: test/Dtmc/Analysis/EventSpec.hs
module Dtmc.Analysis.EventSpec (
spec,
) where
import Dtmc.Analysis.Event (
DiscreteEvent (..),
includesInfiniteOutcome,
matches,
)
import Numeric.Natural (
Natural,
)
import Test.Hspec (
Spec,
describe,
it,
shouldBe,
)
import Test.Hspec.QuickCheck (
prop,
)
import Test.QuickCheck (
NonNegative (..),
property,
)
asNatural :: NonNegative Integer -> Natural
asNatural (NonNegative value) = fromInteger value
spec :: Spec
spec = do
describe "matches" $ do
it "implements every comparison at and around its threshold" $ do
let values = [2, 3, 4]
map (matches (EqualTo 3)) values
`shouldBe` [False, True, False]
map (matches (LessThan 3)) values
`shouldBe` [True, False, False]
map (matches (AtMost 3)) values
`shouldBe` [True, True, False]
map (matches (GreaterThan 3)) values
`shouldBe` [False, False, True]
map (matches (AtLeast 3)) values
`shouldBe` [False, True, True]
it "has the structural zero-threshold boundaries" $ do
matches (LessThan 0) 0 `shouldBe` False
matches (AtMost 0) 0 `shouldBe` True
matches (GreaterThan 0) 0 `shouldBe` False
matches (AtLeast 0) 0 `shouldBe` True
prop "AtMost n is LessThan (n + 1)" $ \rawThreshold rawValue ->
let threshold = asNatural rawThreshold
value = asNatural rawValue
in matches (AtMost threshold) value
== matches (LessThan (threshold + 1)) value
prop "AtLeast (n + 1) is GreaterThan n" $ \rawThreshold rawValue ->
let threshold = asNatural rawThreshold
value = asNatural rawValue
in matches (AtLeast (threshold + 1)) value
== matches (GreaterThan threshold) value
prop "upper and lower complements partition every finite value" $
\rawThreshold rawValue ->
let threshold = asNatural rawThreshold
value = asNatural rawValue
in property $
and
[ matches (GreaterThan threshold) value
/= matches (AtMost threshold) value
, matches (AtLeast threshold) value
/= matches (LessThan threshold) value
]
describe "includesInfiniteOutcome" $ do
it "includes infinity exactly in upper-tail events" $ do
map
includesInfiniteOutcome
[ EqualTo 3
, LessThan 3
, AtMost 3
, GreaterThan 3
, AtLeast 3
]
`shouldBe` [False, False, False, True, True]
prop "is independent of the finite threshold" $ \rawThreshold ->
let threshold = asNatural rawThreshold
in property $
and
[ not (includesInfiniteOutcome (EqualTo threshold))
, not (includesInfiniteOutcome (LessThan threshold))
, not (includesInfiniteOutcome (AtMost threshold))
, includesInfiniteOutcome (GreaterThan threshold)
, includesInfiniteOutcome (AtLeast threshold)
]