Home > Articles > Programming

  • Print
  • + Share This
This chapter is from the book

8.9 Repetitive Patterns

Many systems repeat the same behavior over and over. A typical example is found in communication protocols that repeat behaviors such as "if no acknowledgement, time out and resend"—lack of success requires the protocol to keep on attempting to send a message. So event patterns must be able to express repetitive behavior.

In Rapide-EPL we first express the pattern of the behavior that is repeated. Say this is a pattern, P. Each repetition is another poset that matches P. Next, we need to express how P repeats—that is, the causal or timing relationship between one poset that matches P and the next poset that matches P. It can be any of the structural relational operators. We do this by writing a prefix to P that specifies the number of repetitions and the relationship between each repetition and the next one—called the repetition profile.

So, to express a pattern consisting of repetitions of P, the syntax is:

[number of repetitions rel relational operator ] P; 

The part inside the square brackets is the repetition profile. It expresses the number of repetitions and the structural relationship between each match of P. P is the body that is being repeated.

The repetition profile can have a counter variable that counts the number of repetitions, and that counter can be used as a parameter of the pattern body—just like a for loop.3 A repetitive pattern matches a poset if the poset consists of the specified number of subposets, each matching the body, and each of the matches is related by the relational operator in the prefix. The number of repetitions can be specified in various ways: a specific number or any number. We use "*" for any number.

Example 1: Some repetitive patterns

1.   [ * rel ] Deposit
2.   [ 1..10 rel ] Deposit
3.   [ I in 1 .. 10 rel ~] Deposit(I)
4.   [ * rel ~] (Msg ?M)(Send(?M) (Ack(?M.header) or Time Out) )
5.   (Msg ?M)([ * rel ~](Send(?M) (Ack(?M.header) or Time Out) ))

Each of these examples illustrates a different feature of repetitive patterns.

The body of the first pattern matches any Deposit event. The repetition profile specifies any number (*) of matches related to one another by . So this repetitive pattern expresses "any number of Deposit events, where each event is causally related to the previous one." A matching poset must be a causally ordered chain of Deposit events.

The (*) repetition pattern has what we call maximal match semantics. This means that it will match only the chain of Deposit events that consists of the maximal number of events, not a subchain consisting of some of those events.

The second pattern dialers from the first one only in specifying exactly ten Deposit events. It uses a common range notation, 1 .. 10, to specify a finite number of matches.

The third pattern uses a repetition counter variable, I, as a parameter of the body. So, the pattern body Deposit(I) changes for each repetition. The repetitive pattern matches a poset consisting of Deposit(1), Deposit(2), . . . up to ten, with any relationship between the events. Some could be dependent and some independent.

The fourth pattern is one that is repeated an arbitrary number of times. But it illustrates some "fine points." The pattern body is

(Msg ?M)(Send(?M) (Ack(?M.header) or Time Out) ) 

which matches a poset consisting of two events, a Send(O) event with a message object, O, that binds to ?M, which causes either an Ack event with the header of O as its parameter or a Time Out event. The body can be matched repeatedly. Because ?M is declared in the body, it can be bound to a different message O on each of the matches. So the pattern matches a poset consisting of any number of pairs of events, either Send(O) Ack(O.header), or Send(O) Time Out; each pair can be dependent or independent of other pairs (the ~ relation) and can have a different message O.

The fifth pattern matches similar posets to the fourth one, except that the placeholder ?M is declared before the repetition profile. Therefore, it must be common to all the repetitions of the body. So a single binding for M must be common to all the repeated matches.

Example 2: A pattern that matches a supply chain bidding process

(RFQId ?Id, Time ?T1)(RFQ(?Id) at ?T1 
[* rel ~] (Time ?T2) Bid(RFQId is ?Id) at ?T2 where ?T2 <?T1 + Bnd); 

This example uses the RFQ and Bid actions in the supply chain example in Section 8.3.4 (Example 3). It matches the kind of electronic bidding process that might be expected in B2B activities of the electronic enterprise (see Chapter 2).

Let's look at the pattern in detail. It matches an RFQ event with an ?Id that happens at time ?T1 and a poset of Bid events that are caused by the RFQ event. There can be any number (*) of Bid events, in any relation (~) to one another, provided they all occur within a time bound, Bnd, of the RFQ event. The Bid events must all contain the ?Id of the RFQ event.

So this pattern "picks out" from the global event cloud all the Bid events in response to an RFQ that happen within a time limit.

  • + Share This
  • 🔖 Save To Your Account