Двусторонний детерминированный конечный автомат — различия между версиями
Kabanov (обсуждение | вклад) (→Регулярность языков) |
м (rollbackEdits.php mass rollback) |
||
(не показано 9 промежуточных версий 4 участников) | |||
Строка 1: | Строка 1: | ||
{{Определение | {{Определение | ||
|definition= | |definition= | ||
− | '''Двусторонний детерминированный конечный автомат (2ДКА)''' (англ. ''Two-way deterministic finite automaton (2DFA)'') {{---}} набор из восьми элементов <tex>\langle \Sigma , Q, L, R, s, t, r, \delta \rangle</tex>, где <tex>\Sigma</tex> {{---}} алфавит | + | '''Двусторонний детерминированный конечный автомат (2ДКА)''' (англ. ''Two-way deterministic finite automaton (2DFA)'') {{---}} набор из восьми элементов <tex>M = \langle \Sigma , Q, L, R, s, t, r, \delta \rangle</tex>, где |
+ | * <tex>\Sigma</tex> {{---}} алфавит, | ||
+ | * <tex>Q</tex> {{---}} множество состояний, | ||
+ | * <tex>L \notin \Sigma</tex> {{---}} левый маркер конца строки (англ. ''left endmarker''), | ||
+ | * <tex>R \notin \Sigma</tex> {{---}} правый маркер конца строки (англ. ''right endmarker''), | ||
+ | * <tex>s \in Q</tex> — начальное (стартовое) состояние, | ||
+ | * <tex>t \in Q</tex> {{---}} допускающее состояние, | ||
+ | * <tex>r \in Q</tex> — отвергающее состояние, | ||
+ | * <tex>\delta : Q \times \{\Sigma \cup \{L, R\}\} \to Q \times \{left, right\}</tex> {{---}} функция переходов. | ||
}} | }} | ||
Также должны быть удовлетворены следующие условия: | Также должны быть удовлетворены следующие условия: | ||
Строка 13: | Строка 21: | ||
* <tex>\delta(t, R) = (t, left)</tex>, | * <tex>\delta(t, R) = (t, left)</tex>, | ||
* <tex>\delta(r, R) = (r, left)</tex>. | * <tex>\delta(r, R) = (r, left)</tex>. | ||
− | |||
− | |||
− | + | == Регулярность языка == | |
+ | {{Теорема | ||
+ | |statement=Классы языков ДКА и 2ДКА совпадают. | ||
+ | |proof= | ||
+ | Рассмотрим длинную входную строку <tex>w_1</tex> и разобьем на две подстроки <tex>w_1=xz</tex>. Будем считать, что <tex>w_1 = a_1 a_2 a_3 \dots a_n</tex>. Пусть <tex>a_0 = L</tex> и <tex>a_{n+1}=R</tex>. Так как у нас наш автомат может производить чтение в любом направлении, то граница <tex>x</tex> и <tex>z</tex> может быть пересечена несколько раз. Каждый раз, когда автомат пересекает границу справа налево (то есть из <tex>z</tex> в <tex>x</tex>), он выходит из <tex>z</tex> в состояние <tex>q</tex>. Когда пересечение происходит снова слева направо (если оно вообще происходит), то автомат выходит из <tex>x</tex> в состояние <tex>p</tex>. Теперь, если 2ДКА перейдет в <tex>x</tex> в состояние <tex>q</tex> заново, то он снова может появиться в состоянии <tex>p</tex>. Более того, состояние <tex>p</tex> зависит исключительно от <tex>q</tex> и <tex>x</tex>. Обозначим такое отношение через <tex>T_x(q) = p</tex>. Мы может записать все такие отношения в виде конечной таблицы <tex>T_x : Q \cup \{d\} \to Q \cup \{h\}</tex>, где <tex>Q</tex> {{---}} множество состояний 2ДКА, а <tex>d</tex> и <tex>h</tex> будут описаны ниже. | ||
− | + | На входной строке <tex>xz</tex> 2ДКА начнет чтение с левого маркера конца строки. В процессе работы автомата позиция чтения будет меняться. В конце концов это позиция пересечет слева направо границу между <tex>x</tex> и <tex>z</tex>. В первый раз это произойдет в каком-нибудь состоянии, которое будем называть <tex>T_x(d)</tex> (для этого мы и выделили <tex>d</tex>). Так же автомат может никогда не выйти из <tex>x</tex>. В таком случае мы запишем <tex>T_x(d) = h</tex>. Состояние <tex>T_x(d)</tex> дает немного информации о <tex>x</tex>, но только конечное количество, поскольку существует только конечное количество вариантов для <tex>T_x(d)</tex>. Отметим, что <tex>T_x(d)</tex> зависит только от <tex>x</tex> и не зависит от <tex>z</tex>. Если на вход подавалась бы строка <tex>xw</tex> вместо <tex>xz</tex>, то в таком случае при пересечении границы из <tex>x</tex> в <tex>w</tex> автомат также был бы в состоянии <tex>T_x(d)</tex>, потому что его значение до того момента определялось только <tex>x</tex> и до тех пор все, что находится справа от границы никак не влияет. | |
− | + | Если <tex>T_x(d) = h</tex>, то 2ДКА в бесконечном цикле внутри <tex>x</tex>, и он никогда не допустит и не отвергнет входную строку. | |
− | |||
− | + | Предположим, что 2ДКА переходит из <tex>x</tex> в <tex>z</tex> и спустя время переходит обратно в состояние <tex>q</tex>. Если это происходит, то потом: | |
− | |||
− | |||
− | |||
− | Предположим, что 2ДКА переходит из <tex>x</tex> в <tex>z</tex> и спустя время | ||
* либо снова произойдет переход из <tex>x</tex> в некоторое состояние <tex>p</tex>. В таком случае мы определим <tex>T_x(q)=p</tex>. | * либо снова произойдет переход из <tex>x</tex> в некоторое состояние <tex>p</tex>. В таком случае мы определим <tex>T_x(q)=p</tex>. | ||
* либо никогда не перейдет. В таком случае <tex>T_x(q) = h</tex>. | * либо никогда не перейдет. В таком случае <tex>T_x(q) = h</tex>. | ||
− | Ещё раз отметим, что <tex>T_x(q)</tex> зависит только от <tex>x</tex> и <tex>q</tex> и не зависит от <tex>z</tex>. Если автомат переходит в <tex>x</tex> справа в состояние <tex>q</tex>, то тогда он появится заново в состоянии <tex>T_x(q)</tex> (или никогда не перейдет, если <tex>T_x(q) = h</tex>), потому что автомат детерминированный, и | + | Ещё раз отметим, что <tex>T_x(q)</tex> зависит только от <tex>x</tex> и <tex>q</tex> и не зависит от <tex>z</tex>. Если автомат переходит в <tex>x</tex> справа в состояние <tex>q</tex>, то тогда он появится заново в состоянии <tex>T_x(q)</tex> (или никогда не перейдет, если <tex>T_x(q) = h</tex>), потому что автомат детерминированный, и его поведение полностью определяется <tex>x</tex> и состоянием, в которое он вошел. |
Если мы запишем <tex>T_x(q)</tex> для каждого состояния <tex>q</tex> вместе с <tex>T_x(d)</tex>, это даст нам всю информацию о <tex>x</tex>, которую можно перенести через границу между <tex>x</tex> и <tex>z</tex>. Все это позволит узнать <tex>T_x(d)</tex> сразу после пересечения границы, а также посмотреть значения <tex>T_x(q)</tex>. Если <tex>y</tex> {{---}} другая строка, такая что <tex>T_y=T_x</tex>, то тогда <tex>x</tex> и <tex>y</tex> будут неразличимы. | Если мы запишем <tex>T_x(q)</tex> для каждого состояния <tex>q</tex> вместе с <tex>T_x(d)</tex>, это даст нам всю информацию о <tex>x</tex>, которую можно перенести через границу между <tex>x</tex> и <tex>z</tex>. Все это позволит узнать <tex>T_x(d)</tex> сразу после пересечения границы, а также посмотреть значения <tex>T_x(q)</tex>. Если <tex>y</tex> {{---}} другая строка, такая что <tex>T_y=T_x</tex>, то тогда <tex>x</tex> и <tex>y</tex> будут неразличимы. | ||
Строка 37: | Строка 42: | ||
Заметим, что у нас конечное число возможных таблиц | Заметим, что у нас конечное число возможных таблиц | ||
<tex>T_x : Q \cup \{d\} \to Q \cup \{h\}</tex>, | <tex>T_x : Q \cup \{d\} \to Q \cup \{h\}</tex>, | ||
− | а именно <tex>(k+1)^{k+1}</tex>, где <tex>k</tex> {{---}} размер | + | а именно <tex>(k+1)^{k+1}</tex>, где <tex>k</tex> {{---}} размер множества <tex>Q</tex>. Таким образом, у нас конечное количество информации о <tex>x</tex>, которое мы может перенести через границу справа от <tex>x</tex>, и которое закодировано у нас в таблицe <tex>T_x</tex>. |
− | Отметим также, что если <tex>T_x=T_y</tex> и автомат допускает строку <tex>xz</tex>, то тогда он допускает и строку <tex>yz</tex>, потому что последовательность состояний перенесенных через границу <tex>x</tex> и <tex>z</tex> (либо <tex>y</tex> и <tex>z</tex>) в любом направлении полностью определяется таблицами <tex>T_x=T_y</tex> и строкой <tex>z</tex>. Чтобы допустить строку <tex>xz</tex>, автомат должен в какой-то момент прочитать правый маркер конца строки, находясь в допускающем состоянии <tex>t</tex>. | + | Отметим также, что если <tex>T_x=T_y</tex> и автомат допускает строку <tex>xz</tex>, то тогда он допускает и строку <tex>yz</tex>, потому что последовательность состояний, перенесенных через границу <tex>x</tex> и <tex>z</tex> (либо <tex>y</tex> и <tex>z</tex>) в любом направлении, полностью определяется таблицами <tex>T_x=T_y</tex> и строкой <tex>z</tex>. Чтобы допустить строку <tex>xz</tex>, автомат должен в какой-то момент прочитать правый маркер конца строки, находясь в допускающем состоянии <tex>t</tex>. |
Теперь мы может использовать теорему Майхилла-Нероуда, чтобы показать, что язык <tex>L(M)</tex> нашего автомата <tex>M</tex> [[Регулярные_языки:_два_определения_и_их_эквивалентность|регулярный]]. | Теперь мы может использовать теорему Майхилла-Нероуда, чтобы показать, что язык <tex>L(M)</tex> нашего автомата <tex>M</tex> [[Регулярные_языки:_два_определения_и_их_эквивалентность|регулярный]]. | ||
− | <tex>T_x = T_y \Rightarrow \forall z (M\ \text{accepts}\ xz \Leftrightarrow M\ \text{accepts}\ yz)</tex> <tex> \Leftrightarrow \forall z (xz \in L(M)</tex> <tex> \Leftrightarrow yz \in L(M)) \Leftrightarrow x \equiv_{L(M)} y</tex>, где <tex>\equiv_{L(M)}</tex> {{---}} [[Отношение_эквивалентности|отношение эквивалентности]] на множестве слов в алфавите. Таким образом, если 2 строки имеют одинаковые таблицы, то тогда они эквивалентны отношением <tex>\equiv_{L(M)}</tex>. Поскольку у нас только конечное число таблиц, отношение <tex>\equiv_{L(M)}</tex> имеет только конечное количество [[Отношение_эквивалентности|классов эквивалентности]], самое большее один для каждой таблицы. | + | <tex>T_x = T_y \Rightarrow \forall z (M\ \text{accepts}\ xz \Leftrightarrow M\ \text{accepts}\ yz)</tex> <tex> \Leftrightarrow \forall z (xz \in L(M)</tex> <tex> \Leftrightarrow yz \in L(M)) \Leftrightarrow x \equiv_{L(M)} y</tex>, где <tex>\equiv_{L(M)}</tex> {{---}} [[Отношение_эквивалентности|отношение эквивалентности]] на множестве слов в алфавите. Таким образом, если 2 строки имеют одинаковые таблицы, то тогда они эквивалентны отношением <tex>\equiv_{L(M)}</tex>. Поскольку у нас только конечное число таблиц, отношение <tex>\equiv_{L(M)}</tex> имеет только конечное количество [[Отношение_эквивалентности|классов эквивалентности]], самое большее один для каждой таблицы. Следовательно, по теореме Майхилла-Нероуда, <tex>L(M)</tex> {{---}} регулярный язык, что согласно теореме Клини, совпадает с классом и автоматных языков, ч.т.д. |
+ | }} | ||
== Пример == | == Пример == | ||
Рассмотрим следующий язык <tex>L_n = (a+b)^∗a(a+b)^{n-1}a(a+b)^∗</tex> при <tex>\forall n > 0</tex>. | Рассмотрим следующий язык <tex>L_n = (a+b)^∗a(a+b)^{n-1}a(a+b)^∗</tex> при <tex>\forall n > 0</tex>. | ||
− | Он может быть легко распознан с помощью следующего | + | Он может быть легко распознан с помощью следующего [[Недетерминированные_конечные_автоматы|недетерминированного конечного автомата]]. |
− | Теперь построим на его основе ДКА. Мы можем построить автомат <tex>A_n</tex>, который запоминает последние <tex>n</tex> входных символов. Следовательно, когда мы находимся | + | [[Файл:2dfa_example_1.png|600px]] |
+ | |||
+ | Теперь построим на его основе [[Детерминированные_конечные_автоматы|ДКА]]. Мы можем построить автомат <tex>A_n</tex>, который запоминает последние <tex>n</tex> входных символов. Следовательно, когда мы находимся в состоянии, соответствующему подстроке <tex>\sigma_1 \sigma_2 \dots \sigma_n</tex>, и читаем очередной символ <tex>\gamma</tex>, то мы переходим в состояние, которому уже будет соответствовать подстрока <tex>\sigma_2 \sigma_3 \dots \sigma_n \gamma</tex>. Однако, в случае <tex>\sigma_1 = \gamma = a</tex> автомат переходит в допускающее состояние, где в цикле может переходить на любому символу. Следует отметить, что такая стратегия строит ДКА c <tex>2^n + 1</tex> состояниями. Ниже представлен автомат <tex>A_3</tex>, который распознает язык <tex>L_3</tex>. | ||
+ | |||
+ | [[Файл:2dfa_example_2.png|500px]] | ||
Покажем, что построенные таким образом автоматы будут минимальными. | Покажем, что построенные таким образом автоматы будут минимальными. | ||
* Каждые две попарно различных строки <tex>x</tex> и <tex>y</tex> длины <tex>n</tex> различимы. Чтобы доказать это, достаточно рассмотреть строку <tex>b^{i-1}a</tex>, где <tex>i : 1 \leqslant i \leqslant n</tex> {{---}} самая левая позиция символа, в которой начинают различаться строки <tex>x</tex> и <tex>y</tex>, и проверить, что ровно одна строка <tex>xb^{i-1}a</tex> или <tex>yb^{i-1}a</tex> принадлежит <tex>L_n</tex>. | * Каждые две попарно различных строки <tex>x</tex> и <tex>y</tex> длины <tex>n</tex> различимы. Чтобы доказать это, достаточно рассмотреть строку <tex>b^{i-1}a</tex>, где <tex>i : 1 \leqslant i \leqslant n</tex> {{---}} самая левая позиция символа, в которой начинают различаться строки <tex>x</tex> и <tex>y</tex>, и проверить, что ровно одна строка <tex>xb^{i-1}a</tex> или <tex>yb^{i-1}a</tex> принадлежит <tex>L_n</tex>. | ||
− | * Каждая строка длины <tex>n</tex> не принадлежит <tex>L_n</tex> и, следовательно, различима | + | * Каждая строка длины <tex>n</tex> не принадлежит <tex>L_n</tex> и, следовательно, различима со строкой <tex>a^{n+1}</tex>, которая принадлежит <tex>L_n</tex>. |
* Таким образом, <tex>2^n + 1</tex> строк в <tex>\Sigma^n \cup \{a^{n+1}\}</tex> являются попарно различимыми для <tex>L_n</tex>. Как следствие, <tex>2^n + 1</tex> {{---}} минимальное количество состояний для ДКА, который способен распознать язык <tex>L_n</tex>. | * Таким образом, <tex>2^n + 1</tex> строк в <tex>\Sigma^n \cup \{a^{n+1}\}</tex> являются попарно различимыми для <tex>L_n</tex>. Как следствие, <tex>2^n + 1</tex> {{---}} минимальное количество состояний для ДКА, который способен распознать язык <tex>L_n</tex>. | ||
+ | |||
+ | Чтобы определить, что строка <tex>w=c_1 \dots c_n</tex> принадлежит языку <tex>L_n</tex>, нужно для <tex>\forall i = 1, \dots, |w|-n</tex> проверить, что <tex>c_i=c_{i+n}=a</tex>. Строка будет допустимой, если условие сработает хотя бы для одного <tex>i</tex>. Этот алгоритм может быть просто реализован с помощью 2ДКА. Будем для каждого <tex>i</tex> двигаться на <tex>n</tex> позиций вперед, а потом на <tex>n-1</tex> позиций назад до позиции <tex>i+1</tex>. Кроме того, при движении с позиции <tex>i</tex> до <tex>i+n</tex> автомат должен помнить сохраняется ли условие <tex>c_i=a</tex>. Такой подход требует <tex>O(n)</tex> состояний. | ||
== См. также == | == См. также == | ||
− | * [[ | + | * [[Локальные автоматы]] |
+ | * [[Теорема Клини (совпадение классов автоматных и регулярных языков)]] | ||
== Источники информации== | == Источники информации== | ||
− | + | * [[wikipedia:Two-way_deterministic_finite_automaton|Wikipedia {{---}} Two-way deterministic finite automaton]] | |
+ | * [[wikipedia:ru:Теорема_Майхилла_—_Нероуда|Википедия {{---}} Теорема Майхилла-Нероуда]] | ||
+ | * [http://arxiv.org/pdf/1208.2755.pdf Giovanni Pighizzini, ''Two-Way Finite Automata: Old and Recent Results''] | ||
+ | * [http://www.cs.cornell.edu/Courses/cs682/2008sp/Handouts/2DFA.pdf Cornell University, ''Two-Way Finite Automata''] | ||
+ | * [http://webcourse.cs.technion.ac.il/236807/Spring2012/ho/WCFiles/Two-way%20finite%20automata%20new.pdf Liat Peterfreund, ''Two-way finite automata & pebble automata''] | ||
[[Категория: Теория формальных языков]] | [[Категория: Теория формальных языков]] | ||
[[Категория: Автоматы и регулярные языки]] | [[Категория: Автоматы и регулярные языки]] | ||
+ | [[Категория: Другие автоматы]] |
Текущая версия на 19:38, 4 сентября 2022
Определение: |
Двусторонний детерминированный конечный автомат (2ДКА) (англ. Two-way deterministic finite automaton (2DFA)) — набор из восьми элементов
| , где
Также должны быть удовлетворены следующие условия:
- для некоторого ,
- для некоторого ,
и
- ,
- ,
- ,
- .
Регулярность языка
Теорема: |
Классы языков ДКА и 2ДКА совпадают. |
Доказательство: |
Рассмотрим длинную входную строку и разобьем на две подстроки . Будем считать, что . Пусть и . Так как у нас наш автомат может производить чтение в любом направлении, то граница и может быть пересечена несколько раз. Каждый раз, когда автомат пересекает границу справа налево (то есть из в ), он выходит из в состояние . Когда пересечение происходит снова слева направо (если оно вообще происходит), то автомат выходит из в состояние . Теперь, если 2ДКА перейдет в в состояние заново, то он снова может появиться в состоянии . Более того, состояние зависит исключительно от и . Обозначим такое отношение через . Мы может записать все такие отношения в виде конечной таблицы , где — множество состояний 2ДКА, а и будут описаны ниже.На входной строке 2ДКА начнет чтение с левого маркера конца строки. В процессе работы автомата позиция чтения будет меняться. В конце концов это позиция пересечет слева направо границу между и . В первый раз это произойдет в каком-нибудь состоянии, которое будем называть (для этого мы и выделили ). Так же автомат может никогда не выйти из . В таком случае мы запишем . Состояние дает немного информации о , но только конечное количество, поскольку существует только конечное количество вариантов для . Отметим, что зависит только от и не зависит от . Если на вход подавалась бы строка вместо , то в таком случае при пересечении границы из в автомат также был бы в состоянии , потому что его значение до того момента определялось только и до тех пор все, что находится справа от границы никак не влияет.Если , то 2ДКА в бесконечном цикле внутри , и он никогда не допустит и не отвергнет входную строку.Предположим, что 2ДКА переходит из в и спустя время переходит обратно в состояние . Если это происходит, то потом:
Ещё раз отметим, что зависит только от и и не зависит от . Если автомат переходит в справа в состояние , то тогда он появится заново в состоянии (или никогда не перейдет, если ), потому что автомат детерминированный, и его поведение полностью определяется и состоянием, в которое он вошел.Если мы запишем для каждого состояния вместе с , это даст нам всю информацию о , которую можно перенести через границу между и . Все это позволит узнать сразу после пересечения границы, а также посмотреть значения . Если — другая строка, такая что , то тогда и будут неразличимы.Заметим, что у нас конечное число возможных таблиц , а именно , где — размер множества . Таким образом, у нас конечное количество информации о , которое мы может перенести через границу справа от , и которое закодировано у нас в таблицe .Отметим также, что если и автомат допускает строку , то тогда он допускает и строку , потому что последовательность состояний, перенесенных через границу и (либо и ) в любом направлении, полностью определяется таблицами и строкой . Чтобы допустить строку , автомат должен в какой-то момент прочитать правый маркер конца строки, находясь в допускающем состоянии .Теперь мы может использовать теорему Майхилла-Нероуда, чтобы показать, что язык регулярный. нашего автомата , где — отношение эквивалентности на множестве слов в алфавите. Таким образом, если 2 строки имеют одинаковые таблицы, то тогда они эквивалентны отношением . Поскольку у нас только конечное число таблиц, отношение имеет только конечное количество классов эквивалентности, самое большее один для каждой таблицы. Следовательно, по теореме Майхилла-Нероуда, — регулярный язык, что согласно теореме Клини, совпадает с классом и автоматных языков, ч.т.д. |
Пример
Рассмотрим следующий язык
при .Он может быть легко распознан с помощью следующего недетерминированного конечного автомата.
Теперь построим на его основе ДКА. Мы можем построить автомат , который запоминает последние входных символов. Следовательно, когда мы находимся в состоянии, соответствующему подстроке , и читаем очередной символ , то мы переходим в состояние, которому уже будет соответствовать подстрока . Однако, в случае автомат переходит в допускающее состояние, где в цикле может переходить на любому символу. Следует отметить, что такая стратегия строит ДКА c состояниями. Ниже представлен автомат , который распознает язык .
Покажем, что построенные таким образом автоматы будут минимальными.
- Каждые две попарно различных строки и длины различимы. Чтобы доказать это, достаточно рассмотреть строку , где — самая левая позиция символа, в которой начинают различаться строки и , и проверить, что ровно одна строка или принадлежит .
- Каждая строка длины не принадлежит и, следовательно, различима со строкой , которая принадлежит .
- Таким образом, строк в являются попарно различимыми для . Как следствие, — минимальное количество состояний для ДКА, который способен распознать язык .
Чтобы определить, что строка
принадлежит языку , нужно для проверить, что . Строка будет допустимой, если условие сработает хотя бы для одного . Этот алгоритм может быть просто реализован с помощью 2ДКА. Будем для каждого двигаться на позиций вперед, а потом на позиций назад до позиции . Кроме того, при движении с позиции до автомат должен помнить сохраняется ли условие . Такой подход требует состояний.