Wednesday, January 26, 2011

How to Catch a Bad Guy with 3 Lines of Code

Every rule registered in the rules engine's repository has a target. The target simply names the type of object the rule applies to. When an event comes in, the rules engine tries to match the event type to a rule target. If the targets match, the engine invokes the Ctrl interpreter and passes the event itself into the interpreter as the evaluation context for the rule's statement.

In the suspicious-circling-vehicle-detection-scenario, video analytics are applied to a video stream to generate an event of type "A" each time a red vehicle moves through the camera's region of interest in a specific direction. The event stream generated from this configuration is then fed to the rules engine.

Given such an event stream, a rule whose target is "A", and the following 3-line Ctrl statement, can be setup to detect the circling vehicle:
var events = 
  (this.time - 10m <= lookup.events.type("A").time)
if (events.size >= 4) {
  takeAction('Dispatch Patrol Car')
}
In plain English the statement roughly translates to: "if event A occurred 4 or more times in the last 10 minutes, take action, dispatch patrol car."

Breaking down the statement:

Variable Declaration
var events = 
  (this.time - 10m <= lookup.events.type("A").time)
A variable declaration, var events =, declares a variable to store a value. The Ctrl is not a strongly typed language. The interpreter automatically converts a var into the appropriate type, based on the expression to the right of the assignment. The type of value assigned to the variable in this case is an array of event.

Time Roll Expression
this.time - 10m
The event that triggers a rule is refered to in the Ctrl as "this", a special keyword. Each event has a "time" property, a timestamp, which the expression refers to as "this.time". The expression rolls back the timestamp value 10 minutes by appending - 10m, to complete the expression. In the Ctrl expressions like this one are called time roll expressions. Time roll expressions evaluate to date-time values that are calculated relative to the date-time of an incoming event. Date-time values may be rolled back or forward by seconds, minutes, hours, days, or months.

Lookup Expression
lookup.events.type("A").time
A lookup expression that resolves to an array of event, these expressions refer to persistent data. Lookup expressions reflect on the database schema and drill down into record sets (and sub-sets) using the dot "." operator. A filter, type("A"), further qualifies a lookup by narrowing down the result set to events whose type property is "A".
(this.time - 10m <= lookup.events.type("A").time)
In full form, the expression above resolves to an array of events of type "A" whose timestamp value is greater than or equal to 10 minutes prior to the timestamp of the incoming event.

If Statement

The array size check guarantees that at least 4 matching events are fetched by the lookup:
if (events.size >= 4) {
  ...
}
Rule Action

The rule "triggers" if the statement above evaluates true, and the action inside the body of the if statement executes:
takeAction('Dispatch Patrol Car')
Under normal circumstances, the suspicious vehicle would trigger the rule in real-time upon completing it's fifth circle around the block. Five times around the block is very suspicious behavior. If all goes well, the patrol car dispatched would confront nothing more menacing than a lost tourist. Otherwise, 3 lines of Ctrl code is all it takes to catch a bad guy.

No comments:

Post a Comment