Serguey Zefirov ([info]thesz) wrote,
@ 2005-05-29 00:45:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:лямбда исчисление

Лямбда-исчисление.
Коротко и неформально.

Лямбда-исчисление - это правила построения и вычисления безымянных функций.

И перейдем сразу к примерам.

Вот запись функции, которая получает на вход число и вычисляет значение, большее его на единицу:

    (\x.x+1)
Что здесь к чему? Сама функция записана в скобочках. Символ '\' будет впредь обозначать строчную греческую букву λ (кстати, в Haskell использется именно это обозначение, и такая безымянная функция в Haskell будет выглядеть \x -> x+1). Далее, до точки, идут аргументы функции, а после точки -- выражение.

Применение функций к аргументам записывается просто -- через пробел. Вот так:

    (\x.x+1) 2
Мы можем упрощать записанное нами выражение, подставляя вместо переменных их значения (бета-упрощение, бета-редукция):
    (\x.x+1) 2 -- применяем бета-редукцию, подстановку значений аргументов.
==> (2+1) -- применяем дельта-редукцию, то есть, вычисление функции от аргументов.
==> 3
Так оно и происходит. И даже в реальной жизни, когда идет рассуждение о программе.

Еще немного поупражняемся. Сделаем-ка функцию от двух аргументов, все ту же сумму:

    (\x y.x+y)
Ага, сделали. Что будет, если мы применим ее к одному аргументу? Сейчас выясним:
    (\x y.x+y) 1 -- примением бета-редукцию, заменим x на 1.
==> (\y.1+y)
Получили все ту же функцию увеличения на единицу, вид, так сказать, в профиль. То есть, если мы применим функцию к неполному числу аргументов, то получим другую функцию, которая должна получить оставшиеся аргументы.

И, в лучших традициях формальной математики, перепишем только что обнаруженный нами факт:

    (\x y.x+y) эквивалентно (\x.(\y.x+y))
Этот прием назвается карринг (currying), и именно он не стал шонфикелингом. ;)

Я еще упомяну о необходимости переименовывать переменные, чтобы после подстановки значений не возникало проблем, какой это y -- этот y является нашей переменной, или результатом подстановки?

Вот. А пока займемся другой проблемой. Посмотрим на выражение (\x.x x)(\x.x x). Попробуем его упростить:

    (\x.x x) (\x.x x) -- переименуем x в самом левом выражении в z.
    (\z.z z) (\x.x x) -- затем подставим вместо z его значение (\x.x x).
    ((\x.x x) (\x.x x)) -- где-то мы это уже видели.
Мы получили невычислимое выражение. Оно настолько просто, что его можно вычислять до бесконечности. ;) И оно чуть-чуть интереснее, чем банальное деление на ноль.

Зато это дает возможность продемонстрировать еще кое-что. На этот раз мы возьмем в качестве кандидата на упрощение следующее выражение -- (\x.1)((\x.x x) (\x.x x)).

Если мы начнем вычислять аргумент, то никогда не остановимся. Однако, если мы начнем сразу с тела функции ((\x.1) -- функция, которая всегда вычисляется в 1), то сразу придем к ответу -- 1. Отличие разительно, не находите?

Это пример того, как порядок вычисления выражений может оказать влияние на результат вычислений одного и того же выражения. Обычно выделяют два порядка вычислений: сперва упрощаем самый правый член в записи вычисления или сперва упрощаем самый левый член вычисления. Первый вариант приводит к тому, что сперва вычисляются все аргументы, а потом само выражение, а второй -- к тому, что мы откладываем вычисление аргументов до тех пор, пока они нам не понадобятся.

Второй вариант называется нормальным (или ленивым) порядком вычислений. Есть, даже, специальная теорема, которая доказывает, что если лямбда-выражение имеет значение, то оно всегда будет вычислено путем применения нормального порядка вычислений.

В свою очередь, первый вариант применяется энергичными (жадными) языками и легче для реализации. OCaml и LISP используют именно его.

Вообще, никакая современная программа не может обойтись без ленивых вычислений. Тот же if..then..else.. откладывает вычисления.

Кстати, а давайте сочиним условную конструкцию с помощью лямбда-исчисления? Хорошо, тем более, что это очень просто.

