Опубликован: 06.08.2007 | Доступ: свободный | Студентов: 1550 / 726 | Оценка: 4.45 / 4.29 | Длительность: 18:50:00
Специальности: Программист
Лекция 3:

Языки и их представление

< Лекция 2 || Лекция 3: 123456 || Лекция 4 >

Теорема 2.1. Каждый контекстно-свободный язык может быть порожден неукорачивающей контекстно- свободной грамматикой.

Доказательство. Пусть L - контекстно-свободный язык. Тогда существует контекстно-свободная грамматика G = (N, T, P, S), порождающая L.

Построим новую грамматику G' = (N',T,P',S') следующим образом:

  1. Если в P есть правило вида A\rightarrow\alpha_0 B_1 \alpha_1 \ldots B_k \alpha_k, где k\geq 0, \; B_i \; \Rightarrow^+ \; e для 1 \leq i \leq k и ни из одной цепочки \alpha_j(0 \leq j \leq k) не выводится e, то включить в P' все правила (кроме A\rightarrow e ) вида
    A\rightarrow\alpha_0 X_1 \alpha_1 \ldots X_k \alpha_k
    где X_i это либо B_i, либо e.

  2. Если S \rightarrow^+ \; e, то включить в P' правила S' \rightarrow S, \; S' \rightarrow e и положить N'= N \cup \{S'\}. В противном случае положить N'= N и S'= S. Порождает ли грамматика пустую цепочку можно установить следующим простым алгоритмом:

    Шаг 1. Строим множество N_0=\{N \mid N\rightarrow e\}

    Шаг 2. Строим множество N_i=N_{i-1}\cup \{N \mid N\rightarrow \alpha, \; \alpha \in \{N_{i-1}\}^*\}

    Шаг 3. Если N_i=N_{i-1}, перейти к шагу 4, иначе шаг 2.

    Шаг 4. Если S \in  N_i, значит S \rightarrow^* e.

    Легко видеть, что G' - неукорачивающая грамматика. Можно показать по индукции, что L(G') = L(G).

Пусть Ki - класс всех языков типа i. Доказано, что справедливо следующее (строгое) включение: K_3 \subset K_2 \subset K_1 \subset K_0.

Заметим, что если язык порождается некоторой грамматикой, это не означает, что он не может быть порожден грамматикой с более сильными ограничениями на правила. Приводимый ниже пример иллюстрирует этот факт.

Пример 2.8. Рассмотрим грамматику G = (\{S, A, B\}, \{0, 1\}, \{S \rightarrow AB, \; A \rightarrow 0A, \; A \rightarrow 0, \; B \rightarrow 1B, \; B \rightarrow 1\},  \; S). Эта грамматика является контекстно-свободной. Легко показать, что L(G) = \{0^n 1^m \mid n,m \; > \; 0\}. Однако, в примере 2.7 приведена праволинейная грамматика, порождающая тот же язык.

Ниже приводятся подробные примеры решения двух практически интересных более сложных задач на построение КС- и НС-грамматик.

Пример 2.9. Данный пример относится к несколько парадоксальной для грамматик постановке: построить КС-грамматику, порождающую язык:

\{\{a,b\}^*\backslash a^n b^m a^n b^m \mid n,m \geq1\}

т.е. построить все цепочки кроме указанных (обычно-то говорят о том, что надо построить). Но, может быть, в такой постановке заложена и подсказка к решению? Известно, что иные задачи с подобными требованиями так и решаются: нужно сделать все, "что не надо", а потом отклониться от этого "не надо" всеми возможными способами.

Однако воодушевлнных построением в рамках КС- грамматики цепочек вида \{a^n b^m a^n b^m \} (здесь и далее в этом примере n, m, k, l, j \; \geq \; 1) ждет некоторое разочарование. Действительно, в отличие от таких случаев, как \{a^n b^n a^m b^m \}, \{a^n b^m a^m b^n \}, \{a^n b^m b^n a^m\} и т.п., обе зависимости (по n и по m ) придется отслеживать одновременно и из двух разных центров порождения, к чему КС-грамматики по своей природе (виду своих правил) оказываются не предназначены.

Попробуем тогда пересказать условие задачи в конструктивном (созидательном) плане, т.е. обозначая лишь то, что нам нужно построить, а не наоборот. Поначалу такое множество цепочек кажется необозримым. Но попробуем, "Дорогу осилит идущий"! Начнем с очевидных случаев:

\{a^n\}, \{b^n\}, \{a^n b^m\}, \{b^n a^m\}, \{a^n b^m a^k\}, \{b^n a^m b^k\}\ldots

Однако бесконечно продолжать в духе \{b^n a^m b^k a^l b^j\} уже как- то скучно. Замечаем, что b\{a, b\}^* вполне конечным образом определяет половину из упомянутых бесчисленных описаний, а в следующий момент симметрия нам подсказывает и язык \{a, b\}^*a.

Таким образом, все цепочки вышеперечисленных видов укладываются в три случая:

\{a^n b^m\}, \;  b\{a,b\}^*, \; \{a,b\}^*a

Далее рассмотрим случай \{a^n b^m a^k b^l \mid n \neq k \; или \; m \neq l\}. Но что такое, к примеру, n \neq k? То же самое, что объединение условий n>k \; и \; n<k! И здесь перешли к конструктиву, который несложно строится в рамках КС-грамматики.

Остается единственный неупомянутый случай:

