Обсуждение участницы:Анна — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
Строка 1: Строка 1:
 +
== Примеры доказательств ==
 +
=== Язык <tex>half(L)</tex> ===
 
{{Определение
 
{{Определение
 
|definition = Определим <tex>half(L)</tex> как множество первых половин цепочек языка <tex>L</tex>, то есть множество <tex>\{ w \mid </tex> существует <tex>x</tex>, для которой <tex>wx \in L</tex>, причем <tex>|w| = |x| \}</tex>. }}
 
|definition = Определим <tex>half(L)</tex> как множество первых половин цепочек языка <tex>L</tex>, то есть множество <tex>\{ w \mid </tex> существует <tex>x</tex>, для которой <tex>wx \in L</tex>, причем <tex>|w| = |x| \}</tex>. }}
 
Например, если <tex>L = \{ \varepsilon, 0010, 011, 010110 \}</tex>, то <tex>half(L) = \{ \varepsilon, 00, 010 \}</tex>. Заметим, что цепочки нечетной длины не влияют на <tex>half(L)</tex>.
 
Например, если <tex>L = \{ \varepsilon, 0010, 011, 010110 \}</tex>, то <tex>half(L) = \{ \varepsilon, 00, 010 \}</tex>. Заметим, что цепочки нечетной длины не влияют на <tex>half(L)</tex>.
{{Определение
 
|definition = Определим <tex>cycle(L)</tex> как множество <tex>\{ w \mid </tex> цепочку <tex>w</tex> можно представить в виде <tex>w = xy</tex>, где <tex>yx \in L \}</tex>. }}
 
Например, если <tex>L = \{ 01, 011 \}</tex>, то <tex>cycle(L) = \{ 01, 10, 011, 110, 101 \}</tex>.
 
  
 
{{Утверждение
 
{{Утверждение
Строка 16: Строка 15:
 
Теперь по индукции не сложно доказать, что <tex>\delta'(q_0', x) = (\delta(q_0, x), S_n)</tex>, где <tex>|x| = n</tex>. По определению множества терминальных вершин, автомат <tex>M'</tex> допускает строку <tex>x</tex> тогда и только тогда, когда <tex>\delta(q_0, x) \in S_n</tex>. Следовательно, автомат <tex>M'</tex> допускает язык <tex>half(L)</tex>.Таким образом, мы построили ДКА, который допускает язык <tex>half(L)</tex>. Следовательно, данный язык является регулярным.
 
Теперь по индукции не сложно доказать, что <tex>\delta'(q_0', x) = (\delta(q_0, x), S_n)</tex>, где <tex>|x| = n</tex>. По определению множества терминальных вершин, автомат <tex>M'</tex> допускает строку <tex>x</tex> тогда и только тогда, когда <tex>\delta(q_0, x) \in S_n</tex>. Следовательно, автомат <tex>M'</tex> допускает язык <tex>half(L)</tex>.Таким образом, мы построили ДКА, который допускает язык <tex>half(L)</tex>. Следовательно, данный язык является регулярным.
 
}}
 
}}
 +
