O combinador de ponto fixo FIX (também conhecido como combinador Y) no cálculo lambda (sem tipo) ( ) é definido como:
FIX
Entendo sua finalidade e posso rastrear perfeitamente a execução de seu aplicativo; Gostaria de entender como derivar o FIX dos primeiros princípios .
Aqui está o que eu vejo quando tento derivar isso sozinho:
- CORRECÇÃO é uma função: CORRECÇÃO
- O FIX utiliza outra função, , para torná-la recursiva: FIX≜ X f . ...
- O primeiro argumento da função é o "nome" da função, usado onde um aplicativo recursivo se destina. Portanto, todas as aparências do primeiro argumento para devem ser substituídas por uma função, e essa função deve esperar o restante dos argumentos de (vamos supor que use um argumento): FIXf f f ≜ λ f . ... f ( λ y . ... y )
É aqui que eu não sei "dar um passo" no meu raciocínio. As pequenas elipses indicam onde meu FIX está faltando alguma coisa (embora eu só possa saber disso comparando-o com o FIX "real").
Eu já li Tipos e Linguagens de Programação , que não tentam derivá-lo diretamente e, em vez disso, encaminha o leitor para The Little Schemer para uma derivação. Também li isso e sua "derivação" não foi tão útil. Além disso, é menos uma derivação direta e mais um uso de um exemplo muito específico e uma tentativa ad-hoc de escrever uma função recursiva adequada em .
Respostas:
Eu não li isso em nenhum lugar, mas é assim que acredito que poderia ter sido derivado:Y
Vamos ter uma função recursiva , talvez um fatorial ou qualquer outra coisa assim. Informalmente, definimos como termo pseudo-lambda onde ocorre em sua própria definição:f ff f f
Primeiro, percebemos que a chamada recursiva pode ser fatorada como um parâmetro:
Agora poderíamos definir se tivéssemos uma maneira de passar isso como argumento para si mesmo. Isso não é possível, é claro, porque não temos em mãos. O que temos em mãos é . Como contém tudo o que precisamos para definir , podemos tentar passar como argumento em vez de e tentar reconstruir mais tarde. Nossa primeira tentativa é assim:f M M f M f ff f M M f M f f
No entanto, isso não está completamente correto. Antes, foi substituído por no interior . Mas agora passamos vez. Temos de corrigir alguma forma todos os lugares onde usamos para que eles reconstruir de . Na verdade, isso não é nada difícil: agora que sabemos que , em todos os lugares que usamos , simplesmente o substituimos por .r M M r f M f = M M r ( r r )f r M M r f M f=MM r (rr)
Esta solução é boa, mas tivemos que alterar dentro. Isso não é muito conveniente. Podemos fazer isso de forma mais elegante sem precisar modificar introduzindo outro que envia a seu argumento aplicado a si mesmo: expressando como obtemosM λ M M ′ λ x . M ( x x )M M λ M M′ λx.M(xx)
Dessa forma, quando é substituído por , é substituído por , que é pela definição igual a . Isso nos dá uma definição não recursiva de , expressa como um termo lambda válido!x M M r f fM x MM r f f
A transição para agora é fácil. Podemos usar um termo lambda arbitrário em vez de e executar esse procedimento nele. Para que possamos fatorar e definirM MY M M
De fato, o reduz a como o definimos.fYM f
Nota: Derivei conforme definido na literatura. O combinator você descreveu é uma variante do para chamada por valor línguas, às vezes também chamado de . Veja este artigo da Wikipedia .Y ZY Y Z
fonte
Como Yuval apontou, não há apenas um operador de ponto fixo. Existem muitos deles. Em outras palavras, a equação para o teorema do ponto fixo não possui uma única resposta. Portanto, você não pode derivar o operador deles.
É como perguntar como as pessoas derivam como uma solução para . Eles não! A equação não tem uma solução única.x = y(x,y)=(0,0) x=y
Para o caso de você querer saber como foi descoberto o primeiro teorema de ponto fixo. Deixe-me dizer que também me perguntei como eles surgiram com os teoremas de ponto fixo / recursão quando os vi pela primeira vez. Parece tão engenhoso. Particularmente na forma da teoria da computabilidade. Ao contrário do que Yuval diz, não é o caso de as pessoas brincarem até encontrar algo. Aqui está o que eu encontrei:
Tanto quanto me lembro, o teorema é originalmente devido a SC Kleene. Kleene criou o teorema original do ponto fixo ao recuperar a prova de inconsistência do cálculo lambda original da Igreja. O cálculo lambda original da Igreja sofria de um paradoxo do tipo Russel. O cálculo lambda modificado evitou o problema. Kleene estudou a prova de inconsistência provavelmente para ver como se o cálculo lambda modificado sofria de um problema semelhante e transformou a prova de inconsistência em um teorema útil do cálculo lambda modificado. Através de seu trabalho sobre equivalência do cálculo lambada com outros modelos de computação (máquinas de Turing, funções recursivas etc.), ele o transferiu para outros modelos de computação.
Como derivar o operador que você pode perguntar? Aqui está como eu mantenho isso em mente. O teorema do ponto fixo trata da remoção da auto-referência.
Todo mundo conhece o paradoxo do mentiroso:
Ou na forma mais lingüística:
Agora, a maioria das pessoas pensa que o problema com esta frase está na auto-referência. Não é! A auto-referência pode ser eliminada (o problema é com a verdade, uma linguagem não pode falar sobre a verdade de suas próprias sentenças em geral, veja o teorema da indefinibilidade do verbo de Tarski ). O formulário em que a auto-referência é removida é o seguinte:
Sem auto-referência, temos instruções sobre como construir uma frase e depois fazer algo com ela. E a frase que é construída é igual às instruções. Observe que em -calculus não precisamos de aspas porque não há distinção entre dados e instruções.λ
Agora, se analisarmos isso, temos onde é as instruções para construir e fazer alguma coisa.MM Mx xx
Então é e temosM λx.f(xx)
Isto é para um fixo . Se você deseja torná-lo um operador, basta adicionar e obteremos :f λf Y
Por isso, lembro o paradoxo sem auto-referência e isso me ajuda a entender o que é oY
fonte
Então você precisa definir um combinador de ponto fixo
mas sem recursão explícita. Vamos começar com o combinador irredutível mais simples
O
x
primeiro lambda é repetidamente substituído pelo segundo lambda. A simples conversão alfa torna esse processo mais claro:Ou seja, a variável no primeiro lambda sempre desaparece. Então, se adicionarmos um
f
ao primeiro lambdao
f
vai subirNós nos
omega
recuperamos. Agora deve ficar claro que, se adicionarmos umf
ao segundo lambda, elef
aparecerá no primeiro lambda e depois será exibido:Desde a
podemos reescrever a expressão como
que é apenas
e nós temos nossa equação
Y f = f (Y f)
. Portanto, oY
combinador é essencialmentef
f
balançarfonte
Você pode ter visto o exemplo clássico de uma equação sem uma forma normal:
Uma equação semelhante é sugerida por aquela para recursão geral:
(A) é uma maneira de escrever equações recursivas gerais no cálculo lambda (além da recursiva primitiva). Então, como você resolve a equação ? Conecte para na equação acima para obter:Yf=f(Yf) f R
Y = λ f . ( λ x . f ( x x ) ) ( λ x . f ( x x ) )
fonte