Controlled grammar

From HandWiki

Controlled grammars[1] are a class of grammars that extend, usually, the context-free grammars with additional controls on the derivations of a sentence in the language. A number of different kinds of controlled grammars exist, the four main divisions being Indexed grammars, grammars with prescribed derivation sequences, grammars with contextual conditions on rule application, and grammars with parallelism in rule application. Because indexed grammars are so well established in the field, this article will address only the latter three kinds of controlled grammars.

Control by prescribed sequences

Grammars with prescribed sequences are grammars in which the sequence of rule application is constrained in some way. There are four different versions of prescribed sequence grammars: language controlled grammars (often called just controlled grammars), matrix grammars, vector grammars, and programmed grammars.

In the standard context-free grammar formalism, a grammar itself is viewed as a 4-tuple, [math]\displaystyle{ G = (N, T, S, P) }[/math], where N is a set of non-terminal/phrasal symbols, T is a disjoint set of terminal/word symbols, S is a specially designated start symbol chosen from N, and P is a set of production rules like [math]\displaystyle{ X \to \alpha }[/math], where X is some member of N, and [math]\displaystyle{ \alpha }[/math] is some member of [math]\displaystyle{ (N \cup T)^{*} }[/math].

Productions over such a grammar are sequences of rules in P that, when applied in order of the sequence, lead to a terminal string. That is, one can view the set of imaginable derivations in G as the set [math]\displaystyle{ \{ p_1 p_2 ... p_n : n \geq 0 \} }[/math], and the language of G as being the set of terminal strings [math]\displaystyle{ L(G) = \{ w \in T^{*} : S \Rightarrow_{p_1} ... \Rightarrow_{p_n} w \} }[/math]. Control grammars take seriously this definition of the language generated by a grammar, concretizing the set-of-derivations as an aspect of the grammar. Thus, a prescribed sequence controlled grammar is at least approximately a 5-tuple [math]\displaystyle{ G = (N, T, S, P, R) }[/math] where everything except R is the same as in a CFG, and R is an infinite set of valid derivation sequences [math]\displaystyle{ p_1 p_2 ... p_n }[/math].

The set R, due to its infinitude, is almost always (though not necessarily) described via some more convenient mechanism, such as a grammar (as in language controlled grammars), or a set of matrices or vectors (as in matrix and vector grammars). The different variations of prescribed sequence grammars thus differ by how the sequence of derivations is defined on top of the context-free base. Because matrix grammars and vector grammars are essentially special cases of language controlled grammars, examples of the former two will not be provided below.

Language controlled grammars

Language controlled grammars are grammars in which the production sequences constitute a well-defined language of arbitrary nature, usually though not necessarily regular, over a set of (again usually though not necessarily) context-free production rules. They also often have a sixth set in the grammar tuple, making it [math]\displaystyle{ G = (N, T, S, P, R, F) }[/math], where F is a set of productions that are allowed to apply vacuously. This version of language controlled grammars, ones with what is called "appearance checking", is the one henceforth.

Proof-theoretic description

We let a regularly controlled context-free grammar with appearance checking be a 6-tuple [math]\displaystyle{ G = (N, T, S, P, R, F) }[/math] where N, T, S, and P are defined as in CFGs, R is a subset of P* constituting a regular language over P, and F is some subset of P. We then define the immediately derives relation [math]\displaystyle{ \Rightarrow_{p_i} }[/math] as follows:

Given some strings x and y, both in [math]\displaystyle{ (N \cup T)^{*} }[/math], and some rule [math]\displaystyle{ p = A \to w \in P }[/math],

[math]\displaystyle{ x \Rightarrow^{ac}_{p} y }[/math]

holds if either

[math]\displaystyle{ x = x_{1}Ax_{2} }[/math] and [math]\displaystyle{ y = y_{1}wy_{2} }[/math], or
[math]\displaystyle{ x = y }[/math] and [math]\displaystyle{ p \in F }[/math]

Intuitively, this simply spells out that a rule can apply to a string if the rule's left-hand-side appears in that string, or if the rule is in the set of "vacuously applicable" rules which can "apply" to a string without changing anything. This requirement that the non-vacuously applicable rules must apply is the appearance checking aspect of such a grammar. The language for this kind of grammar is then simply set of terminal strings [math]\displaystyle{ L(G) = \{ w \in T^{*} : S \Rightarrow^{ac}_{p_1} w_{1} \Rightarrow^{ac}_{p_2} w_{2} \Rightarrow^{ac}_{p_3} ... \Rightarrow^{ac}_{p_n} w,\ for\ some\ p_1 p_2 ... p_n \in R \} }[/math].

Example

Consider a simple (though not the simplest) context-free grammar that generates the language [math]\displaystyle{ \{ a^n : n \geq 1 \} }[/math]:

Let [math]\displaystyle{ G = (\{S, A, X\}, \{a\}, S, \{f,g,h,k,l\}) }[/math], where

