Temporal Reasoning

Temporal reasoning is another requirement of any CEP system. As discussed previously, one of the distinguishing characteristics of events is their strong temporal relationships.

Temporal reasoning is an extensive field of research, from its roots on Temporal Modal Logic to its more practical applications in business systems. There are hundreds of papers and thesis written and approches are described for several applications. Drools once more takes a pragmatic and simple approach based on several sources, but specially worth noting the following papers:

[ALLEN81] Allen, J.F.. An Interval-based Representation of Temporal Knowledge. 1981.

[ALLEN83] Allen, J.F.. Maintaining knowledge about temporal intervals. 1983.

[BENNE00] Bennet, Brandon and Galton, Antony P.. A Unifying Semantics for Time and Events. 2005.

[YONEK05] Yoneki, Eiko and Bacon, Jean. Unified Semantics for Event Correlation Over Time and Space in Hybrid Network Environments. 2005.

Drools implements the Interval-based Time Event Semantics described by Allen, and represents Point-in-Time Events as Interval-based evens with duration 0 (zero).

Temporal Operators

Drools implements all 13 operators defined by Allen and also their logical complement (negation). This section details each of the operators and their parameters.

After

The after evaluator correlates two events and matches when the temporal distance from the current event to the event being correlated belongs to the distance range declared for the operator.

Lets look at an example:

$eventA : EventA( this after[ 3m30s, 4m ] $eventB ) 

The previous pattern will match if and only if the temporal distance between the time when $eventB finished and the time when $eventA started is between ( 3 minutes and 30 seconds ) and ( 4 minutes ). In other words:

 3m30s <= $eventA.startTimestamp - $eventB.endTimeStamp <= 4m 

The temporal distance interval for the after operator is optional:

  • If two values are defined (like in the example bellow), the interval starts on the first value and finishes on the second.

  • If only one value is defined, the interval starts on the value and finishes on the positive infinity.

  • If no value is defined, it is assumed that the initial value is 1ms and the final value is the positive infinity.

Tip

It is possible to define negative distances for this operator. Example:

$eventA : EventA( this after[ -3m30s, -2m ] $eventB ) 

Note

If the first value is greater than the second value, the engine automatically reverses them, as there is no reason to have the first value greater than the second value. Example: the following two patterns are considered to have the same semantics:

$eventA : EventA( this after[ -3m30s, -2m ] $eventB ) 
$eventA : EventA( this after[ -2m, -3m30s ] $eventB ) 

Before

The before evaluator correlates two events and matches when the temporal distance from the event being correlated to the current correlated belongs to the distance range declared for the operator.

Lets look at an example:

$eventA : EventA( this before[ 3m30s, 4m ] $eventB ) 

The previous pattern will match if and only if the temporal distance between the time when $eventA finished and the time when $eventB started is between ( 3 minutes and 30 seconds ) and ( 4 minutes ). In other words:

 3m30s <= $eventB.startTimestamp - $eventA.endTimeStamp <= 4m 

The temporal distance interval for the before operator is optional:

  • If two values are defined (like in the example bellow), the interval starts on the first value and finishes on the second.

  • If only one value is defined, then the interval starts on the value and finishes on the positive infinity.

  • If no value is defined, it is assumed that the initial value is 1ms and the final value is the positive infinity.

Tip

It is possible to define negative distances for this operator. Example:

$eventA : EventA( this before[ -3m30s, -2m ] $eventB ) 

Note

If the first value is greater than the second value, the engine automatically reverses them, as there is no reason to have the first value greater than the second value. Example: the following two patterns are considered to have the same semantics:

$eventA : EventA( this before[ -3m30s, -2m ] $eventB ) 
$eventA : EventA( this before[ -2m, -3m30s ] $eventB ) 

Coincides

The coincides evaluator correlates two events and matches when both happen at the same time. Optionally, the evaluator accept thresholds for the distance between events' start and finish timestamps.

