24.01.2014 Views

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

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!