[math]\displaystyle{ f: S \to AA }[/math]
[math]\displaystyle{ g: S \to X }[/math]
[math]\displaystyle{ h: A \to S }[/math]
[math]\displaystyle{ k: A \to X }[/math]
[math]\displaystyle{ l: S \to a }[/math]

In language controlled form, this grammar is simply [math]\displaystyle{ G^{\prime} = (\{S, A, X\}, \{a\}, S, \{f, g, h, k, l\}, (f|g|h|k|l)^{*}, \{f, g, h, k, l\}) }[/math] (where [math]\displaystyle{ (f|g|h|k|l)^{*} }[/math] is a regular expression denoting the set of all sequences of production rules). A simple modification to this grammar, changing is control sequence set R into the set [math]\displaystyle{ (f^{*}gh^{*}k)^{*}l^{*} }[/math], and changing its vacuous rule set F to [math]\displaystyle{ \{g, k\} }[/math], yields a grammar which generates the non-CF language [math]\displaystyle{ \{ a^{2^n} : n \geq 0 \} }[/math]. To see how, consider the general case of some string with n instances of S in it, i.e. [math]\displaystyle{ S^n }[/math] (the special case [math]\displaystyle{ S^1 }[/math] trivially derives the string a which is [math]\displaystyle{ a^{2^0} }[/math], an uninteresting fact).

If we chose some arbitrary production sequence [math]\displaystyle{ f^u g h^v k ... }[/math], we can consider three possibilities: [math]\displaystyle{ n = u }[/math], [math]\displaystyle{ n \lt u }[/math], and [math]\displaystyle{ n \gt u }[/math] When [math]\displaystyle{ n = u }[/math] we rewrite all n instances of S as AA, by applying rule f to the string u times, and proceed to apply g, which applies vacuously (by virtue of being in F) . When [math]\displaystyle{ n \lt u }[/math], we rewrite all n instances of S as AA, and then try to perform the n+1 rewrite using rule f, but this fails because there are no more Ss to rewrite, and f is not in F and so cannot apply vacuously, thus when [math]\displaystyle{ n \lt u }[/math], the derivation fails. Lastly, then [math]\displaystyle{ n \gt u }[/math], we rewrite u instances of S, leaving at least one instance of S to be rewritten by the subsequent application of g, rewriting S as X. Given that no rule of this grammar ever rewrites X, such a derivation is destined to never produce a terminal string. Thus only derivations with [math]\displaystyle{ n = u }[/math] will ever successfully rewrite the string [math]\displaystyle{ S^n }[/math]. Similar reasoning holds of the number of As and v. In general, then, we can say that the only valid derivations have the structure [math]\displaystyle{ S^n \Rightarrow_{f} ... \Rightarrow_{f} A^{2n} \Rightarrow{g} A^{2n} \Rightarrow{h} ... \Rightarrow{h} S^{2n} \Rightarrow{k} S^{2n} }[/math] will produce terminal strings of the grammar. The X rules, combined with the structure of the control, essentially force all Ss to be rewritten as AAs prior to any As being rewritten as Ss, which again is forced to happen prior to all still later iterations over the S-to-AA cycle. Finally, the Ss are rewritten as as. In this way, the number of Ss doubles each for each instantiation of [math]\displaystyle{ f^{8} g h^{*} k }[/math] that appears in a terminal-deriving sequence.

Choosing two random non-terminal deriving sequences, and one terminal-deriving one, we can see this in work:

Let [math]\displaystyle{ s_1 = ffghkll }[/math], then we get the failed derivation:

[math]\displaystyle{ S \Rightarrow^{ac}_{f} AA \Rightarrow^{ac}_{f} \text{failure: f cannot apply, no S to rewrite} }[/math]

Let [math]\displaystyle{ s_2 = fghhhkll }[/math], then we get the failed derivation:

[math]\displaystyle{ S \Rightarrow^{ac}_{f} AA \Rightarrow^{ac}_{g} AA \Rightarrow^{ac}_{h} SA \Rightarrow^{ac}_{h} SS \Rightarrow^{ac}_{h} \text{failure: h cannot apply, no A to rewrite} }[/math]

Let [math]\displaystyle{ s_3 = fghhkll }[/math], then we get the successful derivation:

[math]\displaystyle{ S \Rightarrow^{ac}_{f} AA \Rightarrow^{ac}_{g} AA \Rightarrow^{ac}_{h} SA \Rightarrow^{ac}_{h} SS \Rightarrow^{ac}_{k} SS \Rightarrow^{ac}_{l} aS \Rightarrow^{ac}_{l} aa }[/math]

Similar derivations with a second cycle of [math]\displaystyle{ f^{*}gh^{*}k }[/math] produce only SSSS. Showing only the (continued) successful derivation:

