Тверской государственный университет
Опубликован: 21.08.2007 | Доступ: свободный | Студентов: 1686 / 244 | Оценка: 5.00 / 5.00 | Длительность: 14:18:00
ISBN: 978-5-94774-714-0
Специальности: Программист, Математик
Лекция 5:

Регулярные языки и конечные автоматы

< Лекция 4 || Лекция 5: 123 || Лекция 6 >
Аннотация: Операции конкатенации и итерации языков. Регулярные выражения и языки. Примеры регулярных выражений и языков. Построение конечного автомата по регулярному выражению

Регулярные выражения и языки

Регулярные выражения являются достаточно удобным средством для построения "алгебраических" описаний языков. Они строятся из элементарных выражений \varnothing , \varepsilon , a \in  \Sigma с помощью операций объединения ( + ), конкатенации ( \hat{} ) и итерации ( * ). Каждому такому выражению r соответствует представляемый им язык Lr. Смысл операции объединения языков мы знаем. Определим операции конкатенации и итерации (иногда ее называют замыканием Клини).

Пусть L1 и L2 - языки в алфавите \Sigma.

Тогда L= L_{1} \hat{}  L_{2}=  \{  w  |  (\exists  w_{1} \in  L_{1}) (\exists  w_{2} \in  L_{2}) (w = w_{1}w_{2})\}, т.е. конкатенация языков состоит из конкатенаций всех слов первого языка со всеми словами второго языка. В частности, если \varepsilon  \in  L_{1}, то L_{2} \subseteq  L, а если \varepsilon  \in  L_{2}, то L_{1} \subseteq  L.

Введем обозначения для "степеней" языка L:

L^0=\{ \varepsilon\},\\ 
L^1= L,\\ 
L^{i+1} = L \circ L^i\ \ \ (i=1,2,\ldots).\\

Таким образом в Li входят все слова, которые можно разбить на i подряд идущих слов из L.

Итерацию (L)* языка L образуют все слова которые можно разбить на несколько подряд идущих слов из L:

(L)^*=\{ \varepsilon\} \cup \{ w\ |\  (\exists k \geq 1)( w=w_1w_2\ldots w_k) \textit{ и все}\ w_i \in L\}

Ее можно представить с помощью степеней:

(L)^*= \bigcup_{i=0}^{\infty} L^i

Часто удобно рассматривать "усеченную" итерацию языка, которая не содержит пустое слово, если его нет в языке: L^+= \bigcup_{i=1}^{\infty} L^i. Это не новая операция, а просто удобное сокращение для выражения L\circ L^*.

Отметим также, что если рассматривать алфавит \Sigma =\{ a_{1}, \dots  , a_{m}\} как конечный язык, состоящий из однобуквенных слов, то введенное ранее обозначение \Sigma ^{*} для множества всех слов, включая и пустое, в алфавите \Sigma соответствует определению итерации \Sigma ^* этого языка.

В следующей таблице приведено формальное индуктивное определение регулярных выражений над алфавитом \Sigma и представляемых ими языков.

Выражение r Язык Lr
\varnothing L_{\varnothing }=\varnothing
\varepsilon L\_ \varepsilon =\{ \varepsilon \}
a\in \Sigma La={a}
Пусть r1 и r2 -это Lr1 и Lr2 -представляемые
регулярные выражения. ими языки.
Тогда следующие выражения
являются регулярными и представляют языки:
r=(r1+r2) L_{r}=L_{r1}\cup L_{r2}
r=(r1circr2) L_{r}=L_{r1}\hat{} L_{r2}
r=(r1)* Lr=Lr1*