\{a^n b^m a^k b^l\}a\{a,b\}^*

Вспоминая, что объединение КС-языков есть КС-язык, получаем искомое решение задачи.

Так, если язык \{a^n b^m \} может быть порожден грамматикой

S_1\rightarrow AB
A\rightarrow aA \mid a
B\rightarrow bB \mid b

а язык b \{a, b\}^* - грамматикой

S_2 \rightarrow bC
C \rightarrow CC \mid a \mid b \mid \varepsilon ,

то для объединения этих языков (в общем случае использующих каждый свой уникальный набор вспомогательных знаков) достаточно добавить правило старта из новой общей аксиомы:

S \rightarrow S_1 \mid S_2

Пример 2.10. Построение НС-грамматики.

Грамматики непосредственных составляющих (или, кратко, НС-грамматики) есть вид представления контекстно-зависимых грамматик, т.е. они обладают теми же выразительными возможностями, что и КЗ-грамматики в целом. Каждое правило НС-грамматики должно соответствовать виду:

\varphi A \psi \rightarrow \varphi\eta\psi, \; (\mid \eta \mid \geq 1)

то есть левое и правое окружение (контекст) заменяемого знака A должны сохраниться и вокруг непустой заменяющей цепочки \eta (греческая буква "эта".

Такое дополнительное ограничение позволяет удобнее переходить от КЗ-грамматики к соответствующему линейно- ограниченному автомату

Рассмотрим построение НС-грамматики для языка

\{a^{n^2} \mid n\geq 0\}, порождающего слова вида \varepsilon, \; a, \; a^4, \; a^9, \;\ldots

Для большей ясности сперва построим для этого языка грамматику общего вида, а потом перестроим ее в соответствии с НС-ограничениями.

Сам алгоритм порождения a^{n^2} может основываться как на известном свойстве квадратов чисел, разность между соседними из которых образуют арифметическую прогрессию, так и на собственно "квадратности" интересующих чисел, т.е. того, что каждое квадратное число представимо наподобие матрицы из n строк и n столбцов единичных элементов (в связи с чем Пифагор и дал название подобным числам - квадратные, а среди других чисел по тому же принципу отметил треугольные, кубические, пирамидальные и т.п.). Последний подход представляется более общим, поскольку подобным образом мы сможем построить и \{a^{n^k}
\mid  k > 2\}.

Итак, порождаем две группы по n элементов

Правила Вид получаемой цепочки
S \rightarrow CSD \mid CD C^n D^n
CD \rightarrow DCA C^{n-1} \; DCAD^{n-1} (A задерживает C)
CA \rightarrow AC (DA^n)^n C^n (отработали все C)
A \rightarrow a (Da^n)^n C^n

Получили a^{n^2}, но что делать с C и D? Сделав свое дело, они стали лишними.

В грамматике общего вида такие знаки сокращают ("увольняют"), а в КЗ-грамматиках - "переводят на другую работу" (в основные знаки). Но если мы просто напишем C \rightarrow \varepsilon , D \rightarrow \varepsilon, вывод в случайный момент времени может закончиться досрочно и станет возможным порождение лишних цепочек.

Поэтому в обоих случаях не обойтись без дальнейшего уточнения предназначения (миссий) и состава "действующих лиц". Отметим для этого самый первый из команды знаков C (назовем его B ) и самый последний из D (обозначим его E ). Когда B и E встретятся, это и будет признаком полного завершения процесса порождения знаков a.

Начнем вывод с начала:

Правила Вид получаемой цепочки
S\rightarrow BS'E BS'E
S' \rightarrow CS'D \mid CD BC^n D^n E
CD \rightarrow DCA BC^{n-1}\; (DA)^n \; CE ( C прошло первый раз)
CA \rightarrow AC B(DA^n)^n C^n \; E (прошли все C)
BD \rightarrow B BA^n \; (DA^n)^{n-1} \; C^n \; E
BA \rightarrow  AB A^{n*n}BC^n E (ушли все D)
CE \rightarrow  E A^{n*n}BE (ушли все C)
BE \rightarrow \varepsilon A^{n*n} (ушли B c E)
A \rightarrow a a^{n*n}

Результат получили, но какой ценой (для B, C, D и E )? Прямо-таки сталинские методы. Точнее скажем, в военных или иных чрезвычайных условиях иначе, порой, и нет возможности поступить. А в более мирное время? Попробуем "соблюдать КЗОТ" и обойтись без сокращений.

Снова:

Правила Вид получаемой цепочки
S'\rightarrow BSE BSE
S \rightarrow CSD \mid CD BC^n D^n E
CD \rightarrow DCA BC^{n-1}\; (DA)^n \; CE ( C прошло первое C )
CA \rightarrow AC B(DA^n)^n C^n \; E (прошли все C)
BD \rightarrow aaB a^ BA^n \; (DA^n)^{n-1} \; C^n \; E
BA \rightarrow  AB (a^2 A^n)^n BC^n E (ушли все D)
CE \rightarrow  Eaa (a^2 A^n)^n BEa^{2n} (ушли все C)
A \rightarrow a a^{n*n+2n}BEa^{2n} (ушли B c E)
BE \rightarrow aaaa a^{{n^2}+4n+4}=a^{(n+2)^2}
S \rightarrow \varepsilon \mid a \mid a^4 (восполнили \ частные \ решения)
< Лекция 2 || Лекция 3: 123456 || Лекция 4 >