É sabido que uma máquina com uma única pilha, como apenas armazenamento ilimitado, não está completa com Turing, se puder apenas ler a partir da parte superior da pilha. Eu quero uma máquina que seja (ligeiramente) mais poderosa que uma máquina de empilhar, mas que ainda não esteja completa com Turing. (Gostaria de saber se existe uma máquina completa não-Turing, que possa simular deterministicamente qualquer autômato não-determinístico de pushdown com uma única desaceleração polinomial.) A extensão mais benigna (direta) que me veio à mente foi uma (única) frente leia o iterador.
Deixe-me elaborar os detalhes da implementação, para deixar claro o que quero dizer com um iterador de leitura direta. Uma lista vinculada única pode ser usada para implementar uma pilha. Deixe a lista ser implementada por um ponteiro pTop
, que é zero ou aponta para um SList
nó. Um SList
nó consiste em um campo de carga útil value
e um campo de ponteiro pNext
, onde pNext
é zero ou aponta para um SList
nó. Deixe o iterador de leitura direta ser implementado por um ponteiro pRead
, que é zero ou aponta para um SList
nó. Os ponteiros pTop
e pRead
não podem ser acessados diretamente, mas só podem ser usados pelos seguintes métodos:
Push(val)
cria um novoSList
nón
comn.value = val
en.pNext = pTop
, e definepTop = &n
.Pop()
aborta sepTop == 0
oupRead == pTop
. Caso contrário, ele lêval = pTop->value
epTopNext = pTop->pNext
libera oSList
nó apontado porpTop
, definepTop = pTopNext
e retornaval
.ReadBegin()
conjuntospRead = pTop
.ReadNext()
aborta sepRead == 0
. Caso contrário, ele lêval = pRead->value
, definepRead = pRead->pNext
e retornaval
.ReadFinished()
retornatrue
sepRead == 0
e defalse
outra forma.
fonte
pTop == 0
epRead == 0
. Um métodoReadCancel()
que definepRead = 0
também pode ser uma boa ideia, porque, caso contrário, o abortar dePop()
forpRead == pTop
pode ser irritante.Respostas:
Infelizmente, o seu modelo é completo em Turing.
Você pode simular uma fila na sua estrutura de dados usando o seguinte algoritmo. Introduziu 3 novos símbolos de pilha:d, x , y .
Enqueue(val)
é justoPush(val)
.Para
Dequeue()
:ReadBegin()
.ReadBegin()
.pTop
é umReadNext()
até retornar algo diferente dePop()
.ReadNext()
é retornado como resultado deDequeue
.A prova é direta. Verifique o histórico de revisões para obter uma versão mais complicada, primeiro reduzindo-a para uma versão bidirecional.
fonte
Seu modelo é Turing completo (ao contrário do que eu pensava anteriormente), consulte a resposta do usuário21313, um esboço da prova (a essência é que você pode simular uma fila e os autômatos de filas estão completos Turing).
Existem várias maneiras de enfraquecer o modelo para cair na equivalência com autômatos vinculados lineares ou inferiores.
Ginsburg, Greibach & Harrison [1] fornecem uma máquina chamada "Stack Automaton", que é um PDA com dois recursos adicionais: 1. O cabeçote de entrada pode se mover para a esquerda e para a direita (para digitalizar partes da entrada vistas anteriormente). 2. A cabeça de leitura / gravação na pilha pode digitalizar através da pilha no modo somente leitura, mas pressionar e saltar ainda ocorre apenas na parte superior. Observe a principal diferença aqui com o seu modelo, que me confundiu anteriormente: a pilha possui apenas uma cabeça / ponteiro que pode mover para cima e para baixo na pilha, enquanto a sua possui duas, o que é suficiente para tornar seu modelo Turing completo. Eles também fornecem outro modelo [2], onde a entrada só pode ser lida da esquerda para a direita, mas a digitalização de pilha somente leitura adicional ainda está disponível.
Na Figura 2 de [1], eles fornecem a contenção (comprovada na Seção 5 da mesma, talvez com algumas partes em [2]) e as linguagens de autômatos de pilha não determinísticos bidirecionais estão estritamente contidas emR . No entanto, eles são equivalentes a autômatos vinculados lineares não determinísticos, portanto reconhecem linguagens sensíveis ao contexto.
Autômatos de pilha bidirecional e não determinístico e autômatos de pilha bidirecional parecem equivalentes, no entanto, alterar a cabeça de entrada para unidirecional faz uma diferença significativa. O conjunto de linguagens de autômatos de pilha não determinística unidirecionais é um subconjunto estrito de linguagens sensíveis ao contexto (ainda não sei exatamente onde ainda) e o conjunto de autômatos de pilha determinística de mão única (que são equivalentes ao seu modelo ) languages é um subconjunto estrito do conjunto de idiomas unideterministas não-determinísticos de pilha de autômatos.
Um tipo mais fraco novamente, que fica abaixo desses, é o autômato da pilha que não apaga, que só pode gravar na pilha.
Hopcroft & Ullman mostram que os idiomas reconhecidos pelos autómatos de pilha determinísticos que não apagam correspondem aDS P A C E (nlogn ) autómatos não determinísticos de pilha não apagáveis correspondem a D S P A C E (n2) .
Termo aditivo
Depois de mais algumas escavações, esses slides de aula sugerem que os autômatos determinísticos de pilha unidirecional e sem apagamento são estritamente mais fracos que a versão bidirecional; portanto, reconheça algo menos queD S P A C E (nlogn ) .
Também encontrei outros artigos de Hopcroft e Ullman [4,5], que podem fornecer mais algumas pistas, mas parece ser tangencial neste momento. [5] pelo menos prova algumas equivalências de alguns Stack Automata com LBAs.
Referências
fonte
pRead
estiver. (como eu o entendo)pTop
epRead
são dois ponteiros separados. Você pode enfileirarpTop
e desenfileirar (movendo-se para cima e ignorar qualquer coisa abaixo) empRead
? (Se for bidirecional.)