Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data Events a
- eventsFromList :: [(Time, a)] -> Events a
- eventsFromListUpToTime :: Time -> [(Time, a)] -> Events a
- eventsToList :: Events a -> [(Time, a)]
- eventsToListWithId :: Events a -> [E a]
- selectEvents :: (a -> Maybe b) -> Events a -> Events b
- primitiveTransformEvents :: ([E a] -> [E b]) -> Events a -> Events b
- data TS = TS !Time !Int
- data E a = E !TS a
- data Signal a = Signal a [E a]
- mergeSignals :: Signal (a -> b) -> Signal a -> Signal b
- eventsInvariant :: Events a -> Bool
- signalInvariant :: Signal a -> Bool
- fromChangeEvents :: a -> Events a -> Signal a
- toChangeEvents :: Signal a -> Events a
- fromEvents :: Events a -> Signal (Maybe a)
- fromEventsWith :: a -> Events a -> Signal a
- signalProperty :: Int -> (a -> String) -> (a -> Bool) -> Signal a -> Property
- truncateAt :: Time -> Signal a -> Signal a
- stable :: Signal a -> Signal a
- nub :: Eq a => Signal a -> Signal a
- nubBy :: (a -> a -> Bool) -> Signal a -> Signal a
- linger :: DiffTime -> (a -> Bool) -> Signal a -> Signal Bool
- timeout :: DiffTime -> (a -> Bool) -> Signal a -> Signal Bool
- until :: (a -> Bool) -> (a -> Bool) -> Signal a -> Signal Bool
- difference :: (a -> a -> b) -> Signal a -> Signal (Maybe b)
- scanl :: (b -> a -> b) -> b -> Signal a -> Signal b
- always :: TS -> (b -> Bool) -> Signal b -> Bool
- eventually :: TS -> (b -> Bool) -> Signal b -> Bool
- keyedTimeout :: forall a b. Ord b => DiffTime -> (a -> Set b) -> Signal a -> Signal (Set b)
- keyedLinger :: forall a b. Ord b => DiffTime -> (a -> Set b) -> Signal a -> Signal (Set b)
- keyedUntil :: forall a b. Ord b => (a -> Set b) -> (a -> Set b) -> (a -> Bool) -> Signal a -> Signal (Set b)
Events
A time-ordered trace of discrete events that occur at specific times.
This corresponds for example to a trace of events or observations from a simulation.
Instances
Functor Events Source # | |
Foldable Events Source # | |
Defined in Ouroboros.Network.Testing.Data.Signal fold :: Monoid m => Events m -> m # foldMap :: Monoid m => (a -> m) -> Events a -> m # foldMap' :: Monoid m => (a -> m) -> Events a -> m # foldr :: (a -> b -> b) -> b -> Events a -> b # foldr' :: (a -> b -> b) -> b -> Events a -> b # foldl :: (b -> a -> b) -> b -> Events a -> b # foldl' :: (b -> a -> b) -> b -> Events a -> b # foldr1 :: (a -> a -> a) -> Events a -> a # foldl1 :: (a -> a -> a) -> Events a -> a # elem :: Eq a => a -> Events a -> Bool # maximum :: Ord a => Events a -> a # minimum :: Ord a => Events a -> a # | |
Show a => Show (Events a) Source # | |
eventsFromListUpToTime :: Time -> [(Time, a)] -> Events a Source #
Construct Events
from a time series.
The time series is truncated at (but not including) the given time. This is necessary to check properties over finite prefixes of infinite time series.
eventsToList :: Events a -> [(Time, a)] Source #
eventsToListWithId :: Events a -> [E a] Source #
Low level access
Instances
Functor E Source # | |
Foldable E Source # | |
Defined in Ouroboros.Network.Testing.Data.Signal fold :: Monoid m => E m -> m # foldMap :: Monoid m => (a -> m) -> E a -> m # foldMap' :: Monoid m => (a -> m) -> E a -> m # foldr :: (a -> b -> b) -> b -> E a -> b # foldr' :: (a -> b -> b) -> b -> E a -> b # foldl :: (b -> a -> b) -> b -> E a -> b # foldl' :: (b -> a -> b) -> b -> E a -> b # foldr1 :: (a -> a -> a) -> E a -> a # foldl1 :: (a -> a -> a) -> E a -> a # elem :: Eq a => a -> E a -> Bool # maximum :: Ord a => E a -> a # | |
Show a => Show (E a) Source # | |
Signals
A signal is a time-varying value. It has a value at all times. It changes value at discrete times, i.e. it is not continuous.
Signal | |
|
Invariants
eventsInvariant :: Events a -> Bool Source #
Events are all ordered by time and causal order
signalInvariant :: Signal a -> Bool Source #
Signal time changing events are all ordered by timestamp and causal order
Construction and conversion
fromChangeEvents :: a -> Events a -> Signal a Source #
Construct a Signal
from an initial value and a time series of events
that represent new values of the signal.
This only makes sense for events that sample a single time-varying value.
toChangeEvents :: Signal a -> Events a Source #
Convert a Signal
into a time series of events when the signal value
changes.
fromEvents :: Events a -> Signal (Maybe a) Source #
Construct a Signal
that represents a time series of discrete events. The
signal is Just
the event value at the time of the event, and is Nothing
at all other times.
Note that this signal "instantaneously" takes the event value and reverts
to Nothing
before time moves on. Therefore this kind of signal is not
"stable" in the sense of stableSignal
.
fromEventsWith :: a -> Events a -> Signal a Source #
Like fromEvents
but it is using the given value a
instead of 'Nothing.
It is equivalent to `a -> fmap (fromMaybe a) . fromEvents`
QuickCheck
signalProperty :: Int -> (a -> String) -> (a -> Bool) -> Signal a -> Property Source #
Check a property over a Signal
. The property should be true at all times.
On failure it shows the n
most recent signal values.
Simple signal transformations
stable :: Signal a -> Signal a Source #
A signal can change value more than once at a single point of time.
Sometimes we are interested only in the final "stable" value of the signal before time moves on. This function discards the other values, keeping only the final value at each time.
nub :: Eq a => Signal a -> Signal a Source #
Sometimes the way a signal is constructed leads to duplicate signal values
which can slow down signal processing. This tidies up the signal by
eliminating the duplicates. This does not change the meaning (provided the
Eq
instance is true equality).
Temporal operations
linger :: DiffTime -> (a -> Bool) -> Signal a -> Signal Bool Source #
A linger signal remains True
for the given time after the underlying
signal is True
.
Make a timeout signal, based on observing an underlying signal.
The timeout signal takes the value True
when the timeout has occurred, and
False
otherwise.
The timeout is controlled by an "arming" function on the underlying signal.
The arming function should return True
when the timeout should be started,
and it returns the time to wait before the timeout fires. The arming function
should return False
when the timeout should be cancelled or not started.
The output signal becomes True
when the arming function has been
continuously active (i.e. returning True
) for the given duration.
always :: TS -> (b -> Bool) -> Signal b -> Bool Source #
Starting on a given event does the predicate holds for all the trace.
If there's no events after the given time, return True
eventually :: TS -> (b -> Bool) -> Signal b -> Bool Source #
Starting on a given event does the predicate eventually holds.
If there's no events after the given time, return True
Set-based temporal operations
:: forall a b. Ord b | |
=> DiffTime | |
-> (a -> Set b) | The timeout arming set signal |
-> Signal a | |
-> Signal (Set b) |
Make a signal that says if a given event longed at least a certain time (timeout), based on observing an underlying signal.
The underlying signal is scrutinised with the provided "timeout arming" function that tells us if the signal value is interesting to track. If it is, we arm it with a timeout and see, if until the timeout goes off there's no other event to arm. If any activity occurs again before the previous timeout, then the timeout is reset with the new event and the other one is discarded.
Example: We have a signal that tracks if a button is pressed or not, i.e.
it's true if it is pressed and false otherwise. Then `timeout 5 id s` will
return a signal that checks whether the button is left pressed for at least
5 seconds. So the output signal becomes true if the button remains pressed
for 5 continuous seconds and is false if the buttom is released before 5
seconds. However, if we wanted to analyse 3 buttons, we could combine the
3 button signals, but we still wouldn't be able to get a signal that
would give us at what times each button was left pressed more than a given
number of time units. We could only check if either any, all or a
particular configuration of them as pressed for a duration. If we wanted to
be able to know exactly which buttons were left pressed we would need to
have a timeout for each button individually. That's the extra expressive
power that keyedTimeout
offers.
offers
This function is often used in property tests with a negative predicate. E.g. The system doesn't stay in a wrong state more than 5 seconds = `all Set.null $ keyedTimeout 5s wrongState`
:: forall a b. Ord b | |
=> DiffTime | |
-> (a -> Set b) | The activity set signal |
-> Signal a | |
-> Signal (Set b) |
Make a signal that keeps track of recent activity, based on observing an underlying signal.
The underlying signal is scrutinised with the provided "activity interest" function that tells us if the signal value is activity of interest to track. If it is, the given key is entered into the result signal set for the given time duration. If the same activity occurs again before the duration expires then the expiry will be extended to the new deadline (it is not cumulative). The key will be removed from the result signal set when it expires.
Example: We cannot directly verify successful promotions due to certain constraints (network attenuations), but we can ensure that the system takes all promotion opportunities. To achieve this, we need to discard peers that we have attempted to connect during the backoff period. For every failure event in the input signal, we want to produce a signal that includes those events for a specified duration. This allows us to then combine the trace with all promotion opportunities and all the failed attempts and discard those. This allow us to correctly identify valid promotion opportunities.