Operating over past events

You can write rules that match events in the event history that is associated with the bound entity. For example, you can test that several events happened to the bound entity in a specified period before the current event.

Rule agents have read-only access to the event history associated with the bound entity. The runtime automatically manages the event history. It adds previous events to the history and removes events from the history when they are older than the event horizon. The event horizon is specified in the rule agent descriptor.

Remember: Rule agents also have read-only access to the current event. The current event is not necessarily the most recent event, as events can arrive out of order.

The event history of rule agents can be used to detect patterns, along with data from the current event and the bound entity. These patterns can be relatively simple, or can include sophisticated temporal and aggregation operators, such as the number of, and during.

For example, the following rule checks if at least three purchase events happened in the last seven days. The current purchase event that is processed in this rule is not included in the number of events returned. The condition of the rule is true if the event history already contains three purchase events.

when a purchase event occurs
if
   the number of purchase events during the last period of 7 days is at least 3
then
   print "At least 3 purchases in a week";
Warning: Expressions such as the last period of refer implicitly to the time now. The variable now might not refer to the time stamp of the event in the when <event> occurs clause. For more information, see Event processing in agents.

The following rule calculates the amount of all the purchase events. The total amount is calculated for the events that are within the event horizon for this agent.

when a purchase event occurs
if
   the total amount of all purchase events is more than 300
then
   print "Apply 10% discount on this purchase"; 
   set the loyalty status of 'the customer' to Gold; 
Tip: In cases where you want to count the historical occurrence of events that meet some criteria, use shared aggregates instead of looking for patterns in the event history. For more information, see Shared aggregates.

The following rule identifies the previous event of the zone enter type that occurred in the last 20 minutes, and explicitly names the current event LAST. Naming the current event is optional. If the current event is not named, then it can be referred to in this rule as 'this zone enter'.

when a zone enter occurs , called LAST
definitions
   set 'previous zone enter' to a zone enter during the last period of 20 minutes before LAST ;
if
   there is no zone enter
      where this zone enter is after 'previous zone enter' ,
   and the zone id of the zone of 'previous zone enter' is "ZONE001"
then
   print "Current zone enter is: " + the timestamp of LAST ;
   print "Previous zone enter is: " + the timestamp of 'previous zone enter' ;

In this rule, the definitions clause has a single variable binding.

Note: A variable binding looks similar to a local variable in Java, but it behaves differently. Variable bindings in rules query the constraints against the events in the event history.

In the definitions part, the rule defines a 'previous zone enter' variable binding that contains a collection of instances in the event history with time stamps that are not older than 20 minutes before the time stamp of the current zone enter event. When the collection contains no event that is after a previous event, the most recent event is identified. The rule then prints the time of the current event and the time of the previous event.

If no events in the event history match the constraints, then the variable binding fails and the if part is not evaluated. If the binding variable matches multiple event instances, the if part of the rule evaluates each of the matched events in turn, which can have a large impact on the amount of work the agent must do. It is not obvious that the rule contains a programming loop-like statement, but the pattern matching of the events is key to understanding how variable bindings work and how these bindings can be used to detect complex situations.

If a rule matches many events in the event history by using a variable binding that is too inclusive, you might create a collection that contains hundreds or even thousands of objects. The processing time of this rule can increase many times in this case (can be in the order of seconds, depending on the cardinality of the collection). The cardinality of a set is the number of elements of the set. For example, set A = {6, 4, 2} contains three elements; A has a cardinality of three. A rule that contains three definition bindings, for example, can cause the number of rule instances to grow faster than a linear function. How fast a collection can grow is determined by the number of definition statements and the number of matched events.

Important: The size of the event history is one of the factors that impact the performance of a rule agent the most. Looking for patterns in an event history of 1,000 events is much more expensive than looking for patterns in an event history of 20 events.

It is easy to write a rule that queries all elements of the event horizon. To reduce the list of matched events from the event history, you can add constructs to limit this number. The following constructs are listed from best to worst in terms of exclusion.

  • there is no
  • there is at least one
  • there are less than
  • set 'var' to the number of events where
  • set 'var' to all events where

For example, to limit the number of elements for the constraint to be true, a rule can include the there are less than construct.

when an online purchase occurs, called CURRENT PURCHASE
if
   there are less than 2 online purchases in online purchases
      where this online purchase is after 4 hours before CURRENT PURCHASE

If you want to use a definitions part to bind a variable to a constraint, use a count in the definition instead of creating a collection. The following rule binds the number of purchases variable to a count, and fires only if the count is one.

when an online purchase occurs, called CURRENT PURCHASE
definitions
   set 'number of purchases' to the number of online purchases in online purchases
      where this online purchase is after 4 hours before CURRENT PURCHASE
if 'number of purchases' is less than 2

When you use complex patterns in your rules, test for: true positives, false positives, true negatives, and false negatives. It is also worth testing how your rules behave when events occur out of order.