Что делает if c then a else b? В зависимости от значения c (condition, условия) оно выбирает либо значение a, либо значение b. Итак, конструкия if c then a else b -- это функция с тремя параметрами:

    (\c.a.b.???)
Нам надо выяснить, что может находиться вместо знаков вопроса.

Во-первых, там не может быть никаких if c then a else b, поскольку мы именно это и определяем. Во-вторых, там должен находится выбор значений a или b в зависимости от c, при этом на структуру самого c ограничений нет. Если мы примем значение (\a.b.a) за логическую истину, а значение (\a.b.b) -- за ложь, то можно подставить вместо знаков вопроса выражение c a b. Сейчас проверим:

    (\c.a.b.c a b) (\a.b.a) 1 2 -- то же, что if true then 1 else 2.
==> (\a.b.(\x.y.x) a b) 1 2
==> (\a.b.a) 1 2
==> 1
Вроде, правильно. Как записать if false then 1 else 2, и во что это раскроется, я оставлю в качестве упражнения.

Столь хитрые, на первый взгляд, манипуляции требуются редко, однако когда они нужны, до них легко дотянуться.

Например, в реальной программе можно легко сварганить свой собственный оператор управления выполнением, используя похожие методы. Несмотря на то, что в нашем решении практически никак не указывалось, как мы пришли к записи логических значений в виде функций, в жизни, обычно, присутствуют подсказки, на которые можно опираться. И вот такие примеры, которые дают общую идею. ;)

Ну, и в качестве заключения.

Я довольно долго исследовал всякие системы на предмет упрощения труда программиста. На данный момент я считаю, что лямбда-исчисление с ленивым порядком вычислений позволяет записать решения самым коротким способом при самой лучшей эффективности исполнения. То есть, если надо записать решение задачи короче, то будет значительно менее эффективно, при разнице в длине записи порядка десятка процентов, и не всегда в пользу не-Haskell записи (см. сравнение Haskell vs. Maude, есть такое в сети). А если надо эффективнее, то получится значительно длинее (Haskell vs. C, такое тоже есть).

На этом, пожалуй, все. ;)




(Post a new comment)


[info]morvic
2005-06-15 05:34 pm UTC (link)
здорово!
пиши исчо!
Предлагаю следующие темы
1. Деревья решений. Прямая и обратная цепочка рассуждений. Алгоритм CLS
2. Логика предикатов. Основные понятия. Особенности использования кванторов.
3. Индуктивный вывод. Виды математической индукции.
4. Рекурсия. Виды рекурсий.
5. Метод доказательства от противного.
6. Приведение к префиксной нормальной форме. Основные правила.
7. Скалемизация.
8. Приведение к клаузальной нормальной форме.
9. Метод резолюции для высказываний.
10. Алгоритм унификации. НОУ. Правила допустимости подстановок.
11. Метод резолюции для предикатов. Особенности метода при использовании равенств.
12. Генетические алгоритмы. Основные характеристики. Примеры. Разновидности алгоритмов
13. Нейронные сети. Основные понятия. Вероятностные сети. Карта Кохонена. LVQ. Сети Хоппфилда и BAM. Сеть BP – SOM

(Reply to this) (Thread)

Обязательно.
[info]thesz
2005-06-15 05:39 pm UTC (link)
Как только будет время.

Начну прямо с пятого пункта. ;)

А каким ветром тебя сюда занесло? ;)

(Reply to this) (Parent)

Книги на русском языке по ламбда-исчислению и комбинат
[info]askhome
2005-08-29 09:48 am UTC (link)
По-моему, российское сообщество аппликативных вычислений разделилось по написанию: лЯмбда-исчисление и лАмбда-исчисление. Это - в порядке юмора. Но поисковые механизмы Web это различают. Имеется целый ряд книг, за последнее время изданных в России. Подробное и элементарное изложение, есть глоссарии и библиографии. Вот некоторые ссылки: http://jurinfor.exponenta.ru ; http://vew.0catch.com ; http://www.microsoft.com/Rus/Msdnaa/Curricula/Default.mspx. Многие из книг с этих ссылок можно бесплатно загрузить. Перспективы исследований и открытые проблемы можно узнать на ссылке http://kuzichev.boom.ru.

(Reply to this) (Thread)

Re: Книги на русском языке по ламбда-исчислению и комбин
[info]thesz
2005-08-29 09:54 am UTC (link)
Ага.