=== Язык <tex>alt(L, M)</tex> ===
 +
{{Определение
 +
|definition = Пусть <tex>w = w_1 w_2 \dots w_n</tex> и <tex>x = x_1 x_2 \dots x_n</tex>. Определим <tex>alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n</tex>. Распространим это определение на языки следующим образом: пусть <tex>L</tex> и <tex>M</tex> {{---}} два языка над одним алфавитом <tex>\Sigma</tex>. Тогда <tex>alt(L, M) = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}</tex>.}}
  
 
{{Утверждение
 
{{Утверждение
 
|id = st4
 
|id = st4
 +
|statement = Пусть <tex>L</tex> и <tex>M</tex> {{---}} регулярные языки. Тогда <tex>alt(L, M)</tex> также является регулярным.
 +
|proof = Так как <tex>L</tex> и <tex>M</tex> {{---}} регулярные языки, то существуют ДКА <tex>D_L = \langle \Sigma , Q_L , q_{0L} , F_L , \delta_L \rangle </tex>, распознающий язык <tex>L</tex>, и <tex>D_M = \langle \Sigma , Q_M , q_{0M} , F_M , \delta_M \rangle </tex>, распознающий <tex>M</tex>.
 +
}}
 +
=== Язык <tex>cycle(L)</tex> ===
 +
{{Определение
 +
|definition = Определим <tex>cycle(L)</tex> как множество <tex>\{ w \mid </tex> цепочку <tex>w</tex> можно представить в виде <tex>w = xy</tex>, где <tex>yx \in L \}</tex>. }}
 +
Например, если <tex>L = \{ 01, 011 \}</tex>, то <tex>cycle(L) = \{ 01, 10, 011, 110, 101 \}</tex>.
 +
 +
{{Утверждение
 +
|id = st5
 
|statement =
 
|statement =
 
Пусть <tex>L</tex> {{---}} регулярный язык. Тогда язык <tex>cycle(L)</tex> также регулярен.
 
Пусть <tex>L</tex> {{---}} регулярный язык. Тогда язык <tex>cycle(L)</tex> также регулярен.
 
|proof =
 
|proof =
[[Файл:Enfa_before.jpg|left|thumb|240px|Рис. 1. Разбиение автомата.]]
+
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]
[[Файл:Enfa-after.jpg|right|thumb|240px|Рис. 2. Перестроение.]]
+
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]
 
Так как <tex>L</tex> {{---}} регулярный язык, то существует допускающий его ДКА <tex>M = \langle \Sigma , Q , q_0 , F , \delta \rangle </tex>. Построим из <tex>M</tex> недетерминированный автомат с <tex>\varepsilon-</tex>переходами следующим образом: рассмотрим состояние <tex>q \in Q</tex>, из которого есть переходы в другие состояния (то есть начиная с <tex>q</tex> можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с <tex>q</tex>, станет префиксом нового слова, а префикс, заканчивающийся в <tex>q</tex> {{---}} суффиксом. Разделим автомат на две части <tex>A_1</tex> и <tex>A_2</tex> такие, что <tex>A_1</tex> будет содержать все вершины, из которых достижима <tex>q</tex>, а <tex>A_2</tex> {{---}} все вершины, которые достижимы из <tex>q</tex> (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат <tex>M</tex> содержит циклы. Теперь перестроим автомат так, что он будет принимать слова "зацикленные" вокруг <tex>q</tex>, то есть начинающиеся с <tex>q</tex> и после достижения терминальной вершины продолжающиеся с <tex>q_0</tex> (см. рис. 2). Для этого стартовой вершиной сделаем <tex>q</tex> и построим от нее часть <tex>A_2</tex>. Теперь добавим состояние <tex>q_0</tex> и соединим с ним все терминальные состояния из <tex>A_2</tex> с помощью <tex>\varepsilon-</tex>переходов. Далее построим от <tex>q_0</tex> часть <tex>A_1</tex>. Добавим вершину <tex>q'</tex>, эквивалентную <tex>q</tex>, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины <tex>q</tex>. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой <tex>q</tex>. Для этого создадим новую стартовую вершину <tex>q_0'</tex> и свяжем ее <tex>\varepsilon-</tex>переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих <tex>q</tex>), в том числе и с изначальным автоматом. Построенный автомат допускает язык <tex>cycle(L)</tex>, следовательно, данный язык является регулярным.
 
Так как <tex>L</tex> {{---}} регулярный язык, то существует допускающий его ДКА <tex>M = \langle \Sigma , Q , q_0 , F , \delta \rangle </tex>. Построим из <tex>M</tex> недетерминированный автомат с <tex>\varepsilon-</tex>переходами следующим образом: рассмотрим состояние <tex>q \in Q</tex>, из которого есть переходы в другие состояния (то есть начиная с <tex>q</tex> можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с <tex>q</tex>, станет префиксом нового слова, а префикс, заканчивающийся в <tex>q</tex> {{---}} суффиксом. Разделим автомат на две части <tex>A_1</tex> и <tex>A_2</tex> такие, что <tex>A_1</tex> будет содержать все вершины, из которых достижима <tex>q</tex>, а <tex>A_2</tex> {{---}} все вершины, которые достижимы из <tex>q</tex> (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат <tex>M</tex> содержит циклы. Теперь перестроим автомат так, что он будет принимать слова "зацикленные" вокруг <tex>q</tex>, то есть начинающиеся с <tex>q</tex> и после достижения терминальной вершины продолжающиеся с <tex>q_0</tex> (см. рис. 2). Для этого стартовой вершиной сделаем <tex>q</tex> и построим от нее часть <tex>A_2</tex>. Теперь добавим состояние <tex>q_0</tex> и соединим с ним все терминальные состояния из <tex>A_2</tex> с помощью <tex>\varepsilon-</tex>переходов. Далее построим от <tex>q_0</tex> часть <tex>A_1</tex>. Добавим вершину <tex>q'</tex>, эквивалентную <tex>q</tex>, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины <tex>q</tex>. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой <tex>q</tex>. Для этого создадим новую стартовую вершину <tex>q_0'</tex> и свяжем ее <tex>\varepsilon-</tex>переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих <tex>q</tex>), в том числе и с изначальным автоматом. Построенный автомат допускает язык <tex>cycle(L)</tex>, следовательно, данный язык является регулярным.
 
}}
 
}}
[[Файл:Ex_1_before.jpg|left|thumb|240px|Рис. 3. Автомат, принимающий язык <tex>L</tex>.]]
+
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык <tex>L</tex>.]]
[[Файл:Ex_1_after.jpg|right|thumb|300px|Рис. 4. Автомат, принимающий язык <tex>cycle(L)</tex>.]]
+
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык <tex>cycle(L)</tex>.]]
 
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.<br>
 
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.<br>
 