[math]\displaystyle{ ... \Rightarrow SS \Rightarrow^{ac}_{f} AAS \Rightarrow^{ac}_{f} AAAA \Rightarrow^{ac}_{g} AAAA }[/math]
[math]\displaystyle{ \Rightarrow^{ac}_{h} SAAA \Rightarrow^{ac}_{h} SSAA \Rightarrow^{ac}_{h} SSSA \Rightarrow^{ac}_{h} SSSS \Rightarrow^{ac}_{k} SSSS }[/math]
[math]\displaystyle{ \Rightarrow^{ac}_{l} aSSS \Rightarrow^{ac}_{l} aaSS \Rightarrow^{ac}_{l} aaaS \Rightarrow^{ac}_{l} aaaa }[/math]

Matrix grammars

Matrix grammars (expanded on in their own article) are a special case of regular controlled context-free grammars, in which the production sequence language is of the form [math]\displaystyle{ (m_1|m_2|...|m_n)^{*} }[/math], where each "matrix" [math]\displaystyle{ m_i }[/math] is a single sequence. For convenience, such a grammar is not represented with a grammar over P, but rather with just a set of the matrices in place of both the language and the production rules. Thus, a matrix grammar is the 5-tuple [math]\displaystyle{ G = (N, T, M, S, F) }[/math], where N, T, S, and F are defined essentially as previously done (with F a subset of M this time), and M is a set of matrices [math]\displaystyle{ m_i = p_{i,1} p_{i,2} ... p_{i,n_i} }[/math] where each [math]\displaystyle{ p_{i,j} }[/math] is a context-free production rule.

The derives relation in a matrix grammar is thus defined simply as:

Given some strings x and y, both in [math]\displaystyle{ (N \cup T)^{*} }[/math], and some matrix [math]\displaystyle{ m = p_1 p_2 ... p_n \in M }[/math],

[math]\displaystyle{ x \Rightarrow^{ac}_{m} y }[/math]

holds if either

[math]\displaystyle{ x = x_{1}Ax_{2} }[/math], [math]\displaystyle{ y = y_{1}wy_{2} }[/math], and [math]\displaystyle{ A \Rightarrow^{ac}_{p_1} w_1 \Rightarrow^{ac}_{p_2} w_2 \Rightarrow^{ac}_{p_3} ... \Rightarrow^{ac}_{p_n} w }[/math], or
[math]\displaystyle{ x = y }[/math] and [math]\displaystyle{ m \in F }[/math]

Informally, a matrix grammar is simply a grammar in which during each rewriting cycle, a particular sequence of rewrite operations must be performed, rather than just a single rewrite operation, i.e. one rule "triggers" a cascade of other rules. Similar phenomena can be performed in the standard context-sensitive idiom, as done in rule-based phonology and earlier Transformational grammar, by what are known as "feeding" rules, which alter a derivation in such a way as to provide the environment for a non-optional rule that immediately follows it.

Vector grammars

Vector grammars are closely related to matrix grammars, and in fact can be seen as a special class of matrix grammars, in which if [math]\displaystyle{ m \in M }[/math], then so are all of its permutations [math]\displaystyle{ p(m) }[/math]. For convenience, however, we will define vector grammars as follows: a vector grammar is a 5-tuple [math]\displaystyle{ G = (N, T, M, S, F) }[/math], where N, T, and F are defined previously (F being a subset of M again), and where M is a set of vectors [math]\displaystyle{ m_i = \{ p_1, p_2, ..., p_n \} }[/math], each vector being a set of context free rules.

The derives relation in a vector grammar is then:

Given some strings x and y, both in [math]\displaystyle{ (N \cup T)^{*} }[/math], and some matrix [math]\displaystyle{ m = \{ p_1, p_2, ..., p_n \} \in M }[/math],

[math]\displaystyle{ x \Rightarrow^{ac}_{m} y }[/math]

holds if either

[math]\displaystyle{ x = x_{1}Ax_{2} }[/math], [math]\displaystyle{ y = y_{1}wy_{2} }[/math], and [math]\displaystyle{ A \Rightarrow^{ac}_{p_{i_1}} w_1 \Rightarrow^{ac}_{p_{i_2}} w_2 \Rightarrow^{ac}_{p_{i_3}} ... \Rightarrow^{ac}_{p_{i_n}} w }[/math], where [math]\displaystyle{ m = \{p_{i_1}, p_{i_2}, ..., p_{i_n}\} }[/math], or
[math]\displaystyle{ x = y }[/math] and [math]\displaystyle{ m \in F }[/math]

Notice that the number of production rules used in the derivation sequence, n, is the same as the number of production rules in the vector. Informally, then, a vector grammar is one in which a set of productions is applied, each production applied exactly once, in arbitrary order, to derive one string from another. Thus vector grammars are almost identical to matrix grammars, minus the restriction on the order in which the productions must occur during each cycle of rule application.

Programmed grammars

Programmed grammars are relatively simple extensions to context-free grammars with rule-by-rule control of the derivation. A programmed grammar is a 4-tuple [math]\displaystyle{ G = (N, T, S, P) }[/math], where N, T, and S are as in a context-free grammar, and P is a set of tuples [math]\displaystyle{ (p, \sigma, \phi) }[/math], where p is a context-free production rule, [math]\displaystyle{ \sigma }[/math] is a subset of P (called the success field), and [math]\displaystyle{ \phi }[/math] is a subset of P (called the failure field). If the failure field of every rule in P is empty, the grammar lacks appearance checking, and if at least one failure field is not empty, the grammar has appearance checking. The derivation relation on a programmed grammar is defined as follows:

