• No results found

2.11 Conclusions

3.1.2 Pattern Language

Pattern expressions define structural operations on data by mixing concrete data with meta-language expressions. The data language introduced in the previous section forms a subset of the pattern language. Thus, all expressions of the data language are also valid patterns. This section defines the meta-expressions that can be interspersed with the data. Pattern expressions are either primitive patterns or compound patterns composed from simpler ones by means of an operator. Table 3.1 gives an overview of the pattern language. The pattern expressions are divided into categories according to their functionality. The rightmost column defines pattern expression recursively. Let p denote a pattern expres- sion and let P denotes a sequence of pattern expressions [p1, ..., pn]. Let n denote an atom representing the name of a variable. More convenient infix notations are defined for se- quencing (concatenation), choice (|) and vertical composition (!) as these operators will be used regularly in the definitions that follow.

As previously stated, the data language defined in the previous section forms a subset of the pattern language: atoms are primitive pattern expressions and there is an operator to construct typed sequence patterns from a sequence of patterns and a type pattern. This entails that every data expression is also a valid pattern expression.

Pattern expressions have two fundamental interpretations: matching and instantiation. Matching is the process of recognising and deconstructing data. Instantiation is the pro- cess of creating and assembling data. Let Seq be the set of all data sequences as defined by the non-terminal seq in Figure 3.1 and let ✏ denote the empty sequence. Let A be the set of all atoms and let T seq be the set of all typed sequences as defined by tseq in Fig- ure 3.1. The set of all values is defined as V al = A [ T seq [ Seq. Let the store Sto be a set of pairs (n, v) with n 2 A and v 2 V al, each pair representing a variable binding, and let the empty store " denote the empty set. Let P tn be the set of all pattern expressions

Category Pattern Syntax Basic atom a anything ↵ variable n:p reference ref (p)

Hierarchical typed sequence ⌧ (P, p) Modifying negation !p maybe p? all all(p) ignore ign(p) Horizontal sequencing ⇠(P )or p p choice or(P )or p | p repetition p⇤ repetition > 0 p+ Two dimensional vertical ⇤(P )or p ! p vertical repetition p⇤v diagonal (p) diagonal’ 0(p)

Transformative unconditional transformation p ) p Quoting quote quote(p) i-activate i-unquote(p) quasiquote qq(p) unquote uq(p) Searching

find f ind p among p

findall f indall p among p

replaceall replaceall p among p findall nested f ind p among p in p

Table 3.1: Pattern Language has the following signature:

match : P tn⇥ Seq ⇥ Sto ! V al ⇥ Seq ⇥ Sto

A pattern expression and a data sequence are matched in the context of variable bindings that are contained in a store. Matching yields a result value, a data sequence and a store. The operational semantics is that matching may change the data sequence and the store: values might be removed from or added to the data sequence; the store may be extended with bindings created during the matching. In the following, the matching and instan- tiation semantics of selected pattern operations will be discussed informally before full formal semantics will be presented in the next section.

An atom only matches a data sequence if a syntactically equal atom is the first ele- ment of the sequence. Accordingly, matching the primitive atom pattern a with sequence

of atoms [a, b, c] and the empty store " yields result a, remaining sequence [b, c] and store ". The notation ha, [a, b, c], "i ! ha, [b, c], "i will be used to express a successful matchm with these inputs and outputs. The pattern⇠([a, b])is a composition of two atom patterns a and b using the sequence operator⇠. The operator has the semantics that the patterns in its argument list are matched with the data sequence in the order in which they appear. The in- dividual matching results are combined into a sequence. Matching this pattern with the in- puts from above is described by: h⇠([a, b]), [a, b, c], "i ! h[a, b], [c], "i. The variable oper-m ator : combines an atom representing a variable name with an arbitrary pattern expression. Its semantics is to match the pattern expression with the data sequence, return the result and to add to the store a binding from the variable name to the result. Matching a variable pattern is illustrated by the example hx:⇠([a, b]), [a, b, c], "i ! h[a, b], [c], {(x, [a, b])}im in which the atom x is the variable name. The matching semantics of typed sequences demands that the first element of the data sequence is a typed sequence. The result is con- structed from the individual matching results of the type and content parts. Accordingly, h⌧([a, x:↵], t), [⌧([a, b], t)], "i m! h⌧([a, b], t), ✏, {(x, b)} where ↵ is a pattern that matches any atom or typed sequence and t is an atom.

The instantiation semantics of patterns can be defined by an operation with the signa- ture:

instantiate : P tn⇥ Seq ⇥ Sto ! Seq

A pattern expression is instantiated in the context of a data sequence and a store. It yields an updated data sequence. The operational semantics is that the data sequence is modified by the instantiation operation. An example is the instantiation of the primitive atom pattern c with the sequence of atoms [a, b] and the empty store ". An atom is in- stantiated by adding it to the input sequence. Accordingly, the result is [a, b, c], which is expressed by the notation hc, [a, b], "i ! h[a, b, c]i. The instantiation semantics ofi the sequence operator is to instantiate the patterns in its argument list in order, with each instantiation working on the result of the previous one, as shown in the following example: h⇠([b, c]), [a], "i ! h[a, b, c]i. While the matching interpretation of variablesi is to add a name-value binding to the store, the instantiation semantics is to look up the value from the store and replace the variable with the bound value. For example, h⇠([a, x:↵]), ✏, {(x, b)}i ! h[a, b]i. Instantiating a typed sequence pattern yields the re-i sult of instantiating the type and content parts and combining them with the ⌧ operator. For example, h⌧([a], x:↵), ✏, {(x, t)}i! h[⌧([a], t)]i.i