Lets look at an example:

$eventA : EventA( this coincides $eventB ) 

The previous pattern will match if and only if the start timestamps of both $eventA and $eventB are the same AND the end timestamp of both $eventA and $eventB also are the same.

Optionally, this operator accepts one or two parameters. These parameters are the thresholds for the distance between matching timestamps.

  • If only one paratemer is given, it is used for both start and end timestamps.

  • If two parameters are given, then the first is used as a threshold for the start timestamp and the second one is used as a threshold for the end timestamp.

In other words:

$eventA : EventA( this coincides[15s, 10s] $eventB ) 

Above pattern will match if and only if:

abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 15s && 
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 10s 

Caution

It makes no sense to use negative interval values for the parameters and the engine will raise an error if that happens.

During

The during evaluator correlates two events and matches when the current event happens during the occurrence of the event being correlated.

Lets look at an example:

$eventA : EventA( this during $eventB ) 

The previous pattern will match if and only if the $eventA starts after $eventB starts and finishes before $eventB finishes.

In other words:

$eventB.startTimestamp < $eventA.startTimestamp <= $eventA.endTimestamp < $eventB.endTimestamp 

The during operator accepts 1, 2 or 4 optional parameters as follow:

  • If one value is defined, this will be the maximum distance between the start timestamp of both event and the maximum distance between the end timestamp of both events in order to operator match. Example:

    $eventA : EventA( this during[ 5s ] $eventB )

    Will match if and only if:

    0 < $eventA.startTimestamp - $eventB.startTimestamp <= 5s && 
    0 < $eventB.endTimestamp - $eventA.endTimestamp <= 5s
  • If two values are defined, the first value will be the minimum distance between the timestamps of both events, while the second value will be the maximum distance between the timestamps of both events. Example:

    $eventA : EventA( this during[ 5s, 10s ] $eventB )

    Will match if and only if:

    5s <= $eventA.startTimestamp - $eventB.startTimestamp <= 10s && 
    5s <= $eventB.endTimestamp - $eventA.endTimestamp <= 10s
  • If four values are defined, the first two values will be the minimum and maximum distances between the start timestamp of both events, while the last two values will be the minimum and maximum distances between the end timestamp of both events. Example:

    $eventA : EventA( this during[ 2s, 6s, 4s, 10s ] $eventB )

    Will match if and only if:

    2s <= $eventA.startTimestamp - $eventB.startTimestamp <= 6s && 
    4s <= $eventB.endTimestamp - $eventA.endTimestamp <= 10s

Finishes

The finishes evaluator correlates two events and matches when the current event's start timestamp happens after the correlated event's start timestamp, but both end timestamps occur at the same time.

Lets look at an example:

$eventA : EventA( this finishes $eventB ) 

The previous pattern will match if and only if the $eventA starts after $eventB starts and finishes at the same time $eventB finishes.

In other words:

$eventB.startTimestamp < $eventA.startTimestamp && 
$eventA.endTimestamp == $eventB.endTimestamp 

The finishes evaluator accepts one optional parameter. If it is defined, it determines the maximum distance between the end timestamp of both events in order for the operator to match. Example:

$eventA : EventA( this finishes[ 5s ] $eventB ) 

Will match if and only if:

$eventB.startTimestamp < $eventA.startTimestamp && 
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 5s 

Caution

It makes no sense to use a negative interval value for the parameter and the engine will raise an exception if that happens.

Finished By

The finishedby evaluator correlates two events and matches when the current event start timestamp happens before the correlated event start timestamp, but both end timestamps occur at the same time. This is the symmetrical opposite of finishes evaluator.

Lets look at an example:

$eventA : EventA( this finishedby $eventB ) 

The previous pattern will match if and only if the $eventA starts before $eventB starts and finishes at the same time $eventB finishes.

In other words:

$eventA.startTimestamp < $eventB.startTimestamp && 
$eventA.endTimestamp == $eventB.endTimestamp 