Given two strings [math]\displaystyle{ x, y \in (N \cup T)^{*} }[/math], and some rule [math]\displaystyle{ p = (A \to w, \sigma, \phi) \in P }[/math],

[math]\displaystyle{ x \Rightarrow_{p} y }[/math] and [math]\displaystyle{ x = x'Ax'', y = x'wx'' }[/math], or
[math]\displaystyle{ x = y }[/math] and A does not appear in x.

The language of a programmed grammar G is defined by constraining the derivation rule-wise, as [math]\displaystyle{ L(G) = \{ w \in (N \cup T)^{*} : S \Rightarrow_{p_1} w_1 \Rightarrow_{p_2} ... \Rightarrow_{p_n} w \} }[/math], where for each [math]\displaystyle{ p_i = (A_i \to v_i, \sigma_i, \phi_i) }[/math], either [math]\displaystyle{ w_{i-1} = x_{i-1} A x'_{i-1}, w_i = x_{i-1} v_i x'_{i-1},\ and\ p_{i+1} \in \sigma_i }[/math] or [math]\displaystyle{ w_{i-1} = w_i, p_{i+1} \in \phi_i }[/math].

Intuitively, when applying a rule p in a programmed grammar, the rule can either succeed at rewriting a symbol in the string, in which case the subsequent rule must be in ps success field, or the rule can fail to rewrite a symbol (thus applying vacuously), in which case the subsequent rule must be in ps failure field. The choice of which rule to apply to the start string is arbitrary, unlike in a language controlled grammar, but once a choice is made the rules that can be applied after it constrain the sequence of rules from that point on.

Example

As with so many controlled grammars, programmed grammars can generate the language [math]\displaystyle{ \{ a^{2^n} : n \geq 0 \} }[/math]:

Let [math]\displaystyle{ G = (\{S, A\}, \{a\}, S, \{r_1,r_2,r_3\}) }[/math], where

[math]\displaystyle{ r_1 = (S \to AA, \{r_1\}, \{r_2\}) }[/math]
[math]\displaystyle{ r_2 = (A \to S, \{r_2\}, \{r_1, r_3\}) }[/math]
[math]\displaystyle{ r_3 = (S \to a, \{r_3\}, \emptyset) }[/math]

The derivation for the string aaaa is as follows:

[math]\displaystyle{ S \Rightarrow_{r_1} AA \Rightarrow_{r_1} AA \Rightarrow_{r_2} SA \Rightarrow_{r_2} SS \Rightarrow_{r_2} SS }[/math]
[math]\displaystyle{ \Rightarrow_{r_1} AAS \Rightarrow_{r_1} AAAA \Rightarrow_{r_1} AAAA }[/math]
[math]\displaystyle{ \Rightarrow_{r_2} SAAA \Rightarrow_{r_2} SSAA \Rightarrow_{r_2} SSSA \Rightarrow_{r_2} SSSS \Rightarrow_{r_2} SSSS }[/math]
[math]\displaystyle{ \Rightarrow_{r_3} aSSS \Rightarrow_{r_3} aaSS \Rightarrow_{r_3} aaaS \Rightarrow_{r_3} aaaa \Rightarrow_{r_3} aaaa }[/math]

As can be seen from the derivation and the rules, each time [math]\displaystyle{ r_1 }[/math] and [math]\displaystyle{ r_2 }[/math] succeed, they feed back to themselves, which forces each rule to continue to rewrite the string over and over until it can do so no more. Upon failing, the derivation can switch to a different rule. In the case of [math]\displaystyle{ r_1 }[/math], that means rewriting all Ss as AAs, then switching to [math]\displaystyle{ r_2 }[/math]. In the case of [math]\displaystyle{ r_2 }[/math], it means rewriting all As as Ss, then switching either to [math]\displaystyle{ r_1 }[/math], which will lead to doubling the number of Ss produced, or to [math]\displaystyle{ r_3 }[/math] which converts the Ss to as then halts the derivation. Each cycle through [math]\displaystyle{ r_1 }[/math] then [math]\displaystyle{ r_2 }[/math] therefore either doubles the initial number of Ss, or converts the Ss to as. The trivial case of generating a, in case it is difficult to see, simply involves vacuously applying [math]\displaystyle{ r_1 }[/math], thus jumping straight to [math]\displaystyle{ r_2 }[/math] which also vacuously applies, then jumping to [math]\displaystyle{ r_3 }[/math] which produces a.

Control by context conditions

Unlike grammars controlled by prescribed sequences of production rules, which constrain the space of valid derivations but do not constrain the sorts of sentences that a production rule can apply to, grammars controlled by context conditions have no sequence constraints, but permit constraints of varying complexity on the sentences to which a production rule applies. Similar to grammars controlled by prescribed sequences, there are multiple different kinds of grammars controlled by context conditions: conditional grammars, semi-conditional grammars, random context grammars, and ordered grammars.