Книга Вольфенгаген про вычисления с объектами у меня есть, но я до нее все никак не доберусь.

Ссылка на майкрософт интересна. Я сейчас эти две ссылки отдельным постом вынесу.

(Reply to this) (Parent)(Thread)

Re: Книги на русском языке по ламбда-исчислению и комбин - (Anonymous), 2007-09-10 10:02 pm UTC
Re: Книги на русском языке по ламбда-исчислению и комбин - [info]thesz, 2007-09-10 10:12 pm UTC
Re: Книги на русском языке по ламбда-исчислению и комбин
[info]thesz
2005-08-29 09:55 am UTC (link)
Что забыл спросить - каким ветром сюда-то занесло? ;)

(Reply to this) (Parent)


[info]yellow_spots
2006-12-12 02:41 am UTC (link)
отличная вещь для тех, кто хочет успеть выучить хотя бы что-нибудь в ночь перед экзамом.
спасибо.

(Reply to this) (Thread)


[info]thesz
2006-12-12 05:05 am UTC (link)
А это идея! ;)

(Reply to this) (Parent)(Thread)

(no subject) - [info]yellow_spots, 2006-12-12 05:41 am UTC
(no subject) - [info]thesz, 2006-12-12 07:40 am UTC
(no subject) - [info]yellow_spots, 2006-12-12 11:35 am UTC
(no subject) - [info]thesz, 2006-12-12 11:44 am UTC
(no subject) - [info]yellow_spots, 2006-12-12 12:13 pm UTC
(no subject) - [info]thesz, 2006-12-12 12:35 pm UTC
(no subject) - [info]lapanoid, 2008-06-24 12:44 am UTC
(no subject) - [info]thesz, 2008-06-24 08:08 am UTC
(no subject) - [info]lapanoid, 2008-06-24 12:33 pm UTC
(no subject) - [info]rapmyheadup, 2008-10-27 11:17 pm UTC
(no subject) - [info]thesz, 2008-10-27 11:22 pm UTC
(no subject) - [info]rapmyheadup, 2008-10-27 11:26 pm UTC

[info]lynoxod
2006-12-12 05:25 am UTC (link)
Елки, давно все думаю - а может таки "выучить" Хаскель?

(Reply to this) (Thread)


[info]thesz
2006-12-12 07:44 am UTC (link)
Зачем его учить? Его использовать надо. ;)

(Reply to this) (Parent)(Thread)

(no subject) - [info]lynoxod, 2006-12-12 08:32 am UTC
(no subject) - [info]thesz, 2006-12-12 09:06 am UTC
(no subject) - [info]nealar, 2006-12-12 11:09 am UTC
(no subject) - [info]alll, 2007-07-10 08:55 am UTC

[info]bilet_v_zirk
2006-12-12 10:15 am UTC (link)
ы

(Reply to this) (Thread)


[info]thesz
2006-12-12 10:22 am UTC (link)
Ну, извини. Доказательства я опустил, поскольку беру их на веру, многие не знаю, кое-какие не помню. Если хочешь, могу найти ссылки на литературу с доказательствами. ;)

(Reply to this) (Parent)(Thread)

(no subject) - [info]bilet_v_zirk, 2006-12-12 11:34 am UTC
(no subject) - [info]thesz, 2006-12-12 11:44 am UTC

[info]nealar
2006-12-12 11:09 am UTC (link)
Как вот так вот тречить комменты ко всем своим старым записям?

(Reply to this) (Thread)


[info]thesz
2006-12-12 11:11 am UTC (link)
У меня всюду стоит "присылать комменты на почту." Вот и приходят. ;)

(Reply to this) (Parent)


[info]_winnie
2006-12-12 12:14 pm UTC (link)
>(\x y.x+y) эквивалентно (\x.(\y.x+y))
А как в функцию (\x.(\y.x+y)) "передать" y, если "извне" виден только один параметр - (\x.что-то-там)?

(Reply to this) (Thread)


[info]_winnie
2006-12-12 12:18 pm UTC (link)
Понял. Передать надо в возвращаемое значение, которое тоже функция :]

(Reply to this) (Parent)(Thread)

(no subject) - [info]_winnie, 2006-12-12 12:19 pm UTC

[info]thesz
2006-12-12 12:34 pm UTC (link)
Вопсользоваться flip: flip f x y = f y x

