Manual for the CEP Pattern Recognizer and Compiler

This is the companion piece for the paper "Poster: Testing Complex Event Patterns", Paweł Maślanka, Bartosz Zieliński (in press)

Requirements

The code was tested only with SWI Prolog (it is possible it may not work with other Prolog environments as it uses some non-standard libraries. Also module systems differ between Prolog interpreters).

The execution of the code should not depend on the operating system (it was tested on MacOS X and Windows 10) as it does not use any operating system specific libraries.

Description of files (modules)

event_types.pl

The module event_types defines two important functors: def_event_type/1 and def_event_types/1 which accept as a single argument either, respectively, a single declaration of an event type or a list of such declarations. The functors assert associated definitions of ref/3 and event_type/2 functors (also exported by the module) The role of the generated functors is explained below. Finally the module also defines functors event_time/2 (returning timestamp of an event), and update_time/4 which is used by generated automaton and not by the user.

Recall that events are represented as prolog terms of the form

⟨event type⟩(⟨attr_value₁⟩, ⟨attr_value₂⟩, …)

where ⟨event type⟩ plays the role of functor, and arguments are the event’s attributes. Event schema is a list of terms of the form

⟨event_type⟩(⟨attr_name₁⟩, ⟨attr_name₂⟩, …)

with no two terms with the same functor. Declaration such as the one above means that events of type ⟨event_type⟩ have attributes with names ⟨attr_name₁⟩, ⟨attr_name₂⟩, ….. Event

⟨event type⟩(⟨attr_value₁⟩, ⟨attr_value₂⟩, …)

has type ⟨event type⟩ and its argument of name ⟨attr_nameᵢ⟩ has value ⟨attr_nameᵢ⟩ for i∈{1, 2, …}.

If X is an event with an attribute a then our pattern language we refer to the value of this attribute as ref(X, a). During compilation of patterns such terms are replaced by fresh variables (say Y for the sake of example) and additional goals of the form ref(X, a, Y) are added. The goal ref(X, a, Y) is satisfied when the attribute a of event X has value Y.

To check the type of an event one can use predicate event_type/2: The goal

event_type(⟨event⟩, ⟨type⟩)

is satisfied when ⟨event⟩ has type ⟨type⟩.

so_automaton.pl

This module defines a runtime for an automaton recognizing "skipping" patterns on lists. To define an automaton (or rather a family of automatons) itself, a user needs to provide definition for the following five predicates ( the first argument of the first predicate is an identifier which distinguishes between distinct, simultanously defined automatons):

To run the automaton use match_list/3 which is the sole functor exported by module so_automaton. More precisely, the goal

match_list(Id, L, Out)

is satisfied iff the automaton identified by Id recognizes a list L and Out is a bitmap (a list of 0's and 1's) of the same length as L and such that it has 1's at the positions corresponding to the positions in L of events actually matched by the automaton (consumed in ordinary transitions) and 0's at positions corresponding to events which were skipped.

skip_pattern_syntax.pl

Module skip_pattern_syntax exports, aside from binary operators or and then which are used in the patterns (the pattern language is almost the same as described in the paper, the main difference is that instead X.a in order to refer to an attribute a of an event X we write Ref(X, a)), also some predicates which check the properties of patterns and convert patterns. Below we give a list:

Note that while predicates pattern_binds/2, closed/2, and is_unique_pattern/1 do not make any assumptions about how the event variables are represented in the pattern passed as an argument (actual Prolog variables or any other terms, it does not matter), but make_pattern_unique/2 requires for correct execution that the pattern passed as a first argument has event variables represented by actual Prolog variables (and the resulting pattern bound to the second argument represents event variables as Prolog variables as well). This is not checked in the goal, so it may lead to difficult to find errors.

skip_pattern_compiler.pl

Module skip_pattern_compiler defines predicates which compile patterns into automatons (described earlier). The module exports two predicates:

shop_example.pl

This file contains examples from the paper related to RFID augmented shop. To run the examples (as it is explained in the next section) one needs to simply consult this file into Prolog interpreter (it loads all the other files as modules), and then give appropriate commands which answer questions about aspects of the system.

The file first defines all used event types. Next, it defines predicate pattern/2 which stores some predefined patterns to try out. The first argument is the identifier, the second is the pattern.

How to run examples from shop_example.pl

In order to run the examples from the paper first cd into the folder with Prolog files and run the interpreter with the command (it also loads shop_example.pl file):

swipl shop_example.pl

First, let us check if the predicates ref/3 and event_type/2 associated with event types declarations provided in shop_example.pl were correctly asserted:

  event_type(out(1, 10), T).

should bind T=out.

ref(out(1, 10),time,X).

should bind X=10.

Let us now symbollically execute the pattern similar to the one in Equation 1 in the pape. This pattern is available as pattern(1, P). We first compile it with

  pattern(1, P), assert_regular(1, P).

Then we can explore (on backtracking) various strings of events matched by this pattern with the following command:

length(L, N), match_list(1, L, B).