III_202_Lambda_2013.ppt
- Количество слайдов: 26
Теоретичні основи функціонального програмування. Лямбда-числення 2012 Лямбда-числення
Лямбда-терми (1/2) Лямбда-терми (визначаються індуктивно): – символи змінних та констант (база індукції); – (TU) – терм-аплікація; – (λx. T) – терм-абстракція: • потенційне уточнення одноаргументної анонімної (безіменної) функції; ° ° x – (зв'язана) змінна абстракції; T – тіло абстракції. Лямбда-числення 2
Лямбда-терми (2/2) – Домовленості щодо спрощення дужкової структури: • вважатимемо TUV скороченням ((TU)V) – лівоасоціативність аплікації; • замість (λx. (λy. T)) будемо писати λx. λy. T, а також λxy. T; • λx. TU розглядається як (λx. (TU)). (Загалом, пріоритет аплікації є найвищим. ) Лямбда-числення 3
Основне правило виводу (основне правило обчислення лямбдатермів): (λx. T)U T[x: =U] , де T[x: =U] є результатом текстових підстановок U замість x – правило часто називають β-конверсією або β-редукцією з огляду на "скорочуваність" запису терму. Приклад: (λwuv. wvu)(λxy. x) λuv. (λxy. x)vu λuv. (λy. v)u λuv. v Але виникають проблеми. Лямбда-числення 4
Але виникають проблеми Конфлікти з іменуванням (при підстановках). Приклад. Простіше зрозуміти для випадку розширеного лямбда-числення. – Розширені лямбда-числення можуть містити вбудовані (наперед визначені) функції, операції (як бінарні функції в інфіксній формі), константи. ) λx. λy. (x-y) – терм, що відповідає анонімній функції віднімання. λx. λy. (x-y) y λx. λy. (x-y) z λy. (y-y) =0? – β-редукцію обмежують "коректними" підстановками (такі обмеження спряжені з урахуванням зв'язаних й вільних входжень змінних та є досить традиційними); – уводять додаткове правило для перейменування змінних (α -конверсія) Лямбда-числення 5
Проблеми… А якщо кілька редексів? Підвирази лямбда-терму, до яких можна застосувати β-редукції, називають редексами (від redex - reducible expression). Один терм може містити кілька редексів. З якого починати, яку стратегію обрання редексів треба використовувати? ? – АПР (аплікативний порядок редукцій) обирається лівий серед найвнутрішніх редексів. Енергійні обчислення – НПР (нормальний порядок редукцій) спочатку обирається лівий зовнішній редекс. Ліниві обчислення Програмістські паралелі: АПР відповідає викликам параметрів функції за значеннями (by value), НПР – за іменами (by name). При наявності побічних ефектів можна отримувати різні результати. Зокрема, при виклику by name програмні обчислення виразу x+x можуть не давати очікуваного подвоєння. Лямбда-числення 6
А якщо кілька редексів у випадку чистих функцій ? Проблеми лишаються: (λx. λy. y) ((λz. z z)) 1) НПР (нормальний порядок редукцій) : (λx. λy. y) (… ) λy. y 2) АПР (аплікативний порядок редукцій) : (λz. z z) … Лямбда-числення Нескінчений цикл 7
Нормальні форми (1/2) Нормальна форма – форма без редексів. Важливі результати (Чорч –– Россер): – Нормальні форми, отримувані з використанням різних стратегій, є алфавітно еквівалентними (можуть бути зведеними одна до іншої αконверсіями). – Якщо для терма існує нормальна форма, то НПР стратегія гарантує досяжність цієї нормальної форми (з точністю до алфавітної еквівалентності). Лямбда-числення 8
Нормальні форми (2/2) Haskell використовує виклик за необхідністю (call by need). Це "оптимізований" варіант call by name стосовно чистих функцій: замість того, щоб переобчислювати аргумент при кожному використанні, при першому обчисленні всі входження аргументу заміняються отриманим значенням. Формально модифікується β-редукція (при НПР): вираз (λx. T)U має перетворюватись у let x=U in T. Приклад: (λx. x*x)(2+3) let x = 2+3 in (x*x) Лямбда-числення 9
Рекурсивні означення функцій та лямбда-числення (1/5) fact n = if n == 0 then 1 else n * fact(n-1) (Haskell) Але ж лямбда-числення використовує тільки анонімні функції! З аргументом n проблем немає – fact = λn. (if n == 0 then 1 else n * fact(n-1)) А як бути з рекурсією ? (Ім'я ж функції fact використовується у правій частині рівняння. ) (Зауважимо, що if then else можна розглядати як функцію у збагаченому лямбда-численні. Булевський тип та тип натуральних чисел можна змоделювати, але про це пізніше). Спробуємо надалі дослідити наступну функцію FACT (як лямбда-терм): FACT = λf. λn. (if n == 0 then 1 else n * f(n-1)) Лямбда-числення 10
Рекурсивні означення функцій та лямбда-числення (2/5) Y-комбінатори Функція нерухомої точки (частіше використовується термін Y-комбінатор) – це функція-обчислювач нерухомих точок (функцій): Y f = f(Y f). Визначальна властивість Y-комбінаторів Найбільш відомі приклади Y -комбінаторів : – Хаскелл Каррі: λh. (λx. h(xx)) – Алан Тьюринг: (λxy. (y(xxy))) Переконаємось, що Y f = f(Y f) у випадку комбінатора Каррі: Yf = λh. (λx. h(xx))f= Скористаємось β-редукцію (із підстановкою f замість h) Yf (λx. f(xx)) = Скористаємось β-редукцію (із підстановкою (λx. f(xx)) замість x) f((λx. f(xx))) Yf Лямбда-числення 11
Рекурсивні означення функцій та лямбда-числення (3/5) fact = λn. (if n == 0 then 1 else n * fact(n-1)) (*) Факторіал з рекурсивним означенням FACT = λf. λn. (if n==0 then 1 else n * f(n-1)) Візьмемо нерухому точку fct для FACT : fct = Y FACT. Тоді fct = FACT fct = λn. (if n==0 then 1 else n * fct(n-1)) (застосували β-редукцію з підстановкою fct замість f). Отже, fct = λn. (if n==0 then 1 else n * fct(n-1)) Але це ж і є “наш” факторіал! Порівняйте з (*) ! Таким чином, нерухома точка для FACT є нашою шуканою функцією – функцією обчислення факторіала. Перевіримо! Лямбда-числення 12
Рекурсивні означення функцій та лямбда-числення (4/5) Перевірка для 2! (За означенням fct). fct 2 = (Y FACT) 2 = (Скористаємось властивістю Y-комбінатора Y f = f(Y f) ) FACT (Y FACT) 2 = (Розпишемо зовнішній FACT) λf. λn. (if n==0 then 1 else n * f(n-1)) (Y FACT) 2 = (Застосуємо β-редукцію НПР із підстановкою (Y FACT) замість f) λn. (if n == 0 then 1 else n * ((Y FACT) (n-1))) 2 = (Застосуємо β-редукцію НПР із підстановкою 2 замість n та проведемо константні обчислення: if. . . ) 2 * ((Y FACT) 1) Комбінатору знову передається функція FACT як аргумент: – “саморозгортання” FACT ; – власне порядок обчислення відповідає звичному порядку обчислення факторіала. Лямбда-числення 13
Рекурсивні означення функцій та лямбда-числення (5/5) Перевірка для 2! (прод. ) Наступні кроки подібні: 2*((Y FACT) 1) 2*( FACT (Y FACT) 1 ) 2*( λf. λn. (if n==0 then 1 else n*f(n-1)) (Y FACT) 1) 2*( λn. (if n==0 then 1 else n*((Y FACT) (n-1))) 1) 2*(1*((Y FACT) 0)) 2*(1*(FACT (Y FACT) 0)) 2*(1*(λf. λn. (if n==0 then 1 else n*f(n-1)) (Y FACT) 0)) 2*(1*(λn. (if n==0 then 1 else n*((Y FACT) (n-1)))) 0)) 2*(1*(1)) = 2 Зауваження. Застосування "вбудованих" функцій до аргументів-констант формально спряжене з використанням ще однієї редукції – δ-редукції. Лямбда-числення 14
Взаємно-рекурсивні функції f 1 = F 1(f 1, f 2, . . . fn) f 2 = F 2(f 1, f 2, . . . fn). . . fn = Fn(f 1, f 2, . . . fn) Створимо кортеж T із n елементами: T = Tuple-n F 1(f 1, f 2, . . . fn) F 2(f 1, f 2, . . . fn). . . Fn(f 1, f 2, . . . fn) fi = Projection i T T = Tuple-n F 1((Projection 1 T), …, (Projection n T)) F 2((Projection 1 T), …, (Projection n T)). . . Fn((Projection 1 T), …, (Projection n T)) Одне рівняння! І далі можна скористатись комбінатором: Y (λT. Tuple-n F 1((Projection 1 T), …, (Projection n T))… Fn((Projection 1 T), …, (Projection n T))) Лямбда-числення 15
Приклад із двома взаємно-рекурсивними функціями f 1 = F 1(f 1, f 2) f 2 = F 2(f 1, f 2) Таке одне рівняння: P = pair F 1((fst P), (scd P)) pair x y = (x, y) fst (x, _) = x scd (_, y) = y F 2((fst P), (scd P)) Нотація Haskell. Пізніше побачимо, як можна ці функції змоделювати у лямбда-численні. Лямбда-числення 16
Моделювання булевських значень та функцій (1/4) TRUE = λx. λy. x = (скорочено)λxy. x TRUE повертає перший аргумент FALSE = λxy. y FALSE повертає другий аргумент NOT = λwuv. wvu AND = λuv. uvu OR = λuv. uuv Можна (і потрібно!) перевірити коректність визначення функцій. Лямбда-числення 17
Моделювання булевських значень та функцій (2/4) Перевірка NOT 1) NOT TRUE = NOT = λwuv. wvu TRUE =λxy. x FALSE = λxy. y (λwuv. wvu) (λxy. x) Застосуємо β-редукцію із підстановкою (λxy. x) замість w. λuv. (λxy. x)vu Застосуємо β-редукцію із підстановкою v замість x. λuv. (λy. v)u Застосуємо β-редукцію із підстановкою u замість y. λuv. v = FALSE 2) NOT FALSE = … =TRUE Лямбда-числення 18
Моделювання булевських значень та функцій (3/4) Перевірка AND = λuv. uvu TRUE =λxy. x FALSE = λxy. y 1) AND FALSE TRUE = (λuv. uvu)FALSE TRUE (Застосуємо β-редукцію із підстановкою FALSE замість u) (λv. FALSE v FALSE ) TRUE FALSE повертає другий аргумент (λv. FALSE)TRUE = FALSE 2) AND TRUE FALSE = Тут і вище можна було б замість TRUE записувати _. По суті перевірено AND FALSE = FALSE (λuv. uvu)TRUE FALSE (Застосуємо β-редукцію із підстановкою TRUE замість u) (λv. TRUE v TRUE )FALSE TRUE повертає перший аргумент (λv. v)FALSE = FALSE Лямбда-числення 3) AND TRUE = … =TRUE 19
Моделювання булевських значень та функцій (4/4) IF = λcte. cte (IF = λcond. λthen. λelse. cond then else) Інтуїтивно просто і прозоро! Згадаймо, що TRUE повертає перший аргумент, FALSE повертає другий аргумент Перевірка IF IF TRUE A B = (λcte. c t e ) TRUE A B (Застосуємо β-редукцію, а далі розглянемо два варіанти) а) (λte. TRUE t e ) A B Застосуємо двічі β-редукцію НПР TRUE A B = А TRUE повертає перший аргумент б) (λte. TRUE t e ) A B Застосуємо АПР, замінюючи TRUE t e на t (λte. t) A B = А Лямбда-числення 20
Моделювання натуральних значень та функцій (1/4) Нумерали Чорча: 0 1 2 3 … n = = λfx. x (як і FALSE повертає другий аргумент) λfx. fx λfx. f(fx) λfx. f(f(fx)) = λfx. f(. . . (fx). . . ) n Лямбда-числення 21
Моделювання натуральних значень та функцій (2/4) Операції над нумералами Чорча: NEXT = λnfx. f(nfx) – збільшення на одиницю; ADD = λmnfx. mf(nfx) – додавання; MLT = λmnfx. m(nf)x – множення; EXP = λmnfx. nmfx – піднесення у степінь; ISZERO = λn. n (λx. FALSE) TRUE; PRED = λn. n (λgk. ISZERO (g 1) k (ADD (g k) 1))(λv. 0) 0 (при відніманні вважається 0 -1=0 ) SUB = λmn. n PRED m Лямбда-числення 22
Моделювання натуральних значень та функцій (3/4) Перевірка ISZERO 0 = (λn. n (λx. FALSE) TRUE) 0 0 (λx. FALSE) TRUE = TRUE (0 як і FALSE повертає другий аргумент) ISZERO 1 = (λn. n (λx. FALSE) TRUE) 1 1 (λx. FALSE) TRUE (λfy. fy) (λx. FALSE) TRUE Застосуємо двічі β-редукцію (з попередньою α-конверсією!) (λx. FALSE) TRUE = FALSE 1 = λfx. fx 1 = λfy. fy Лямбда-числення 23
Моделювання натуральних значень та функцій (4/4) Перевірка ISZERO (прод. ) ISZERO 2 = (λn. n (λx. FALSE) TRUE) 2 2 (λx. FALSE) TRUE (λfy. f(fy)) (λx. FALSE) TRUE (λx. FALSE)((λx. FALSE)TRUE) = FALSE Не істотно! Подібні вирази будуть і при обчисленнях 3, 4 і т. д. Лямбда-числення ISZERO з аргументами 24
Моделювання структур даних. Пари (кортежі з 2 елементів): PAIR = λxyf. fxy FST = λp. p TRUE SСD = λp. p FALSE PAIR a b = (λf. f a b) Перевірка SСD (PAIR 2 3) = SСD ((λxyf. fxy) 2 3) = SCD ((λyf. f 2 y) 3) = SСD (λf. f 2 3) = (λp. p FALSE) (λf. f 2 3) = (λf. f 2 3) FALSE = FALSE 2 3 = 3 Лямбда-числення 25
Моделювання структур даних. LISP-подібні списки CONS = λhts. sht HEAD = λl. l TRUE TAIL = λl. l FALSE NIL = λx. TRUE NULL = λl. l (λh. λt. FALSE) Перевірка HEAD (CONS A B) = (λl. l TRUE) ((λhts. sht) A B) = HEAD (CONS A B)) = A ((λhts. sht) A B) TRUE = (λs. s A B) TRUE = λxy. x TRUE A B = A TRUE повертає перший аргумент Лямбда-числення 26
III_202_Lambda_2013.ppt