(\f x y.f y x)

(Reply to this) (Parent)


[info]ni_ten_ichi_ryu
2008-06-23 02:14 pm UTC (link)
прошу прощения, но не ответите ли вы на один простой (как мне кажется) вопрос по теме? не конкретно по вашему посту, но тематика та же (лямбда исчесление).

вопрос: что означает запись 2 переменных подряд? например, \x.xx.
будели ли верным след., хотя бы отчасти:
(\x.xx)(\y.y)=(\y.y)(\y.y)=\y.y

т.е., нечто вроде "генератора" аппликаций.

заранее спасибо.

PS: возможно, терминология немного отличается, я читаю "ламбда исчисление" Берендрегта.

(Reply to this) (Thread)


[info]thesz
2008-06-23 02:18 pm UTC (link)
Будет верным. Практически полностью. ;)

Запись \x...\y...(x y) означает применение выражения x к аргументу y.

(Reply to this) (Parent)(Thread)

(no subject) - [info]ni_ten_ichi_ryu, 2008-06-23 04:31 pm UTC
(no subject) - [info]thesz, 2008-06-23 08:34 pm UTC
(no subject) - [info]ni_ten_ichi_ryu, 2008-06-24 07:30 am UTC

[info]antidvacher
2008-06-26 02:00 pm UTC (link)
Это псевдокод?

(Reply to this) (Thread)


[info]thesz
2008-06-26 02:18 pm UTC (link)
В смысле?

(Reply to this) (Parent)(Thread)

(no subject) - [info]antidvacher, 2008-06-26 02:24 pm UTC
(no subject) - [info]thesz, 2008-06-26 02:34 pm UTC

[info]sokoltry
2008-09-24 07:35 pm UTC (link)
Привет. Я что-то никак не могу въехать в этот хитрый редуцирующийся сам в себя терм: (\х. х х)(\х. х х). Запись х у - применение выражения x к аргументу y. Но у нас х не функция, а число. Однако, как я понял, в лямбда исчислении просто число - это функция типа (\y. x), что ей не передавай вернет х. Т.е. функция (\х. х х) что ей передашь, то и вернет, также как и вся эта хитрая (\х. х х)(\х. х х)?

(Reply to this) (Thread)


[info]thesz
2008-09-30 11:23 am UTC (link)
Советую от чисел абстрагироваться. ;)

(Reply to this) (Parent)(Thread)

(no subject) - [info]w_i_n_e_maker, 2009-06-11 11:02 pm UTC
(no subject) - [info]thesz, 2009-06-12 06:36 am UTC

[info]thesz
2008-09-30 03:04 pm UTC (link)
Вы не смотрите ни на какие числа, считайте что "функции" "вычисляют" путем переписывания какие-то абстрактные значения.

При этом некоторые значения можно сопоставить чему-то в реальной жизни (числа в аксиоматике Пеано: zero = (\s z.z), succ = (\s z.s) (по-моему,я навралж)), другие нельзя (вот как (\x.x x) (\x.x x)).

(Reply to this) (Parent)(Thread)

(no subject) - [info]rapmyheadup, 2008-10-27 11:24 pm UTC
(no subject) - [info]thesz, 2008-10-28 12:27 am UTC

[info]vieni
2009-03-18 11:52 am UTC (link)
Здорово! Все понятно, кроме того, что такое шонфикелинг.

(Reply to this) (Thread)


[info]thesz
2009-03-18 09:18 pm UTC (link)
То же самое, что и карринг. Он был изобретён Шонфинкелем и ещё кем-то из советских учёных.

(Reply to this) (Parent)


[info]tarhitai
2009-06-02 10:43 pm UTC (link)
Я случайно попал на эту страницу
у меня вопрос можете подсказать что можно сделать вот с этим

> Непосредственно само задание:
>
> lambdaX.if(>X3)X(>X5)
>
> Что с этим нужно сделать:
> Произвести Beta-редукцию, КЛ,КЛ-редукцию, граф, редукцию графа, код де'Брюйна, КАМ-код и вычислить.

Если откликнитесть, буду очень признателен

(Reply to this) (Thread)


[info]thesz
2009-06-03 12:45 am UTC (link)
Нет, не помогу.

(Reply to this) (Parent)


Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…