На рис. 3 представлен автомат, допускающий язык <tex>L = \{ ab, abb, ac \}</tex>. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин <tex>2</tex> и <tex>3</tex>. Появилась новая стартовая вершина <tex>0</tex>, которая связана <tex>\varepsilon-</tex>переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык <tex>cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}</tex>: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины <tex>2</tex>; последнее слово распознает третья часть, зацикленная относительно вершины <tex>3</tex>.
 
На рис. 3 представлен автомат, допускающий язык <tex>L = \{ ab, abb, ac \}</tex>. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин <tex>2</tex> и <tex>3</tex>. Появилась новая стартовая вершина <tex>0</tex>, которая связана <tex>\varepsilon-</tex>переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык <tex>cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}</tex>: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины <tex>2</tex>; последнее слово распознает третья часть, зацикленная относительно вершины <tex>3</tex>.

Версия 11:32, 15 декабря 2016

Примеры доказательств

Язык [math]half(L)[/math]

Определение:
Определим [math]half(L)[/math] как множество первых половин цепочек языка [math]L[/math], то есть множество [math]\{ w \mid [/math] существует [math]x[/math], для которой [math]wx \in L[/math], причем [math]|w| = |x| \}[/math].

Например, если [math]L = \{ \varepsilon, 0010, 011, 010110 \}[/math], то [math]half(L) = \{ \varepsilon, 00, 010 \}[/math]. Заметим, что цепочки нечетной длины не влияют на [math]half(L)[/math].

Утверждение:
Пусть [math]L[/math] — регулярный язык. Тогда язык [math]half(L)[/math] также регулярен.
[math]\triangleright[/math]

Так как [math]L[/math] — регулярный язык, то существует ДКА [math]M = \langle \Sigma , Q , q_0 , F , \delta \rangle [/math], допускающий его. Рассмотрим строку [math]x[/math]. Для того, чтобы проверить, что [math]x \in half(L)[/math], нам надо убедиться, что существует строка [math]y[/math] такой же длины, что и [math]x[/math], которая, будучи сконкатенированной с [math]x[/math], даст строку из [math]L[/math], то есть если на вход автомату подать [math]xy[/math], то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку [math]x[/math], находится в состоянии [math]q_i[/math], то есть [math]\delta(q_0, x) = q_i[/math]. Мы должны проверить, что существует строка [math]y, |y| = |x|,[/math] которая ведет из состояния [math]q_i[/math] до какого-нибудь терминального состояния [math]M[/math], то есть [math]\delta(q_i, y) \in F[/math].
Предположим, что мы прошли [math]n[/math] вершин автомата, то есть [math]|x| = n[/math]. Обозначим за [math]S_n[/math] множество всех состояний, с которых можно попасть в терминальные за [math]n[/math] шагов. Тогда [math]q_i \in S_n \Leftrightarrow x \in half(L)[/math]. Если мы сможем отслеживать [math]S_n[/math] и [math]q_i[/math], то сможем определять, верно ли, что [math]x \in half(L)[/math]. Заметим, что [math]S_0 \equiv F[/math]. Очевидно мы можем построить [math]S_{n+1}[/math] зная [math]S_n[/math] и [math]\delta[/math]: [math]S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}[/math] — множество состояний, из которых есть переход в какое-либо состояние из [math]S_n[/math] (по единственному символу). Теперь надо найти способ отслеживать и обновлять [math]S_n[/math].
Построим ДКА [math]M'[/math], который будет хранить эту информацию в своих состояниях. Определим [math]Q' = Q \times 2^Q[/math], то есть каждое состояние [math]M'[/math] — это пара из одиночного состояния из [math]M[/math] и множества состояний из [math]M[/math]. Функцию перехода [math]\delta'[/math] автомата [math]M'[/math] определим так, чтобы если по какой-то строке [math]x[/math] длины [math]n[/math] в автомате [math]M[/math] мы перешли в состояние [math]q_i[/math], то по этой же строке в автомате [math]M'[/math] мы перейдем в состояние [math](q_i, S_n)[/math], где [math]S_n[/math] — множество состояний из [math]M[/math], определенное выше. Вспомним приведенную выше функцию [math]prev(S_n) = S_{n+1}[/math]. С ее помощью мы можем определить функцию перехода следующим образом: [math]\delta'((q, S), a) = (\delta(q, a), prev(S))[/math]. Начальное состояние [math]q_0' = (q_0, S_0) = (q_0, F)[/math]. Множество терминальных состояний — [math]F' = \{ (q, S) \mid q \in S, S \in 2^Q \}[/math].