The finishedby evaluator accepts one optional parameter. If it is defined, it determines the maximum distance between the end timestamp of both events in order for the operator to match. Example:

$eventA : EventA( this finishedby[ 5s ] $eventB ) 

Will match if and only if:

$eventA.startTimestamp < $eventB.startTimestamp && 
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 5s 

Caution

It makes no sense to use a negative interval value for the parameter and the engine will raise an exception if that happens.

Includes

The includes evaluator correlates two events and matches when the event being correlated happens during the current event. It is the symmetrical opposite of during evaluator.

Lets look at an example:

$eventA : EventA( this includes $eventB ) 

The previous pattern will match if and only if the $eventB starts after $eventA starts and finishes before $eventA finishes.

In other words:

$eventA.startTimestamp < $eventB.startTimestamp <= $eventB.endTimestamp < $eventA.endTimestamp 

The includes operator accepts 1, 2 or 4 optional parameters as follow:

  • If one value is defined, this will be the maximum distance between the start timestamp of both event and the maximum distance between the end timestamp of both events in order to operator match. Example:

    $eventA : EventA( this includes[ 5s ] $eventB )

    Will match if and only if:

    0 < $eventB.startTimestamp - $eventA.startTimestamp <= 5s && 
    0 < $eventA.endTimestamp - $eventB.endTimestamp <= 5s
  • If two values are defined, the first value will be the minimum distance between the timestamps of both events, while the second value will be the maximum distance between the timestamps of both events. Example:

    $eventA : EventA( this includes[ 5s, 10s ] $eventB )

    Will match if and only if:

    5s <= $eventB.startTimestamp - $eventA.startTimestamp <= 10s && 
    5s <= $eventA.endTimestamp - $eventB.endTimestamp <= 10s
  • If four values are defined, the first two values will be the minimum and maximum distances between the start timestamp of both events, while the last two values will be the minimum and maximum distances between the end timestamp of both events. Example:

    $eventA : EventA( this includes[ 2s, 6s, 4s, 10s ] $eventB )

    Will match if and only if:

    2s <= $eventB.startTimestamp - $eventA.startTimestamp <= 6s && 
    4s <= $eventA.endTimestamp - $eventB.endTimestamp <= 10s 

Meets

The meets evaluator correlates two events and matches when the current event's end timestamp happens at the same time as the correlated event's start timestamp.

Lets look at an example:

$eventA : EventA( this meets $eventB ) 

The previous pattern will match if and only if the $eventA finishes at the same time $eventB starts.

In other words:

abs( $eventB.startTimestamp - $eventA.endTimestamp ) == 0 

The meets evaluator accepts one optional parameter. If it is defined, it determines the maximum distance between the end timestamp of current event and the start timestamp of the correlated event in order for the operator to match. Example:

$eventA : EventA( this meets[ 5s ] $eventB ) 

Will match if and only if:

abs( $eventB.startTimestamp - $eventA.endTimestamp) <= 5s 

Caution

It makes no sense to use a negative interval value for the parameter and the engine will raise an exception if that happens.

Met By

The metby evaluator correlates two events and matches when the current event's start timestamp happens at the same time as the correlated event's end timestamp.

Lets look at an example:

$eventA : EventA( this metby $eventB ) 

The previous pattern will match if and only if the $eventA starts at the same time $eventB finishes.

In other words:

abs( $eventA.startTimestamp - $eventB.endTimestamp ) == 0 

The metby evaluator accepts one optional parameter. If it is defined, it determines the maximum distance between the end timestamp of the correlated event and the start timestamp of the current event in order for the operator to match. Example:

$eventA : EventA( this metby[ 5s ] $eventB ) 

Will match if and only if:

abs( $eventA.startTimestamp - $eventB.endTimestamp) <= 5s 

Caution

It makes no sense to use a negative interval value for the parameter and the engine will raise an exception if that happens.

Overlaps