При записи регулярных выражений будем опускать знак конкатенации \hat{} и будем считать, что операция * имеет больший приоритет, чем конкатенация и +, а конкатенация - больший приоритет, чем +. Это позволит опустить многие скобки. Например, (((1\hat{} 0)\hat{} ((1)^{*}+0)) можно записать как 10(1* + 0).

Определение 5.1. Два регулярных выражения r и p называются эквивалентными, если совпадают представляемые ими языки, т.е. Lr=Lp. В этом случае пишем r = p.

Нетрудно проверить, например, такие свойства регулярных операций:

  • r + p= p+ r (коммутативность объединения),
  • (r+p) +q = r + (p+q) (ассоциативность объединения),
  • (r p) q = r (p q) (ассоциативность конкатенации),
  • (r*)* = r* (идемпотентность итерации ),
  • (r +p) q = rq + pq (дистрибутивность).

Пример 5.1. Докажем в качестве примера не столь очевидное равенство: (r + p)* = (r*p*)*.

Пусть L1 - язык, представляемый его левой частью, а L2 - правой. Пустое слово \varepsilon принадлежит обоим языкам. Если непустое слово w \in  L_{1}, то по определению итерации оно представимо как конкатенация подслов, принадлежащих языку L_{r} \cup  L_{p}. Но этот язык является подмножеством языка L'=Lr*Lp* (почему?). Поэтому w \in  L_{2} = (L')^{*}. Обратно, если слово w \in  L_{2}, то оно представимо как конкатенация подслов, принадлежащих языку L'. Каждое из таких подслов v представимо в виде v= v11... vk1 v12... vl2, где для всех i=1, ... , k подслово v_{i}^{1} \in  L_{r} и для всех j=1, ... , l подслово v_{j}^{2} \in  L_{p} (возможно, что k или l равно 0). Но это значит, что w является конкатенацией подслов, каждое из которых принадлежит L_{r} \cup  L_{p} и, следовательно, w \in  L_{1}.

Рассмотрим несколько примеров регулярных выражений и представляемых ими языков.

Пример 5.2. Регулярное выражение (0 +1)* представляет множество всех слов в алфавите {0, 1}.

Пример 5.3. Регулярное выражение 11(0 +1)*001 представляет язык, состоящий из всех слов в алфавите {0, 1}, которые начинаются на '11', а заканчиваются на '001'.

Пример 5.4. Регулярное выражение (1 +01 +001)^{*}(\varepsilon  + 0 +00) представляет язык, состоящий из всех слов в алфавите {0, 1}, которые не содержат подслово '000' ( см. задачу 5.3).

Пример 5.5. Регулярное выражение 1*(01*01*)* представляет язык L, состоящий из всех слов в алфавите {0, 1}, в которых четное число нулей.

Действительно, каждое слово из L либо вообще не содержит нулей, т.е. входит в язык, представляющий 1*, либо может быть разбито на блоки вида 01i01j, i,j >= 0, которым, быть может, предшествует блок единиц. Выражение (01*01*), очевидно задает один такой блок, а его итерация - произвольную последовательность таких блоков.

Пример 5.6. Построим теперь регулярное выражение, представляющее язык L0ч1ч, который состоит из всех слов в алфавите {0, 1}, содержащих четное число нулей и четное число единиц.

Пусть w=w1w2 ... wn - произвольное слово из L0ч1ч. Тогда, разумеется, n - четно, пусть n=2k. Разобьем w на пары соседних букв pi =w2i-1w2i, i= 1,2,... ,k. Возможны 4 вида таких пар: 00, 11, 01 и 10. Пар вида 00 и 11 может быть сколько угодно, а пар вида 01 и 10 обязательно четное число. Поэтому w разбивается на блоки, каждый из которых начинается одной из пар 01 или 10 и содержит еще одну такую пару. Каждый такой блок описывается выражением (01 +10)(00 + 11)*(01+10)(00 + 11)*. При этом перед первым блоком может быть префикс, состоящий из пар 00 и 11. Множество слов состоящих из пар 00 и 11 задается выражением (00 +11)*. Отсюда получаем выражение R0ч1ч, задающее язык L0ч1ч:

R_{0\textit{ч}1\textit{ч} }= (00 +11)^*((01 +10)(00 + 11)^*(01+10)(00 + 11)^*)^*
< Лекция 4 || Лекция 5: 123 || Лекция 6 >