Conditional grammars

Conditional grammars are the simplest version of grammars controlled by context conditions. The structure of a conditional grammar is very similar to that of a normal rewrite grammar: [math]\displaystyle{ G = (N, T, S, P) }[/math], where N, T, and S are as defined in a context-free grammar, and P is a set of pairs of the form [math]\displaystyle{ (p, R) }[/math] where p is a production rule (usually context-free), and R is a language (usually regular) over [math]\displaystyle{ N \cup T }[/math]. When R is regular, R can just be expressed as a regular expression.

Proof-theoretic definition

With this definition of a conditional grammar, we can define the derives relation as follows:

Given two strings [math]\displaystyle{ x, y \in (N \cup T)^{*} }[/math], and some production rule [math]\displaystyle{ p = (A \to w, R) \in P }[/math],

[math]\displaystyle{ x \Rightarrow_{p} y }[/math] if and only if [math]\displaystyle{ x = x' A x'' }[/math], [math]\displaystyle{ y = x' w x'' }[/math], and [math]\displaystyle{ x \in R }[/math]

Informally then, the production rule for some pair in P can apply only to strings that are in its context language. Thus, for example, if we had some pair [math]\displaystyle{ (S \to x, a^{*}Sb^{*}) }[/math], we can only apply this to strings consisting of any number of as followed by exactly only S followed by any number of bs, i.e. to sentences in [math]\displaystyle{ \{ a^m A b^n : m, n \geq 0 \} }[/math], such as the strings S, aSb, aaaS, aSbbbbbb, etc. It cannot apply to strings like xSy, aaaSxbbb, etc.

Example

Conditional grammars can generate the context-sensitive language [math]\displaystyle{ \{ a^{2^n} : n \geq 0 \} }[/math].

