Wykład 2: Rachunek lambda Systemy typów, II UWr, 2010 20 października 2010
λ-termy zmienne (Var) {x, y, z,...} nieskończony, przeliczalny zbiór zmiennych termy (Term) t ::= x λx.t t t skróty notacyjne λx 1 x 2... x n.t λx 1.λx 2.... λx n.t t 1 t 2 t 3... t n (... ((t 1 t 2 ) t 3 )... )t n
α-równoważność i konwencja Barendregta λ-abstrakcja λx.t wiąże zmienną x w termie t zmienne wolne FV(x) = {x} FV(λx.t) = FV(t) {x} FV(t 0 t 1 ) = FV(t 0 ) FV(t 1 ) termy t i u są α-równoważne, jeżeli różnią się wyłącznie nazwami zmiennych związanych α-równoważność jest relacją równoważności utożsamiamy α-równoważne termy konwencja Barendregta zakładamy, że zmienne wolne są różne od zmiennych związanych w rozważanych termach (zmienne związane można zawsze odpowiednio przemianować)
Podstawienie x{s/x} = s y{s/x} = y x y (λy.t){s/x} = λy.t{s/x} x y, y FV(s) (t 0 t 1 ){s/x} = t 0 {s/x} t 1 {s/x} implementując podstawienie trzeba przemianować zmienne związane w termie, w którym wykonuje się podstawienie na świeże zmienne
β-redukcja relacja β-redukcji (λx.t) s β t{s/x} t β t λx.t β λx.t t β t t s β t s s β s t s β t s (λx.t) s β-redex t jest w postaci normalnej, jeżeli nie istnieje s taki, że t β s
β-redukcja, c.d. relacja β wielokrokowej β-redukcji przechodnio-zwrotne domknięcie β relacja = β β-równości przechodnio-zwrotno-symetryczne domknięcie β Twierdzenie (Churcha-Rossera) Jeżeli t β r i t β s, to istnieje u taki, że r β u i s β u. (Jeżeli r = β s, to istnieje u taki, że r β u i s β u.) Wniosek Każdy term t ma co najwyżej jedną postać normalną u (tj. taką, że t β u). Uwaga Istnieją termy, które nie mają postaci normalnej, np. Ω = ω ω, gdzie ω = λx.x x.
Reprezentacja struktur danych w rachunku λ liczby naturalne (numerały Churcha) c n = λs.λz.s (n) (z) gdzie t (0) (s) = s, t (n+1) (s) = t (t (n) (s)) suc = λm.λs.λz.m s (s z) add = λm.λn.λs.λz.m s (n s z) mul = λm.λn.λs.λz.m (n s) z succ c n β c n+1 add c m c n β c m+n mul c m c n β c m n
Reprezentacja struktur danych w rachunku λ, c.d. wartości logiczne pary, listy, drzewa, etc. rekursja true = λx.λy.x false = λx.λy.y cond = λb.λx.λy.b x y cond true t s β t cond false t s β s Y = λf.(λx.f (x x)) (λx.f (x x)) t (Y t) = β Y t
Strategie redukcji normalizacja postać normalna v ::= λx.v x v 1... v n (n 0) leftmost-outermost (porządek normalny) w każdym kroku wybierany jest najbardziej na lewo położony redeks niezawarty w żadnym redeksie leftmost-innermost (porządek aplikatywny) w każdym kroku wybierany jest najbardziej na lewo położony redeks niezawierający żadnego redeksu Twierdzenie Jeżeli term ma postać normalną, to redukcja w porządku normalnym ją znajdzie, a redukcja w porządku aplikatywnym niekoniecznie.
Ewaluacja w porządku normalnym (call by name) słaba czołowa postać normalna v ::= λx.t x t 1... t n (n 0) relacja redukcji w porządku normalnym n (λx.t) s n t{s/x} t n t t s n t s relacja ewaluacji n w stylu semantyki naturalnej x n x t n λx.u u{s/x} n v t s n v t n v t s n v s λx.t n λx.t (v λx.u)
Ewaluacja w porządku normalnym (call by name), c.d. Twierdzenie t n v wtw t n v. Dowód Indukcja po długości ciągu redukcji t n v. Indukcja po wyprowadzeniu t n v.
Maszyna Krivine a (wariant z podstawieniem) reprezentacja termu (t, t 1 : : t n ) reprezentuje term t t 1... t n przejścia maszyny konfiguracja początkowa (λx.t, s : s) n (t{s/x}, s) (t 0 t 1, s) n (t 0, t 1 : s) (t, ɛ) konfiguracje końcowe (λx.t, ɛ) (x, t) Twierdzenie t n v wtw (t, ɛ) n (v 0, t 1 : : t n ) gdzie v = v 0 t 1... t n.
Ewaluacja w porządku aplikatywnym (call by value) słaba postać normalna v ::= λx.t x v 1... v n (n 0) relacja redukcji w porządku aplikatywnym v (λx.t) v v t{v/x} t v t t s v t s s v s v s v v s relacja ewaluacji v w stylu semantyki naturalnej x v x λx.t v λx.t t v v s v w t s v v w t v λx.u s v w u{w/x} v v t s v v (v λx.u)
Maszyna CK stos przejścia maszyny s ::= ɛ arg(t) : s fun(v) : s (x, s) v (s, x) (λx.t, s) v (s, λx.t) (t 0 t 1, s) v (t 0, arg(t 1 ) : s) (arg(t 1 ) : s, v 0 ) v (t 1, fun(v 0 ) : s) (fun(λx.t) : s, v 1 ) v (t{v 1 /x}, s) (fun(x v 1... v n ) : s, v) v (s, x v 1... v n v) konfiguracja początkowa (t, ɛ) konfiguracja końcowe (ɛ, v)
Indeksy de Bruijna Cel reprezentacja termów, która nie wymaga przemianowania zmiennych przy podstawieniu α-równoważne termy są identyczne Rozwiązanie zmienne reprezentowane za pomocą liczb naturalnych (indeksy de Bruijna) indeks de Bruijna określa odległość (liczba dzielących je λ) zmiennej od wiążącej ją lambdy przykłady λx.x λ.0 λx.λy.x (y x) λ.λ.1 (0 1)
Indeksy de Bruijna, c.d. termy t ::= n λ.t t t termy otwarte mają sens w pewnym kontekście Γ = x n, x n 1,..., x 1, x 0 wiążącym nazwę x i z indeksem i przykład (Γ = c, b, a) a (b c) 0 (1 2) λx.a x λ.1 0 λx.λy.c λ.λ.4
Indeksy de Bruijna, c.d. podstawienie przesunięcie indeksów k{s/k} = s k{s/j} = k, k j (λ.t){s/j} = λ.t{ 1 0 (s)/j + 1} (t 0 t 1 ){s/j} = t 0 {s/j} t 1 {s/j} d c (k) = k, k < c d c (k) = k + d, k c d c (λ.t) = λ. d c+1 (t) d c (t 0 t 1 ) = d c (t 0 ) d c (t 1 ) β-redukcja (λ.t) s β 1 0 (t{ 1 0 (s)/0})
Modelowy język funkcyjny (CBV) składnia t ::= x λx.t t t 0 suc t case t of 0 t suc x t fix x.t syntaktyczny cukier let x = t 1 in t 2 (λx.t 2 ) t 1 letrec x = t 1 in t 2 let x = fix x.t 1 in t 2 program = zamknięty term przykład programu letrec add = λm.λn.case m of 0 n suc k add k (suc n) in add 2 3
Modelowy język funkcyjny (CBV), c.d. wartości semantyka programów (λx.t) v v t{v/x} v ::= nv λx.t nv ::= 0 suc nv t v t t s v t s t v t suc t v suc t s v s v s v v s case 0 of 0 t suc x s v t case (suc nv) of 0 t suc x s v s{nv/x} t v t case t of 0 r suc x s v case t of 0 r suc x s fix x.t v t{fix x.t/x}