The overlaps evaluator correlates two events and matches when the current event starts before the correlated event starts and finishes after the correlated event starts, but before the correlated event finishes. In other words, both events have an overlapping period.

Lets look at an example:

$eventA : EventA( this overlaps $eventB ) 

The previous pattern will match if and only if:

$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp 

The overlaps operator accepts 1 or 2 optional parameters as follow:

  • If one parameter is defined, this will be the maximum distance between the start timestamp of the correlated event and the end timestamp of the current event. Example:

    $eventA : EventA( this overlaps[ 5s ] $eventB )

    Will match if and only if:

    $eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp && 
    0 <= $eventA.endTimestamp - $eventB.startTimestamp <= 5s
  • If two values are defined, the first value will be the minimum distance and the second value will be the maximum distance between the start timestamp of the correlated event and the end timestamp of the current event. Example:

    $eventA : EventA( this overlaps[ 5s, 10s ] $eventB )

    Will match if and only if:

    $eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp && 
    5s <= $eventA.endTimestamp - $eventB.startTimestamp <= 10s 

Overlapped By

The overlappedby evaluator correlates two events and matches when the correlated event starts before the current event starts and finishes after the current event starts, but before the current event finishes. In other words, both events have an overlapping period.

Lets look at an example:

$eventA : EventA( this overlappedby $eventB ) 

The previous pattern will match if and only if:

$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp 

The overlappedby operator accepts 1 or 2 optional parameters as follow:

  • If one parameter is defined, this will be the maximum distance between the start timestamp of the current event and the end timestamp of the correlated event. Example:

    $eventA : EventA( this overlappedby[ 5s ] $eventB )

    Will match if and only if:

    $eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp && 
    0 <= $eventB.endTimestamp - $eventA.startTimestamp <= 5s
  • If two values are defined, the first value will be the minimum distance and the second value will be the maximum distance between the start timestamp of the current event and the end timestamp of the correlated event. Example:

    $eventA : EventA( this overlappedby[ 5s, 10s ] $eventB )

    Will match if and only if:

    $eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp && 
    5s <= $eventB.endTimestamp - $eventA.startTimestamp <= 10s

Starts

The starts evaluator correlates two events and matches when the current event's end timestamp happens before the correlated event's end timestamp, but both start timestamps occur at the same time.

Lets look at an example:

$eventA : EventA( this starts $eventB ) 

The previous pattern will match if and only if the $eventA finishes before $eventB finishes and starts at the same time $eventB starts.

In other words:

$eventA.startTimestamp == $eventB.startTimestamp && 
$eventA.endTimestamp < $eventB.endTimestamp 

The starts evaluator accepts one optional parameter. If it is defined, it determines the maximum distance between the start timestamp of both events in order for the operator to match. Example:

$eventA : EventA( this starts[ 5s ] $eventB ) 

Will match if and only if:

abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s && 
$eventA.endTimestamp < $eventB.endTimestamp 

Caution

It makes no sense to use a negative interval value for the parameter and the engine will raise an exception if that happens.

Started By

The startedby evaluator correlates two events and matches when the correlating event's end timestamp happens before the current event's end timestamp, but both start timestamps occur at the same time. Lets look at an example:

$eventA : EventA( this startedby $eventB ) 

The previous pattern will match if and only if the $eventB finishes before $eventA finishes and starts at the same time $eventB starts.

In other words:

$eventA.startTimestamp == $eventB.startTimestamp && 
$eventA.endTimestamp > $eventB.endTimestamp 

The startedby evaluator accepts one optional parameter. If it is defined, it determines the maximum distance between the start timestamp of both events in order for the operator to match. Example:

$eventA : EventA( this starts[ 5s ] $eventB ) 

Will match if and only if:

abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s && 
$eventA.endTimestamp > $eventB.endTimestamp 

Caution

It makes no sense to use a negative interval value for the parameter and the engine will raise an exception if that happens.