Легкое доказательство того, что контекстно-зависимые языки закрываются при циклическом сдвиге


11

Циклический сдвиг (также называемый поворот или конъюгации ) из языка определяется как { у х | х у L } . Согласно википедииздесь ), контекстно-свободные языки закрыты для этой операции со ссылками на статьи из Oshiba и Maslov. Есть ли простое доказательство этого факта?L{yxxyL}

Для обычных языков закрытие обсуждается в этой форме как « Докажите, что регулярные языки закрыты под оператором цикла ».

Ответы:


5

Вы можете попробовать воспользоваться автоматом. Получив автомат для исходного языка, мы строим его для циклического сдвига. Новый автомат работает в два этапа, соответствующих y и x части слова yx (где xy на языке оригинала). На первом этапе, всякий раз, когда автомат хочет выдвинуть нетерминал A , он может вместо этого нажать нетерминал A ; идея состоит в том, что в конце первого этапа стек будет содержать в обратном порядке символы, которые находятся в стеке после чтения xоригинальным автоматом. На втором этапе (переключатель недетерминирован), вместо нажатия на нетерминал A , нам разрешено выталкивать нетерминал A . Если оригинальный автомат действительно может сгенерировать стек после чтения x , то новый сможет точно вытолкнуть весь стек.

Изменить: вот еще несколько деталей. Предположим, нам дан КПК с алфавитом , набором состояний Q , набором принимающих состояний F , нетерминалами Γ , начальным состоянием q 0 и набором допустимых переходов. Каждый допустимый переход имеет вид ( q , a , A , q , α ) , что означает, что в состоянии q при чтении a A (или a = ϵ , в этом случае это свободный переход), если верх стека A ΣQFΓq0(q,a,A,q,α)qaAa=ϵ (или A = ϵ , что означает, что стек пуст), тогда КПК может (это недетерминированная модель) перейти в состояние q , заменив A на α Γ .AΓA=ϵqAαΓ

