|
| 1 | +\setchapterpreamble[u]{\margintoc} |
| 2 | +\chapter{Регулярные языки} |
| 3 | + |
| 4 | +В данном разделе мы обсудим регулярные языки~--- класс, лежащий на самом нижнем уровне иерархии Хомского. |
| 5 | +Будут рассмотрены основные способы задания таких языков: \emph{регулярные выражения}, \emph{конечные автоматы}, \emph{лево(право)линейные грамматики}. |
| 6 | +Обсудим основные свойства регулярных языков, такие как замкнутость относительно различных операций, а также различные свойства соответствующих автоматов и грамматик. |
| 7 | + |
| 8 | +\section{Регулярные выражения} |
| 9 | + |
| 10 | +Регулярные выражения~--- один из классических способов задать регулярный язык% |
| 11 | +\sidenote{ |
| 12 | + Замечание для программистов. |
| 13 | + Важно понимать, что речь идёт о формальной конструкции, а не о том, что называется регулярными выражениями в различных языках программирования или библиотеках, где под названием \enquote{регулярные выражения} могут скрываться конструкции, существенно более выразительные, чем обсуждаемые здесь. |
| 14 | +}. |
| 15 | +Основывается этот способ на предложении синтаксиса для описания \emph{регулярных множеств}% |
| 16 | +\sidenote{Помним, что язык~--- это множество слов.}. |
| 17 | + |
| 18 | +\begin{definition}[Регулярное множество] |
| 19 | + Регулярное множество (над алфавитом $\Sigma$) это: |
| 20 | + \begin{itemize} |
| 21 | + \item $\varnothing$; |
| 22 | + \item $\{\varepsilon\}$; |
| 23 | + \item $\{t\}$, $t \in \Sigma$; |
| 24 | + \item $R_1 \cup R_2$, где $R_1$ и $R_2$~--- регулярные множества; |
| 25 | + \item $R_1 \cdot R_2$, где $R_1$ и $R_2$~--- регулярные множества; |
| 26 | + \item $R^*$, где $R$~--- регулярное множество. |
| 27 | + \end{itemize} |
| 28 | +\end{definition} |
| 29 | + |
| 30 | +Для того, чтобы описывать такие множества, удобно пользоваться \emph{регулярными выражениями}. |
| 31 | + |
| 32 | +\begin{definition}[Регулярное выражение] |
| 33 | + Регулярное выражение (над алфавитом $\Sigma$) это: |
| 34 | + \begin{itemize} |
| 35 | + \item $\varnothing$; |
| 36 | + \item $\varepsilon$; |
| 37 | + \item $t$, $t \in \Sigma$; |
| 38 | + \item $R_1 \mid R_2$, где $R_1$ и $R_2$~--- регулярные выражения; |
| 39 | + \item $R_1 \cdot R_2$, где $R_1$ и $R_2$~--- регулярные выражения; |
| 40 | + \item $R^*$, где $R$~--- регулярное выражение; |
| 41 | + \item $(R)$, где $R$~--- регулярное выражение. |
| 42 | + \end{itemize} |
| 43 | +\end{definition} |
| 44 | + |
| 45 | +Отметим несколько важных с прикладной точки зрения моментов. |
| 46 | +Во-первых, часто используется расширенный синтаксис, в который добавляются конструкции не увеличивающие выразительную силу, но упрощающие запись. |
| 47 | +Например, встречаются следующие расширения% |
| 48 | +\sidenote{ |
| 49 | + Существуют и другие, однако их мы не будем использовать и, соответственно, рассматривать. |
| 50 | + Читатель может вспомнить, что называется регулярными выражениями в его любимом языке программирования и попробовать самостоятельно выразить имеющиеся там конструкции через базовые.}. |
| 51 | +\begin{itemize} |
| 52 | + \item $R? = R \mid \varepsilon$, где $R$~--- регулярное выражение. |
| 53 | + \item $R^+ = R \cdot R^*$, где $R$~--- регулярное выражение. |
| 54 | +\end{itemize} |
| 55 | + |
| 56 | +Во-вторых, конструкции $\varnothing$ и $\varepsilon$ используются крайне редко, особенно в случае расширенного синтаксиса, так как часто выражение, эквивалентное использующему данные конструкции, часто более компактно записывается с использованием расширенного синтаксиса. |
| 57 | +В-третьих, оператор конкатенации часто опускается% |
| 58 | +\sidenote{Как и знак умножения во многих математических записях.}. |
| 59 | + |
| 60 | +Рассмотрим несколько примеров регулярных выражений. |
| 61 | +\begin{example} |
| 62 | + Регулярное выражение $a$ задаёт регулярное множество $\{a\}$ и, соответственно, язык из единственного слова $a$. |
| 63 | +\end{example} |
| 64 | + |
| 65 | +\begin{example} |
| 66 | + Регулярное выражение $ab$ задаёт регулярное множество $\{ab\}$ и, соответственно, язык из единственного слова $ab$. |
| 67 | +\end{example} |
| 68 | + |
| 69 | + |
| 70 | +\begin{example} |
| 71 | + Регулярное выражение $a^*$ задаёт регулярное множество $$R = \bigcup_{i=0}^{\infty}{a^i} = \{\varepsilon, a, aa, aaa, \ldots \}$$ и, соответственно, бесконечный язык, содержащий для любого неотрицательного целого $n$ цепочку из символов $a$ длины $n$. |
| 72 | +\end{example} |
| 73 | + |
| 74 | + |
| 75 | +\begin{example} |
| 76 | + $a^*b$ |
| 77 | +\end{example} |
| 78 | + |
| 79 | +\begin{example} |
| 80 | + $(a\mid b)^*$ |
| 81 | +\end{example} |
| 82 | + |
| 83 | +\begin{example} |
| 84 | + $(ab)^*c?$ |
| 85 | +\end{example} |
| 86 | + |
| 87 | +\section{Конечные автоматы} |
| 88 | + |
| 89 | +\emph{Конечный автомат}~--- вычислительная машина, которая имеет конечный набор состояний и может совершать переходы между ними, читая входные данные. |
| 90 | +Важно отметить, что ни какой дополнительной памяти классический конечный автомат не имеет% |
| 91 | +\sidenote{Существуют автоматы с константной памятью, регистрами} и не производит дополнительных действий% |
| 92 | +\sidenote{Автоматы с записью на ленту, и т.д.}. |
| 93 | + |
| 94 | +\begin{definition}[Недетерминированный конечный автомат] |
| 95 | + \label{def:NondeterminicticFiniteAutomata} |
| 96 | + \emph{Недетерминированный конечный автомат} (НКА)~--- это пятёрка $M = \langle Q, Q_S, Q_F, \delta, \Sigma \rangle$, где |
| 97 | + \begin{itemize} |
| 98 | + \item $Q$~--- конечное множество состояний; |
| 99 | + \item $Q_S \subseteq= Q$~--- множество стартовых состояний; |
| 100 | + \item $Q_F \subseteq Q$~--- множество финальных состояний; |
| 101 | + \item $\delta \subseteq Q \times (\Sigma \cup \varepsilon) \times 2^Q$~--- функция переходов, а $\varepsilon \notin \Sigma$; |
| 102 | + \item $\Sigma$~--- конечный алфавит. |
| 103 | + \end{itemize} |
| 104 | +\end{definition} |
| 105 | + |
| 106 | +Так как нас интересуют конечные автоматы в контексте языков, то будем говорить, что на ленте автомата записано какое-то слово (или строка). |
| 107 | +Иными словами, будем говорить, что автомат принимает на вход слово или строку. |
| 108 | + |
| 109 | +Процесс вычислений, проделываемых конечным автоматом, удобно описывать в терминах переходов между \emph{конфигурациями}. |
| 110 | + |
| 111 | +\begin{definition}[Конфигурация] |
| 112 | + Конфигурация $c$ конечного автомата $M = \langle Q, Q_S, Q_F, \delta, \Sigma \rangle$~--- это пара $(q, w)$, где $q\in Q$~--- это текущее состояние автомата, а $w \in \Sigma^*$~--- непросмотренная часть входной строки. |
| 113 | +\end{definition} |
| 114 | + |
| 115 | +\begin{definition}[Переход в НКА] |
| 116 | + Будем говорить, что автомат $M = \langle Q, Q_S, Q_F, \delta, \Sigma \rangle$ может перейти из конфигурации $c_1 = (q_1, w_1)$ в конфигурацию $c_2 = (q_2, w_2)$, если |
| 117 | + \[c_2 \in \{(q_2,w_2) \mid w_1 = aw_2, (q_1,a, q_2) \in \delta\} \cup \{(q_2,w_1) \mid (q_1, \varepsilon, q_2) \in \delta\}.\] |
| 118 | + Обозначать этот факт будем как $c_1 \to c_2$. |
| 119 | +\end{definition} |
| 120 | + |
| 121 | +\marginnote{TODO: Без идей что тут написано, но жирная стрелочка для перехода выглядит естественнее} |
| 122 | +$$С_2 = \{(q_2,w_2) \mid w_1 = aw_2, (q_1,a, q_2) \in \delta\} \cup \{(q_2,w_1) \mid (q_1, \varepsilon, q_2) \in \delta\}.$$ |
| 123 | +$$ c_1 \Rightarrow C_2 $$ |
| 124 | + |
| 125 | + |
| 126 | +Стартовая конфигурация. |
| 127 | + |
| 128 | +Финальная конфигурация. |
| 129 | + |
| 130 | +Ошибочная конфигурация. |
| 131 | + |
| 132 | +\begin{example} |
| 133 | + Пример интерпретации конечного автомата. |
| 134 | +\end{example} |
| 135 | + |
| 136 | +\begin{definition}[Детерминированный конечный автомат] |
| 137 | + \label{def:DeterminicticFiniteAutomata} |
| 138 | + \emph{Детерминированный конечный автомат} (ДКА, Deterministic Finite Automata, DFA)~--- это пятёрка $M = \langle Q, q_S, Q_F, \delta, \Sigma \rangle$, где |
| 139 | + \begin{itemize} |
| 140 | + \item $Q$~--- конечное множество состояний; |
| 141 | + \item $q_S \in Q$~--- стартовое состояние; |
| 142 | + \item $Q_F \subseteq Q$~--- множество финальных состояний; |
| 143 | + \item $\delta \subseteq Q \times \Sigma \times Q$~--- функция переходов; |
| 144 | + \item $\Sigma$~--- конечный алфавит. |
| 145 | + \end{itemize} |
| 146 | +\end{definition} |
| 147 | + |
| 148 | +Заметим, что функцию переходов можно представить разными способами в зависимости от того, как именно представлена функция переходов: список троек, матрица, граф. |
| 149 | + |
| 150 | +\begin{example} |
| 151 | + Пример КА. |
| 152 | + % \begin{tikzpicture} |
| 153 | + |
| 154 | + % \end{tikzpicture} |
| 155 | +\end{example} |
| 156 | + |
| 157 | +\begin{example} |
| 158 | + Пример интерпретации конечного автомата. |
| 159 | +\end{example} |
| 160 | + |
| 161 | +Построение КА по регулярному выражению и регулярному выражению по КА. На производных. |
| 162 | + |
| 163 | +Построение регулярного выражения по КА. |
| 164 | + |
| 165 | +Алгоритмы: проверка пустоты ... |
| 166 | + |
| 167 | +Примеры. |
| 168 | + |
| 169 | + |
| 170 | +\section{Лево(право)линейные грамматики} |
| 171 | + |
| 172 | +Наложив некоторые ограничения на внешний вид правил грамматики можно получить грамматики, задающие регулярные языки. |
| 173 | + |
| 174 | +\begin{definition}[Леволинейная грамматика] |
| 175 | + Грамматика $G=\langle \Sigma, N, P, S \rangle$ называется леволиненйной, если все её правила имеют вид |
| 176 | + \[N_i \to \alpha w,\] |
| 177 | + где $N_i \in N$, $\alpha \in \{\varepsilon\} \cup N$, $w \in \Sigma ^*$. |
| 178 | +\end{definition} |
| 179 | + |
| 180 | +\begin{definition}[Праволинейная грамматика] |
| 181 | + Грамматика $G=\langle \Sigma, N, P, S \rangle$ называется праволиненйной, если все её правила имеют вид |
| 182 | + \[N_i \to w \alpha,\] |
| 183 | + где $N_i \in N$, $\alpha \in \{\varepsilon\} \cup N$, $w \in \Sigma ^*$. |
| 184 | +\end{definition} |
| 185 | + |
| 186 | +Ноам Хомский и Джордж Миллер в работе~\sidecite{chomsky1958finite} показали, что лево(право)линейные грамматики задают регулярные языки. |
| 187 | +Приведём процедуры построения автомата по грамматике и наоборот, грамматики по автомату. |
| 188 | + |
| 189 | +Пусть дан конечный автомат $M = \langle \Sigma, Q, q_s, Q_f, \delta \rangle$. По нему можно построить праволинейную грамматику $G=\langle \Sigma, N, S, P \rangle$, где |
| 190 | +\begin{itemize} |
| 191 | + \item $N = Q$ |
| 192 | + \item $P = \{ q_i \to t q_j \mid (q_i, t, q_j)\in \delta\} \cup \{ q_i \to \varepsilon \mid q_i \in Q_F\}$ |
| 193 | + \item $S = q_s$ |
| 194 | +\end{itemize} |
| 195 | + |
| 196 | +Аналогичным образом строится автомат по праволинейной грамматике. |
| 197 | +Упростить процедуру можно если заранее привести правила к виду $N_i \to tN_j$, где $t\in \Sigma$, добавив необходимое количество новых нетерминалов: |
| 198 | +правило вида $N_i \to twN_k$ преобразуется в два правила |
| 199 | +\begin{align*} |
| 200 | + N_i & \to tN_l \\ |
| 201 | + N_l & \to wN_k, |
| 202 | +\end{align*} |
| 203 | +после чего аналогично преобразуется правило для $N_l$. |
| 204 | + |
| 205 | +Пример построения грамматики по автомату. |
| 206 | + |
| 207 | +Автомат по грамматике. |
| 208 | + |
| 209 | +\section{Лемма о накачке} |
| 210 | + |
| 211 | +Лемма о накачке для регулярных языков позволяет проверить, что заданный язык не является регулярным. |
| 212 | + |
| 213 | +\begin{lemma} |
| 214 | + Пусть $L$~--- регулярный язык над алфавитом $\Sigma$, тогда существует такое $n$, что для любого слова $\omega \in L$, $|\omega| \geq n$ найдутся слова $x,y,z\in \Sigma^*$, для которых верно: $xyz = \omega, y\neq \varepsilon,|xy|\leq n$ и для любого $k \geq 0$ $xy^kz \in L$. |
| 215 | +\end{lemma} |
| 216 | + |
| 217 | +\begin{proofSketch} |
| 218 | + \begin{enumerate} |
| 219 | + \item Так как язык регулярный, то для него можно построить конечный автомат $M = \langle Q, q_s,Q_f, \delta, \Sigma \rangle$. |
| 220 | + В том числе, минимальный по количеству состояний. |
| 221 | + \item В качестве $n$ возьмём $|Q| + 1$. |
| 222 | + \item Легко заметить, что для любой цепочки $w \in L, |w| > n$ путь в автомате, соответствующий принятию данной цепочки, будет содержать хотя бы один цикл. |
| 223 | + Действительно, в ориентированном графе с $k$ вершинами (а именно таким является автомат по построению) максимальная длина пути без повторных посещений вершин (соответственно, без циклов) не больше $k - 1$. |
| 224 | + \item Выберем любой цикл. Он будет задавать искомые цепочки $x, y$ и $z$ так, как представлено на рисунке~\ref{fig:reg_lang_pumping_lemma}. |
| 225 | + Заметим, что вход в цикл и выход из него в общем случае могут не совпадать, что даёт несколько вариантов разбиения пути на части, и на рисунке представлен лишь один из возможных. |
| 226 | + \qedhere |
| 227 | + \end{enumerate} |
| 228 | +\end{proofSketch} |
| 229 | + |
| 230 | +\begin{figure} |
| 231 | + \caption{Иллюстрация идеи доказательства леммы о накачке для регулярных языков: любой путь в графе, длина которого достаточно большая, может быть разбит на три части из леммы ($x$~--- красный подпуть, $y$~--- синий, $z$~--- зелёный), а многократный проход по циклу $y$ позволяет \enquote{накачать} слово.} |
| 232 | + \label{fig:reg_lang_pumping_lemma} |
| 233 | + \begin{center} |
| 234 | + \begin{tikzpicture}[->] |
| 235 | + \node[state, initial] (q1) {$q_1$}; |
| 236 | + \node[state, right = 2 of q1] (q2) {$q_2$}; |
| 237 | + \node[state, accepting, right = 2 of q2] (q3) {$q_3$}; |
| 238 | + \node[state, above = 2 of q2] (q4) {$q_4$}; |
| 239 | + \draw (q1) edge[above, snake it] node{} (q2) |
| 240 | + (q2) edge[bend right, snake it, side by side={red}{blue}] node{} (q4) |
| 241 | + (q4) edge[bend right, snake it, color=blue] node[left]{$y$} (q2) |
| 242 | + (q4) edge[above, snake it, color=green] node[right]{$z$} (q3) |
| 243 | + (q1) edge[above, snake it, color=red] node{$x$} (q2) |
| 244 | + ; |
| 245 | + \end{tikzpicture} |
| 246 | + \end{center} |
| 247 | + |
| 248 | +\end{figure} |
| 249 | + |
| 250 | + |
| 251 | +\section{Замкнутость регулярных языков относительно операций} |
| 252 | + |
| 253 | +\begin{theorem} |
| 254 | + Регулярные языки замкнуты относительно перечисленных ниже операций. |
| 255 | + \begin{enumerate} |
| 256 | + \item Пересечение |
| 257 | + \item Дополнение |
| 258 | + \item Обращение |
| 259 | + \item Разность |
| 260 | + \end{enumerate} |
| 261 | +\end{theorem} |
| 262 | + |
| 263 | +Линейная алгебра для работы с регулярными языками: пересечение, замыкание. |
| 264 | + |
| 265 | +Построение пересечения через тензорное произведение автоматов. |
| 266 | + |
| 267 | +Идея доказательства, что мы построили именно пересечение. |
| 268 | + |
| 269 | +Пересечение через синхронный обход в ширину. |
| 270 | + |
| 271 | +%\section{Вопросы и задачи} |
| 272 | +% |
| 273 | +%Построить базу. |
| 274 | +% |
| 275 | +%Научиться выполнять запросы через линейку. |
0 commit comments