Formalny opis rachunku lambda i nie tylko, kolejna wersja
Formalny opis rachunku lambda i nie tylko, kolejna wersja
Formalny opis rachunku lambda i nie tylko, kolejna wersja
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
10.5 λ-definiowalność funkcji pierwot<strong>nie</strong> rekurencyjnych<br />
Twierdze<strong>nie</strong> 10.1 Klasa całkowitych funkcji <strong>lambda</strong> definiowalnych jest zamknięta<br />
ze względu na złoże<strong>nie</strong>.<br />
Dowód. Ten dowód ma jasną ideę i może zostać przedstawiony na przykładzie.<br />
Przypuśćmy, że funkcja h jest złoże<strong>nie</strong>m całkowitych funkcji f, g 1 i g 2 takim, że<br />
h(m, n) = f(g 1 (m, n), g 2 (m, n)).<br />
Niech F , G 1 i G 2 będą termami definiującymi odpowiednio funkcje f, g 1 i g 2 .<br />
Wtedy term<br />
λab.F (G 1 ab)(G 2 ab)<br />
definiuje funkcję h. Po<strong>nie</strong>waż zajmujem się funkcjami całkowitymi, więc wystarczy<br />
sprawdzić <strong>tylko</strong> warunek 1) z definicji funkcji <strong>lambda</strong> definiowalnej (patrz str. 26).<br />
Sprawdze<strong>nie</strong> tego warunku <strong>nie</strong> nastręcza żadnych trudności. ✷<br />
Twierdze<strong>nie</strong> 10.2 Klasa całkowitych funkcji <strong>lambda</strong> definiowalnych jest zamknięta<br />
ze względu na definiowa<strong>nie</strong> przez rekursję prostą.<br />
Dowód. Najpierw zajmiemy się przykładem, z którego powinno wynikać, że rekursja<br />
ma coś wspólnego z iteracją, zwłaszcza w przypadku, gdy kolejną wartość<br />
definiujemy bez parametrów.<br />
Pokażemy <strong>lambda</strong> definiowalność funkcji takiej, że f(0) = 1 i f(n+1) = 2·f(n).<br />
Oczywiście, f(n) = 2 n ). Nietrudno zauważyć, że f(n) = h n (1), gdzie h(n) = 2 · n.<br />
Jeżeli znajdziemy term H definiujący h, to korzystając z interpretacji numerałów<br />
Churcha możemy uznać za definiujący f term λa.aHc 1 . Term H możemy<br />
analogicz<strong>nie</strong> zdefiniować jako λa.aLc 0 , gdzie L jest termem definiujący funkcję<br />
powiększającą argument o 2. Możemy przyjąć, że L = λafx.af(f(fx)).<br />
Teraz musimy rozbudować aparat. Przyjmijmy, że<br />
[M, N] = λx.xMN, K = true = λxy.x oraz K∗ = false = λxy.y.<br />
Oczywiście, mamy [M, N]K = M oraz [M, N]false = N, o ile zmienna x <strong>nie</strong><br />
występuje w termach M i N.<br />
Pokażemy (znowu na przykładzie) <strong>lambda</strong> definiowalność funkcji f definiowanej<br />
wzorami<br />
f(0, m) = g(m) oraz f(k + 1, m) = h(f(k, m), k, m).<br />
Przyjmijmy, że G i H są termami definiującymi odpowiednio g i h.<br />
Nawiasy kwadratowe oznaczają rodzaj funkcji pary. Niech q oznacza funkcję<br />
taką, że<br />
q(m, [a, b]) = [h(a, b, m), b + 1].<br />
W <strong>rachunku</strong> <strong>lambda</strong> taką funkcję reprezentuje term<br />
Q = λuvw.w(H(vK)(vK ∗ )u)(S(vK ∗ ).<br />
Weźmy<br />
Pokażemy najpierw, że<br />
F = λab.a(Qb)[Gb, c 0 ]K,<br />
Qc m [c f , c k ] = [c h(f,k,m) , c k+1 ].<br />
27