Problema de parada sem auto-referência: por que esse argumento não é suficiente (ou é)?

8

Estou tentando encontrar uma maneira de explicar a idéia da prova do problema da parada da maneira mais acessível possível (para alunos de graduação em ciências da computação). O argumento mais simples que encontrei é esse ; esse é precisamente o estilo de tratamento que estou buscando. No entanto, a auto-referência (em particular, verificar se um programa pára em si mesmo) não é a mais didática.

O que estou me perguntando, como um esboço de prova, é por que não conseguimos simplificar ainda mais e dizer: se assumirmos um programa H(P,I)para o Problema de Parada que pára com verdadeiro se P(I)parar e com falso caso contrário, poderíamos criar um programa do formulário:

def Q(J):
  if H(Q,J) then loop forever
  else halt

... que é um programa válido se e somente se o Problema de Parada for um programa válido. Podemos então perguntar: para que deve H(Q,J)retornar qualquer valor arbitrário J? Vemos uma contradição em ambas as possibilidades e concluímos que, como a existência de Hnos permite construir o programa contraditório Q, um programa da forma Hnão pode existir.

Ainda existe alguma auto-referência aqui, pois o programa Qverifica se ele pára ou não na entrada atual (e faz o oposto), mas, para mim, isso parece muito mais intuitivo do que configurar uma situação em que precisamos de uma chamada do formar P(P)ou H(P,P), etc. No entanto, eu não vi esse argumento simples utilizado, e eu acho que teria sido se fosse válido. Portanto, minhas perguntas são:

  • O argumento acima é suficiente como prova (esboço) do problema de parada?
    • Se sim, por que tantos argumentos seguem uma etapa confusa do formulário P(P)ou H(P,P)? (É apenas para remover a "entrada" sem importância da equação?)
    • Se não, o que está faltando?

Há várias perguntas relacionadas a este tópico, como:

Também achei menção à prova baseada no paradoxo de Berry, que é bastante atraente. Ainda assim, ainda não consegui me convencer se o argumento específico acima funciona ou não (mesmo que seja apenas para meu próprio entendimento; sinto que talvez esteja perdendo algo estúpido e gostaria de saber o que é).

badroit
fonte
2
Você conhece este vídeo ? É a explicação mais intuitiva do problema de interrupção que eu já vi.
Polygnome
Obrigado pelo ponteiro! Sim, o @DW vincula-o à sua resposta.
badroit

Respostas:

20

Eu não acho que essa seja uma boa maneira de apresentar o problema da parada, porque envolve uma questão crítica sob as cobertas de uma maneira sorrateira. Sugiro continuar com uma apresentação mais padrão, como a que você vinculou. Se você deseja encontrar uma maneira de explicá-lo de maneira a minimizar o conteúdo técnico, a apresentação neste vídeo é surpreendentemente acessível e permanece fiel à lógica da prova padrão.

Sobre as dificuldades com sua proposta. Na sua proposta, não é trivial escrever o código para tal Q. Pense no que significa ter a linha

  if H(Q,J) then loop forever 

Lembre-se de que o primeiro argumento para Hé uma string de bits que contém o código / algoritmo / máquina de Turing - não é um ponteiro para a função, mas uma string. Ingenuamente, isso parece significar que incluímos uma string codificada que contém o código-fonte para Q, dentro do código de Q. Mas isso não é possível. Suponha que o código para Qocupe 100 caracteres. Precisamos codificar uma constante de cadeia de 100 caracteres dentro da definição de Q, além de precisarmos de mais alguns caracteres para o resto da lógica - e isso soma mais de 100 caracteres. Se você pensar bem, é óbvio que não podemos ter uma constante de cadeia de caracteres dentro do código, Qpois é o código de Q, porque seria muito longo.

Talvez você esteja pensando que não é isso que você tinha em mente. Talvez você estivesse pensando que a linguagem de programação terá alguma API incorporada para obter o código da função atual; portanto, na verdade, o código em que você estava pensando é algo como:

def Q(J):
  if H(get_source_code_of_current_function(),J) then loop forever
  else halt

OK, tudo bem. Isso prova que o problema de parada não pode ser resolvido para o código escrito em qualquer linguagem de programação que tenha uma get_source_code_of_current_function()API. No entanto, minha linguagem de programação favorita não possui essa API. Portanto, essa prova não prova nada sobre minha linguagem de programação favorita - talvez o problema da parada seja solucionável para minha linguagem, quem sabe? Da mesma forma, as máquinas de Turing não possuem essa API, portanto, isso não prova que o problema de parada das máquinas de Turing é indecidível.

E essa é uma grande falha na sua prova. E é uma falha sutil e nada evidente. Não acho que seja pedagogicamente uma boa idéia apresentar uma prova que "pareça válida" na superfície, mas que, na verdade, depois que você se aprofunda nela, é falha.

Agora, é possível resgatar sua prova proposta. Na verdade, é possível construir uma função Qque funcione da maneira que você disse; você basicamente precisa que seja uma solução . Suponho que, em princípio, você possa explicar a ideia de quines, apresentar sua prova e explicar como implementar uma função Q usando essas idéias.. Mas isso me parece uma má ideia, de uma perspectiva pedagógica. Quines são alucinantes, misteriosos e difíceis de entender. Um aluno que não entende de quines não entenderá sua prova. E faz com que a prova de indecidibilidade do problema de parada pareça muito mais misteriosa do que precisa. Portanto, isso não me parece uma maneira mais acessível de entender o problema da parada.

DW
fonte
Excelente resposta, muito obrigado! Acho que talvez seja melhor seguir uma apresentação mais padrão (em vez de introduzir quines, por exemplo).
badroit
"você basicamente precisa que seja uma solução" - ou defina Q como uma constante em um programa maior e avalie-o usando uma máquina de turing universal ou equivalente. Desde que você aceite que a máquina de turing universal se comporte da mesma maneira que a máquina em que está sendo executada em todas as circunstâncias, essa certamente deve ser uma abordagem mais fácil de entender?
Jules
@Jules, desculpe, eu não entendo sua prova proposta, então não posso comentar sobre ela.
DW
Você se importaria de explicar por que considera os vinhos difíceis de entender? Na minha experiência, quines da forma "escreva isto e depois o mesmo citado" são bastante simples de construir.
Dmitri Urbanowicz
@DmitriUrbanowicz, talvez seja só eu e eu estou apenas preso nele. Eu acho que o vinho é mágico e difícil de entender. Talvez seja só eu; ou talvez ainda não tenha visto a explicação certa; ou talvez eu não tenha me esforçado o suficiente. Talvez outros tenham uma experiência diferente!
DW
1

Não vejo como a auto-referência é pedagogicamente difícil. O Barber Paradox é muito fácil de entender. E seu argumento tem auto-referência implícita, e acho que é mais difícil de entender do que simples auto-referência. Além disso, é incoerente. Para definir H (Q, J), primeiro você precisa saber o que é Q e, para definir Q, primeiro precisa saber o que é H (Q, J). Isso não funciona. Na melhor das hipóteses, você pode afirmar que Q é um ponto fixo dessa definição autorreferencial, mas se você tentar derivar algo da natureza contraditória de Q, estará apenas mostrando que H não existe OU que esse ponto fixo não existe. ; agora você tem que provar que se H existisse, o ponto fixo teria que existir.

Acumulação
fonte