Новый КПК имеет новый нетерминал для каждого A Γ . Для каждых двух состояний q , q Q и A Γ { ϵ } существуют два состояния ( q , q , 1 ) , ( q , q , 2 , A ) . Исходные состояния (выбирается фактическое начальное состояние недетерминированно среди них с помощью ε - переходов) , являются (AAΓq,qQAΓ{ϵ}(q,q,1),(q,q,2,A)ϵ(q,q,1)(q,a,A,q,α)( ( q , q , 2 , B ) , a , A , ( q , q , 2 , Б ) , а )((q,q,1),a,A,(q,q,1),α)((q,q,2,B),a,A,(q,q,2,B),α)

Для каждого перехода существуют переходы , где и . Для каждого конечного состояния существуют переходы , где .( ( q , q , 1 ) , a , B , ( q , q , 1 ) , B A α ) B Γ { ϵ } ε ' = ε д F ( ( д ,(q,a,A,q,α)((q,q,1),a,B,(q,q,1),BAα)BΓ{ϵ}ϵ=ϵqFA Γ { ϵ }((q,q,1),ϵ,A,(q0,q,2,ϵ),A)AΓ{ϵ}

Для каждого перехода существуют переходы , где . Для каждого перехода существуют переходы , где . Для каждого перехода существуют «обобщенные переходы» ; они реализованы в виде последовательности двух переходов через новое промежуточное состояние. Переходы\ alpha) с( ( q , q , 2 , A ) , a , B , ( q , q , 2 , A ) , B α ) A Γ { ϵ } ( q , a , ϵ , q (q,a,ϵ,q,α)((q,q,2,A),a,B,(q,q,2,A),Bα)AΓ{ϵ}( ( q , q , 2 , B ) , a , A , ( q , q , 2 , A ) , ϵ ) B Γ { ϵ } ( q , a , A , q , B ) ( ( q , q , 2(q,a,ϵ,q,A)((q,q,2,B),a,A,(q,q,2,A),ϵ)BΓ{ϵ}(q,a,A,q,B)( q , a , ϵ , q , α ) | α | 2 ( q , a , A , q , A ) ( ( q , q , 2 ,((q,q,2,C),a,BA,(q,q,2,C),ϵ)(q,a,ϵ,q,α)|α|2обрабатываются аналогично. Для каждого перехода существуют переходы , где . Переходы обрабатываются аналогично. Наконец, существует единственное конечное состояние и переходы .(q,a,A,q,A)B Γ { ϵ } ( q , a , A , q , A α ) f ( ( q , q , 2 , А ) , ϵ , ϵ , f , ϵ((q,q,2,A),a,B,(q,q,2,A),B)BΓ{ϵ}(q,a,A,q,Aα)f((q,q,2,A),ϵ,ϵ,f,ϵ)

(Там может быть несколько переходов, которые я пропустил, и некоторые детали, которые я опускаю, несколько беспорядочные.)

Напомним, мы пытаемся принять слово , где принимается оригинальным КПК. Состояние означает, что мы находимся на этапе 1, в состоянии , а исходный КПК находится в состоянии после чтения . Состояние аналогично, где соответствует последнему который был вытолкнут. На этапе 1, мы имеем право выдвинуть вместо того , чтобы хлопать . Мы делаем это для каждого нетерминала, который создается при обработке , но выталкивается только при обработке . На 2 -й ступени, нам позволено соватьx y ( q , q , 1 ) q q x ( q , q , 2 , A ) A A A A x y A A A ϵ B yxxy(q,q,1)qqx(q,q,2,A)AAAAxyAвместо того, чтобы нажимать . Если мы сделаем это, тогда мы должны помнить, что вершина акции действительно ; это применимо только в том случае, если в стеке нет «временных» объектов, которые в моделируемом КПК совпадают с вершинами стека или в форме .AAϵB

Вот простой пример. Рассмотрим автомат для который толкает для каждого и выдает для каждого . Новый автомат принимает слова двух форм: и . Для слов первой формы, 1 -й ступени состоит из толкая раз«2 -й ступени состоит из выскакивают раз , толкая раз , и выскакивают раз . Для слов второй формы мы сначала нажимаем раз A x A y y k x n y n - k x k y n x n - k k A k A n - k A n - k A k A k A n - k A n - k 'xnynAxAyykxnynkxkynxnkkAkAnkAnkAkA, затем нажмите раз , нажмите раз , перейдите к этапу 2 и нажмите раз .kAnkAnkA

Вот более сложный пример для языка сбалансированных скобок различных типов ("()", "[]", "<>"), так что непосредственные потомки каждого типа скобок должны принадлежать к другому типу. Например, «([] <>)» в порядке, но «()» неверно. Для каждого «(», мы помещаем если стек топ-не , для каждого «)», мы выскочить . Аналогично , ассоциируются с «[]» и «<>». Вот как мы принимаем слово ">) ([()] <". Мы потребляем ">)", нажимая и переходя к этапу 2. Мы потребляем "(", выталкиваяи запоминание верхней границы стека . Мы потребляем "[()]", нажимая и щелкая ; при нажатииA A B C C A A A B A B A B A A B ϵ X B A C A AABCCAAABAB , мы знаем, что «реальная» вершина стека - это , и поэтому допускаются квадратные скобки (нас не обманул бы «>) (() <»); при нажатии , поскольку вершина стека - это (который не является или имеет форму ), то мы знаем, что также является «реальной» вершиной стека, и поэтому допускаются круглые скобки (даже если теневая вершина стека ). Наконец, мы потребляем "<" и поп .AABϵXBAC


Извините, у меня проблемы с пониманием. Можете ли вы объяснить дальше? С чего начинается автомат и каковы его переходы? И происходит ли переключение для каждого символа стека? Спасибо! AA
Усул

Очень интересное предложение. Спасибо. Я буду немного пережевывать это, чтобы оно впиталось.
Хендрик Ян

@usul, тебе придется заполнить детали самостоятельно. Переключатель (на первом этапе) должно произойти , когда автомат„хочет“ , чтобы поп , но не может, а вместо этого он выталкивает . Вы можете думать об этом как о недетерминированном движении. A A AAAA
Юваль Филмус

@Yuval: извините , но я не могу сделать этого. Как я понимаю вашу мысль, новый автомат начинается имитируя части, изменение хлопков и толчков. Затем генерируют в стеке, где оригинальный автомат начинается с при чтении . Что оригинал начинается с толчка? Тогда Nwe автомат должен выскочить из пустого стека. Я все еще думаю, что ваша интуиция заслуживает внимания, но, похоже, нужна дополнительная осторожность. α α yyααy
Хендрик Jan

@ Хендрик, извини, но я не могу последовать твоему контрпримеру. В какой момент вы думаете , что новые потребности автомата поп из пустого стека?
Юваль Филмус

4

Рассмотрим нормальную форму Грейбаха . Чтобы создать сдвинутый язык, вам нужно всего лишь изменить производство на и добавить новый нетерминальный который ведет себя так же, как раньше, в случае производство ссылки . S A 1A n α S S SSαA1AnSA1AnαSSS


Спасибо, но это сдвиг одной буквой. Меня интересует общая ротация по произвольному количеству букв.
Хендрик Ян

3
@HendrikJan, ну, если является контекстно - свободным, так , безусловно , будет контекст бесплатно , а также. Вы можете построить грамматику для него, применяя метод , который я предложил раз. Кроме того, можно построить грамматика непосредственно, «уплощение» данной грамматики . например , если и грамматика имеет производства и , вы бы добавить производство и повернуть это. конечно, размер ваша грамматика может расти очень быстро.shift1(L)shiftn(L)=shift1(shift1((L))nshiftn(L)n=2SαABAβCSαβCB
Karolis Juodelė

1
При фиксированном вы правы. Но здесь фиксирована и не ограничена. Например , если , то получим . nnL={anbnn0}{akbnak+=n}{bkanbk+=n}
Хендрик Ян

@HendrikJan, я вижу. Я ошибочно предположил, что вопрос был о конечном сдвиге. Я пересмотреть свой ответ ...
Karolis Juodelė

4

Хорошей идеей оказалось проверить старое классическое « Введение в теорию автоматов» Хопкрофта и Уллмана (1979). Закрытие в цикле - это Упражнение 6.4c и помечено S **. Двойные звезды означают, что это одна из самых сложных проблем (в книге). К счастью, S указывает, что это одна из выбранных проблем с решением.

Решение заключается в следующем. Беру CFG в хомском нормальном виде. Рассмотрим любое деривационное дерево и в основном перевернем его. Рассмотрим путь в исходном дереве. На левом дереве есть вклады на правый , то есть строка выводится равных . ( На самом деле , как грамматика CNF , когда путь продолжается влево, вклад будет справа и соответствующий пуст, и т.д.)S=X1,X2,,Xnx1,x2,,xny1,y2,,ynx1x2xnyny2y1xi

У дерева вверх ногами есть путь с вкладами слева и справа, поэтому результат является производным для . Как требуется.у п , ... , у 2 у 1 х п , ... , х 2 х 1 у п ... у 2 у 1 х 1 х 2 ... х пS,X^n,X^2,X^1yn,,y2y1xn,,x2x1yny2y1x1x2xn

Полные детали конструкции приведены в книге.

Обратите внимание, как это напоминает (принятое) решение Ювала. Нетерминалы, которые вставляются, а не выталкиваются, расположены в стеке в обратном порядке. Совершенно похоже на перевернутый на дереве.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.