Теперь по индукции не сложно доказать, что [math]\delta'(q_0', x) = (\delta(q_0, x), S_n)[/math], где [math]|x| = n[/math]. По определению множества терминальных вершин, автомат [math]M'[/math] допускает строку [math]x[/math] тогда и только тогда, когда [math]\delta(q_0, x) \in S_n[/math]. Следовательно, автомат [math]M'[/math] допускает язык [math]half(L)[/math].Таким образом, мы построили ДКА, который допускает язык [math]half(L)[/math]. Следовательно, данный язык является регулярным.
[math]\triangleleft[/math]

Язык [math]alt(L, M)[/math]

Определение:
Пусть [math]w = w_1 w_2 \dots w_n[/math] и [math]x = x_1 x_2 \dots x_n[/math]. Определим [math]alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n[/math]. Распространим это определение на языки следующим образом: пусть [math]L[/math] и [math]M[/math] — два языка над одним алфавитом [math]\Sigma[/math]. Тогда [math]alt(L, M) = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}[/math].


Утверждение:
Пусть [math]L[/math] и [math]M[/math] — регулярные языки. Тогда [math]alt(L, M)[/math] также является регулярным.
[math]\triangleright[/math]
Так как [math]L[/math] и [math]M[/math] — регулярные языки, то существуют ДКА [math]D_L = \langle \Sigma , Q_L , q_{0L} , F_L , \delta_L \rangle [/math], распознающий язык [math]L[/math], и [math]D_M = \langle \Sigma , Q_M , q_{0M} , F_M , \delta_M \rangle [/math], распознающий [math]M[/math].
[math]\triangleleft[/math]

Язык [math]cycle(L)[/math]

Определение:
Определим [math]cycle(L)[/math] как множество [math]\{ w \mid [/math] цепочку [math]w[/math] можно представить в виде [math]w = xy[/math], где [math]yx \in L \}[/math].

Например, если [math]L = \{ 01, 011 \}[/math], то [math]cycle(L) = \{ 01, 10, 011, 110, 101 \}[/math].

Утверждение:
Пусть [math]L[/math] — регулярный язык. Тогда язык [math]cycle(L)[/math] также регулярен.
[math]\triangleright[/math]
Рис. 1. Разбиение автомата.
Рис. 2. Перестроение.
Так как [math]L[/math] — регулярный язык, то существует допускающий его ДКА [math]M = \langle \Sigma , Q , q_0 , F , \delta \rangle [/math]. Построим из [math]M[/math] недетерминированный автомат с [math]\varepsilon-[/math]переходами следующим образом: рассмотрим состояние [math]q \in Q[/math], из которого есть переходы в другие состояния (то есть начиная с [math]q[/math] можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с [math]q[/math], станет префиксом нового слова, а префикс, заканчивающийся в [math]q[/math] — суффиксом. Разделим автомат на две части [math]A_1[/math] и [math]A_2[/math] такие, что [math]A_1[/math] будет содержать все вершины, из которых достижима [math]q[/math], а [math]A_2[/math] — все вершины, которые достижимы из [math]q[/math] (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат [math]M[/math] содержит циклы. Теперь перестроим автомат так, что он будет принимать слова "зацикленные" вокруг [math]q[/math], то есть начинающиеся с [math]q[/math] и после достижения терминальной вершины продолжающиеся с [math]q_0[/math] (см. рис. 2). Для этого стартовой вершиной сделаем [math]q[/math] и построим от нее часть [math]A_2[/math]. Теперь добавим состояние [math]q_0[/math] и соединим с ним все терминальные состояния из [math]A_2[/math] с помощью [math]\varepsilon-[/math]переходов. Далее построим от [math]q_0[/math] часть [math]A_1[/math]. Добавим вершину [math]q'[/math], эквивалентную [math]q[/math], и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины [math]q[/math]. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой [math]q[/math]. Для этого создадим новую стартовую вершину [math]q_0'[/math] и свяжем ее [math]\varepsilon-[/math]переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих [math]q[/math]), в том числе и с изначальным автоматом. Построенный автомат допускает язык [math]cycle(L)[/math], следовательно, данный язык является регулярным.
[math]\triangleleft[/math]
Рис. 3. Автомат, принимающий язык [math]L[/math].
Рис. 4. Автомат, принимающий язык [math]cycle(L)[/math].

Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.
На рис. 3 представлен автомат, допускающий язык [math]L = \{ ab, abb, ac \}[/math]. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные относительно вершин [math]2[/math] и [math]3[/math]. Появилась новая стартовая вершина [math]0[/math], которая связана [math]\varepsilon-[/math]переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык [math]cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}[/math]: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три — вторая, перестроенная относительно вершины [math]2[/math]; последнее слово распознает третья часть, зацикленная относительно вершины [math]3[/math].