Recursão anônima
Um combinador de ponto fixo é uma função de ordem superior fix
que, por definição, satisfaz a equivalência
forall f. fix f = f (fix f)
fix f
representa uma solução x
para a equação de ponto fixo
x = f x
O fatorial de um número natural pode ser comprovado por
fact 0 = 1
fact n = n * fact (n - 1)
Usando fix
, provas construtivas arbitrárias sobre funções gerais / μ-recursivas podem ser derivadas sem auto-referencialidade anônima.
fact n = (fix fact') n
Onde
fact' rec n = if n == 0
then 1
else n * rec (n - 1)
de tal modo que
fact 3
= (fix fact') 3
= fact' (fix fact') 3
= if 3 == 0 then 1 else 3 * (fix fact') (3 - 1)
= 3 * (fix fact') 2
= 3 * fact' (fix fact') 2
= 3 * if 2 == 0 then 1 else 2 * (fix fact') (2 - 1)
= 3 * 2 * (fix fact') 1
= 3 * 2 * fact' (fix fact') 1
= 3 * 2 * if 1 == 0 then 1 else 1 * (fix fact') (1 - 1)
= 3 * 2 * 1 * (fix fact') 0
= 3 * 2 * 1 * fact' (fix fact') 0
= 3 * 2 * 1 * if 0 == 0 then 1 else 0 * (fix fact') (0 - 1)
= 3 * 2 * 1 * 1
= 6
Esta prova formal de que
fact 3 = 6
usa metodicamente a equivalência do combinador de ponto fixo para regravações
fix fact' -> fact' (fix fact')
Cálculo lambda
O formalismo do cálculo lambda não tipado consiste em uma gramática livre de contexto
E ::= v Variable
| λ v. E Abstraction
| E E Application
onde v
varia sobre variáveis, junto com as regras de redução beta e eta
(λ x. B) E -> B[x := E] Beta
λ x. E x -> E if x doesn’t occur free in E Eta
A redução beta substitui todas as ocorrências livres da variável x
no corpo de abstração ("função") B
pela expressão ("argumento") E
. A redução de Eta elimina a abstração redundante. Às vezes é omitido do formalismo. Uma expressão irredutível , à qual não se aplica regra de redução, está na forma normal ou canônica .
λ x y. E
é uma abreviação de
λ x. λ y. E
(multiariedade de abstração),
E F G
é uma abreviação de
(E F) G
(associatividade à esquerda do aplicativo),
λ x. x
e
λ y. y
são equivalentes a alfa .
Abstração e aplicação são as duas únicas "primitivas de linguagem" do cálculo lambda, mas permitem a codificação de dados e operações arbitrariamente complexos.
Os numerais da Igreja são uma codificação dos números naturais semelhantes aos naturais Peano-axiomáticos.
0 = λ f x. x No application
1 = λ f x. f x One application
2 = λ f x. f (f x) Twofold
3 = λ f x. f (f (f x)) Threefold
. . .
SUCC = λ n f x. f (n f x) Successor
ADD = λ n m f x. n f (m f x) Addition
MULT = λ n m f x. n (m f) x Multiplication
. . .
Uma prova formal de que
1 + 2 = 3
usando a regra de reescrita da redução beta:
ADD 1 2
= (λ n m f x. n f (m f x)) (λ g y. g y) (λ h z. h (h z))
= (λ m f x. (λ g y. g y) f (m f x)) (λ h z. h (h z))
= (λ m f x. (λ y. f y) (m f x)) (λ h z. h (h z))
= (λ m f x. f (m f x)) (λ h z. h (h z))
= λ f x. f ((λ h z. h (h z)) f x)
= λ f x. f ((λ z. f (f z)) x)
= λ f x. f (f (f x)) Normal form
= 3
Combinadores
No cálculo lambda, combinadores são abstrações que não contêm variáveis livres. Mais simplesmente I
:, o combinador de identidades
λ x. x
isomórfico para a função de identidade
id x = x
Tais combinadores são os operadores primitivos dos cálculos combinadores, como o sistema SKI.
S = λ x y z. x z (y z)
K = λ x y. x
I = λ x. x
A redução beta não está fortemente normalizando ; nem todas as expressões redutíveis, "redexes", convergem para a forma normal sob redução beta. Um exemplo simples é a aplicação divergente do ω
combinador ômega
λ x. x x
para si mesmo:
(λ x. x x) (λ y. y y)
= (λ y. y y) (λ y. y y)
. . .
= _|_ Bottom
A redução das subexpressões mais à esquerda (“cabeças”) é priorizada. A ordem aplicativa normaliza os argumentos antes da substituição, a ordem normal não. As duas estratégias são análogas à avaliação ágil, por exemplo, C, e à preguiçosa, como Haskell.
K (I a) (ω ω)
= (λ k l. k) ((λ i. i) a) ((λ x. x x) (λ y. y y))
diverge sob redução beta de ordem do aplicativo
= (λ k l. k) a ((λ x. x x) (λ y. y y))
= (λ l. a) ((λ x. x x) (λ y. y y))
= (λ l. a) ((λ y. y y) (λ y. y y))
. . .
= _|_
desde em semântica estrita
forall f. f _|_ = _|_
mas converge com a redução beta de ordem normal preguiçosa
= (λ l. ((λ i. i) a)) ((λ x. x x) (λ y. y y))
= (λ l. a) ((λ x. x x) (λ y. y y))
= a
Se uma expressão tiver uma forma normal, a redução beta de ordem normal a encontrará.
Y
A propriedade essencial do Y
combinador de ponto fixo
λ f. (λ x. f (x x)) (λ x. f (x x))
É dado por
Y g
= (λ f. (λ x. f (x x)) (λ x. f (x x))) g
= (λ x. g (x x)) (λ x. g (x x)) = Y g
= g ((λ x. g (x x)) (λ x. g (x x))) = g (Y g)
= g (g ((λ x. g (x x)) (λ x. g (x x)))) = g (g (Y g))
. . . . . .
A equivalência
Y g = g (Y g)
é isomórfico para
fix f = f (fix f)
O cálculo lambda não tipado pode codificar provas construtivas arbitrárias sobre funções gerais / μ-recursivas.
FACT = λ n. Y FACT' n
FACT' = λ rec n. if n == 0 then 1 else n * rec (n - 1)
FACT 3
= (λ n. Y FACT' n) 3
= Y FACT' 3
= FACT' (Y FACT') 3
= if 3 == 0 then 1 else 3 * (Y FACT') (3 - 1)
= 3 * (Y FACT') (3 - 1)
= 3 * FACT' (Y FACT') 2
= 3 * if 2 == 0 then 1 else 2 * (Y FACT') (2 - 1)
= 3 * 2 * (Y FACT') 1
= 3 * 2 * FACT' (Y FACT') 1
= 3 * 2 * if 1 == 0 then 1 else 1 * (Y FACT') (1 - 1)
= 3 * 2 * 1 * (Y FACT') 0
= 3 * 2 * 1 * FACT' (Y FACT') 0
= 3 * 2 * 1 * if 0 == 0 then 1 else 0 * (Y FACT') (0 - 1)
= 3 * 2 * 1 * 1
= 6
(Multiplicação atrasada, confluência)
Para o cálculo lambda não tipificado da Igreja, foi demonstrado que existe uma infinidade recursivamente enumerável de combinadores de ponto fixo Y
.
X = λ f. (λ x. x x) (λ x. f (x x))
Y' = (λ x y. x y x) (λ y x. y (x y x))
Z = λ f. (λ x. f (λ v. x x v)) (λ x. f (λ v. x x v))
Θ = (λ x y. y (x x y)) (λ x y. y (x x y))
. . .
A redução beta de ordem normal torna o cálculo lambda não digitado sem extensão um sistema de reescrita completo de Turing.
Em Haskell, o combinador de ponto fixo pode ser implementado com elegância
fix :: forall t. (t -> t) -> t
fix f = f (fix f)
A preguiça de Haskell normaliza para uma finura antes de todas as subexpressões terem sido avaliadas.
primes :: Integral t => [t]
primes = sieve [2 ..]
where
sieve = fix (\ rec (p : ns) ->
p : rec [n | n <- ns
, n `rem` p /= 0])