Let [math]\displaystyle{ G = (\{S, S'\}, \{a\}, \{ f, g, h \}, S) }[/math], where

[math]\displaystyle{ f = (S \to AA, A^{*}S^{+}) }[/math]
[math]\displaystyle{ g = (A \to B, B^{*}A^{+}) }[/math]
[math]\displaystyle{ h = (B \to S, S^{*}B^{+}) }[/math]
[math]\displaystyle{ k = (S \to a, a^{*}S^{+}) }[/math]

We can then generate the sentence aaaa with the following derivation:

[math]\displaystyle{ S \Rightarrow_{f} AA \Rightarrow_{g} BA \Rightarrow_{g} BB }[/math]
[math]\displaystyle{ \Rightarrow_{h} SB \Rightarrow_{h} SS \Rightarrow_{f} AAS \Rightarrow_{f} AAAA }[/math]
[math]\displaystyle{ \Rightarrow_{g} BAAA \Rightarrow_{g} BBAA \Rightarrow_{g} BBBA \Rightarrow_{g} BBBB }[/math]
[math]\displaystyle{ \Rightarrow_{h} SBBB \Rightarrow_{h} SSBB \Rightarrow_{h} SSSB \Rightarrow_{h} SSSS }[/math]
[math]\displaystyle{ \Rightarrow_{k} aSSS \Rightarrow_{k} aaSS \Rightarrow_{k} aaaS \Rightarrow_{k} aaaa }[/math]

Semi-conditional grammars

A semi-conditional grammar is very similar to a conditional grammar, and technically the class of semi-conditional grammars are a subset of the conditional grammars. Rather than specifying what the whole of the string must look like for a rule to apply, semi-conditional grammars specify that a string must have as substrings all of some set of strings, and none of another set, in order for a rule to apply. Formally, then, a semi-conditional grammar is a tuple [math]\displaystyle{ G = (N, T, S, P) }[/math], where, N, T, and S are defined as in a CFG, and P is a set of rules like [math]\displaystyle{ (p, R, Q) }[/math] where p is a (usually context-free) production rule, and R and Q are finite sets of strings. The derives relation can then be defined as follows.

For two strings [math]\displaystyle{ xAx', xwx' \in (N \cup T)^{*} }[/math], and some rule [math]\displaystyle{ p = (A \to w, R, Q) \in P }[/math],

[math]\displaystyle{ xAx' \Rightarrow_{p} xwx' }[/math] if and only if every string in R is a substring of [math]\displaystyle{ xAx' }[/math], and no string in Q is a substring of [math]\displaystyle{ xAx' }[/math]

The language of a semi-conditional grammar is then trivially the set of terminal strings [math]\displaystyle{ L(G) = \{ w \in T^{*} : S \Rightarrow^{*} w \} }[/math].

An example of a semi-conditional grammar is given below also as an example of random context grammars.

Random context grammars

A random context grammar is a semi-conditional grammar in which the R and Q sets are all subsets of N. Because subsets of N are finite sets over [math]\displaystyle{ (N \cup T)^{*} }[/math], it is clear that random context grammars are indeed kinds of semi-conditional grammars.

Example

Like conditional grammars, random context grammars (and thus semi-conditional grammars) can generate the language [math]\displaystyle{ \{ a^{2^n} : n \geq 0 \} }[/math]. One grammar which can do this is:

Let [math]\displaystyle{ G = (\{S, X, Y, A\}, \{a\}, S, \{r_1, r_2, r_3, r_4, r_5\}) }[/math], where

[math]\displaystyle{ r_1 = (S \to X X, \emptyset, \{Y, A\}) }[/math]
[math]\displaystyle{ r_2 = (X \to Y, \emptyset, \{S\}) }[/math]
[math]\displaystyle{ r_3 = (Y \to S, \emptyset, \{X\}) }[/math]
[math]\displaystyle{ r_4 = (S \to A, \emptyset, \{X, Y\}) }[/math]
[math]\displaystyle{ r_5 = (A \to a, \emptyset, \{S\}) }[/math]

Consider now the production for aaaa:

[math]\displaystyle{ S \Rightarrow_{r_1} X X \Rightarrow_{r_2} Y X \Rightarrow_{r_2} Y Y \Rightarrow_{r_3} S Y \Rightarrow_{r_3} S S }[/math]
[math]\displaystyle{ \Rightarrow_{r_1} X X S \Rightarrow_{r_1} X X X X \Rightarrow_{r_2} Y X X X \Rightarrow_{r_2} Y Y X X \Rightarrow_{r_2} Y Y Y X \Rightarrow_{r_2} Y Y Y Y }[/math]
[math]\displaystyle{ \Rightarrow_{r_3} S Y Y Y \Rightarrow_{r_3} S S Y Y \Rightarrow_{r_3} S S S Y \Rightarrow_{r_3} S S S S }[/math]
[math]\displaystyle{ \Rightarrow_{r_4} A S S S \Rightarrow_{r_4} A A S S \Rightarrow_{r_4} A A A S \Rightarrow_{r_4} A A A A }[/math]
[math]\displaystyle{ \Rightarrow_{r_5} a A A A \Rightarrow_{r_5} a a A A \Rightarrow_{r_5} a a a A \Rightarrow_{r_5} a a a a }[/math]

The behavior of the R sets here is trivial: any string can be rewritten according to them, because they do not require any substrings to be present. The behavior of the Q sets, however, are more interesting. In [math]\displaystyle{ r_1 }[/math], we are forced by the Q set to rewrite an S, thus beginning an S-doubling process, only when no Ys or As are present in the string, which means only when a prior S-doubling process has been fully initiated, eliminating the possibility of only doubling some of the Ss. In [math]\displaystyle{ r_2 }[/math], which moves the S-doubling process into its second stage, we cannot begin this process until the first stage is complete and there are no more Ss to try to double, because the Q set prevents the rule from applying if there is an S symbol still in the string. In [math]\displaystyle{ r_3 }[/math], we complete the doubling stage by introducing the Ss back only when there are no more Xs to rewrite, thus when the second stage is complete. We can cycle through these stages as many times as we want, rewriting all Ss to XXs before then rewriting each X to a Y, and then each Y to an S, finally ending by replacing each S with an A and then an a. Because the rule for replacing S with A prohibits application to a string with an X in it, we cannot apply this in the middle of the first stage of the S-doubling process, thus again preventing us from only doubling some Ss.

Ordered grammars

Ordered grammars are perhaps one of the simpler extensions of grammars into the controlled grammar domain. An ordered grammar is simply a tuple [math]\displaystyle{ G = (N, T, S, P) }[/math] where N, T, and S are identical to those in a CFG, and P is a set of context-free rewrite rules with a partial ordering [math]\displaystyle{ \lt }[/math]. The partial ordering is then used to determine which rule to apply to a string, when multiple rules are applicable. The derives relation is then:

Given some strings [math]\displaystyle{ xAx', xwx' \in (N \cup T)^{*} }[/math] and some rule [math]\displaystyle{ p = A \to w \in P }[/math],

[math]\displaystyle{ xAx' \Rightarrow_{p} xwx' }[/math] if and only if there is no rule [math]\displaystyle{ p' = A \to w' \in P }[/math] such that [math]\displaystyle{ p \lt p' }[/math].

Example

Like many other contextually controlled grammars, ordered grammars can enforce the application of rules in a particular order. Since this is the essential property of previous grammars that could generate the language [math]\displaystyle{ \{ a^{2^n} : n \geq 0 \} }[/math], it should be no surprise that a grammar that explicitly uses rule ordering, rather than encoding it via string contexts, should similarly be able to capture that language. And as it turns out, just such an ordered grammar exists:

Let [math]\displaystyle{ G = (\{S, X, Y, Z, A\}, \{a\}, S, P) }[/math], where P is the partially ordered set described by the Hasse diagram

Ordered grammar.svg

The derivation for the string aaaa is simply:

[math]\displaystyle{ S \Rightarrow_{S \to XX}\ XX \ \Rightarrow_{X \to Y}\ YX \ \Rightarrow_{X \to Y}\ YY \ \Rightarrow_{Y \to S}\ SY \ \Rightarrow_{Y \to S}\ YY }[/math]
[math]\displaystyle{ \Rightarrow_{S \to XX}\ XXS \ \Rightarrow_{S \to XX}\ XXXX }[/math]
[math]\displaystyle{ \Rightarrow_{X \to Y}\ YXXX \ \Rightarrow_{X \to Y}\ YYXX \ \Rightarrow_{X \to Y}\ YYYX \ \Rightarrow_{X \to Y}\ YYYY }[/math]
[math]\displaystyle{ \Rightarrow_{Y \to S}\ SYYY \ \Rightarrow_{Y \to S}\ SSYY \ \Rightarrow_{Y \to S}\ SSSY \ \Rightarrow_{Y \to S}\ SSSS }[/math]
[math]\displaystyle{ \Rightarrow_{S \to A}\ ASSS \ \Rightarrow_{S \to A}\ AASS \ \Rightarrow_{S \to A}\ AAAS \ \Rightarrow_{S \to A}\ AAAA }[/math]
[math]\displaystyle{ \Rightarrow_{A \to a}\ aAAA \ \Rightarrow_{A \to a}\ aaAA \ \Rightarrow_{A \to a}\ aaaA \ \Rightarrow_{A \to a}\ aaaa }[/math]

At each step of the way, the derivation proceeds by rewriting in cycles. Notice that if at the fifth step SY, we had four options: [math]\displaystyle{ Y \to Z, S \to Z, Y \to S, S \to A }[/math], the first two of which halt the derivation, as Z cannot be rewritten. In the example, we used [math]\displaystyle{ Y \to S }[/math] to derive SS, but consider if we had chosen [math]\displaystyle{ S \to A }[/math] instead. We would have produced the string AS, the options for which are [math]\displaystyle{ Y \to Z }[/math] and [math]\displaystyle{ A \to Z }[/math], both of which halt the derivation. Thus with the string SY, and conversely with YS, we must rewrite the Y to produce SS. The same hold for other combinations, so that overall, the ordering forces the derivation to halt, or else proceed by rewriting all Ss to XXs, then all Xs to Ys, then all Ys to Ss, and so on, then finally all Ss to As then all As to as. In this way, a string [math]\displaystyle{ S^n }[/math] can only ever be rewritten as [math]\displaystyle{ A^n }[/math] which produces as, or as [math]\displaystyle{ S^{2n} }[/math]. Starting with n = 0, it should be clear that this grammar only generates the language [math]\displaystyle{ \{ a^{2^n} : n \geq 0 \} }[/math].

Grammars with parallelism

A still further class of controlled grammars is the class of grammars with parallelism in the application of a rewrite operation, in which each rewrite step can (or must) rewrite more than one non-terminal simultaneously. These, too, come in several flavors: Indian parallel grammars, k-grammars, scattered context grammars, unordered scattered context grammars, and k-simple matrix grammars. Again, the variants differ in how the parallelism is defined.

Indian parallel grammars

An Indian parallel grammar is simply a CFG in which to use a rewrite rule, all instances of the rules non-terminal symbol must be rewritten simultaneously. Thus, for example, given the string aXbYcXd, with two instances of X, and some rule [math]\displaystyle{ X \to w }[/math], the only way to rewrite this string with this rule is to rewrite it as awbYcwd; neither awbYcXd nor aXbYcwd are valid rewrites in an Indian parallel grammar, because they did not rewrite all instances of X.

Indian parallel grammars can easily produce the language [math]\displaystyle{ \{ ww : w \in \{a,b\}^{*}\} }[/math]:

Let [math]\displaystyle{ G = (\{S, A\}, \{a,b\}, S, \{f,g,h,k\}) }[/math], where

[math]\displaystyle{ f = S \to AA }[/math]
[math]\displaystyle{ g = A \to aA }[/math]
[math]\displaystyle{ h = A \to bA }[/math]
[math]\displaystyle{ k = A \to \epsilon }[/math]

Generating then is quite simple:

[math]\displaystyle{ S \Rightarrow_{f} AA \Rightarrow_{g} aAaA \Rightarrow_{g} aaAaaA \Rightarrow_{h} aabAaabA \Rightarrow_{k} aabaab }[/math]

The language [math]\displaystyle{ \{ a^{2^n} : n \geq 0 \} }[/math] is even simpler:

Let [math]\displaystyle{ G = (\{S\}, \{a\}, S, P) }[/math], where P consists of

[math]\displaystyle{ S \to SS }[/math]
[math]\displaystyle{ S \to a }[/math]

It should be obvious, just from the first rule, and the requirement that all instances of a non-terminal are rewritten simultaneously with the same rule, that the number of Ss doubles on each rewrite step using the first rule, giving the derivation steps [math]\displaystyle{ S \Rightarrow S^2 \Rightarrow S^4 \Rightarrow S^8 \Rightarrow ... }[/math]. Final application of the second rule replaces all the Ss with as, thus showing how this simple language can produce the language [math]\displaystyle{ \{ a^{2^n} : n \geq 0 \} }[/math].

K-grammars

A k-grammar is yet another kind of parallel grammar, very different from an Indian parallel grammar, but still with a level of parallelism. In a k-grammar, for some number k, exactly k non-terminal symbols must be rewritten at every step (except the first step, where the only symbol in the string is the start symbol). If the string has less than k non-terminals, the derivation fails.

A 3-grammar can produce the language [math]\displaystyle{ \{ a^n b^n c^n : n \geq 0 \} }[/math], as can be seen below:

Let [math]\displaystyle{ G = (\{S,A,B,C\}, \{a,b,c\}, S, P) }[/math], where P consists of:

[math]\displaystyle{ S \to ABC }[/math]
[math]\displaystyle{ A \to aA }[/math]
[math]\displaystyle{ A \to a }[/math]
[math]\displaystyle{ B \to bB }[/math]
[math]\displaystyle{ B \to b }[/math]
[math]\displaystyle{ C \to cC }[/math]
[math]\displaystyle{ C \to c }[/math]

With the following derivation for aaabbbccc:

[math]\displaystyle{ S \Rightarrow ABC \Rightarrow aAbBcC \Rightarrow aaAbbBccC \Rightarrow aaabbbccc }[/math]

At each step in the derivation except the first and last, we used the self-recursive rules [math]\displaystyle{ A \to aA, B \to bB, C \to cC }[/math]. If we had not use the recursive rules, instead using, say, [math]\displaystyle{ A \to a, B \to bB, C \to cC }[/math], where one of the rules is not self-recursive, the number of non-terminals would have decreased to 2, thus making the string unable to be derived further because it would have too few non-terminals to be rewritten.

Russian parallel grammars

Russian parallel grammars[2] are somewhere between Indian parallel grammars and k-grammars, defined as [math]\displaystyle{ G = (N,T,S,P) }[/math], where N, T, and S are as in a context-free grammar, and P is a set of pairs [math]\displaystyle{ (A \to w, k) }[/math], where [math]\displaystyle{ A \to w }[/math] is a context-free production rule, and k is either 1 or 2. Application of a rule [math]\displaystyle{ p = (A \to w, k) }[/math] involves rewriting k occurrences of A to w simultaneously.

Scattered context grammars

A scattered context grammar is a 4-tuple [math]\displaystyle{ G = (N, T, S, P) }[/math] where N, T, and S are defined as in a context-free grammar, and P is a set of tuples called matrixes [math]\displaystyle{ p = (A_1 \to w_1, ..., A_n \to w_n) }[/math], where [math]\displaystyle{ n \gt 0 }[/math] can vary according to the matrix. The derives relation for such a grammar is

[math]\displaystyle{ x \Rightarrow_{p} y }[/math] if and only if
[math]\displaystyle{ p = (A_1 \to w_1, ..., A_n \to w_n)\in P }[/math], and
[math]\displaystyle{ x = x_1 A_1 x_2 ... x_n A_n x_{n+1}, y = x_1 w_1 x_2 ... x_n w_n x_{n+1} }[/math], for [math]\displaystyle{ x_i \in (N \cup T)^{*} }[/math]

Intuitively, then, the matrixes in a scattered context grammar provide a list of rules which must each be applied to non-terminals in a string, where those non-terminals appear in the same linear order as the rules that rewrite them.

An unordered scattered context grammar is a scattered context grammar in which, for every rule in P, each of its permutations is also in P. As such, a rule and its permutations can instead be represented as a set rather than as tuples.

Example

Scattered context grammars are capable of describing the language [math]\displaystyle{ \{ a^n b^n c^n : n \geq 0 \} }[/math] quite easily.

Let [math]\displaystyle{ G = (\{S,A,B,C\}, \{a,b,c\}, S, \{r_1, r_2, r_3\}) }[/math], where

[math]\displaystyle{ r_1 = (S \to ABC) }[/math]
[math]\displaystyle{ r_2 = (A \to aA, B \to bB, C \to cC) }[/math]
[math]\displaystyle{ r_3 = (A \to \epsilon,B \to \epsilon,C \to \epsilon) }[/math]

Deriving then is trivial:

[math]\displaystyle{ S \Rightarrow_{r_1} ABC \Rightarrow_{r_2} aAbBcC \Rightarrow_{r_2} aaAbbBccC \Rightarrow_{r_2} aaaAbbbBcccC \Rightarrow_{r_3} aaabbbccc }[/math]

References

  1. Dassow, J., Pǎun, Gh., and Salomaa, A. Grammars with Controlled Derivations. In G. Rozenberg and A. Salomaa (Eds.) Handbook of Formal Languages, Vol. 2, Ch. 3.
  2. Dassow, J. 1984. On some extensions of russian parallel context free grammars. Acta Cybernetica 6, pp. 355-360.