Лямбда-исчисление — различия между версиями
Komarov (обсуждение | вклад) (Новая страница: «{{В разработке}} \documentclass[11pt,a4paper,oneside]{article} \usepackage[english,russian]{babel} \usepackage[T2A]{fontenc} \usepackage[utf8]{inpute...») |
Komarov (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
{{В разработке}} | {{В разработке}} | ||
− | + | == Лямбда-исчисление== | |
− | + | ''Лямбда-исчисление'' {{---}} формальная система, придуманная в 1930-х годах | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
Алонзо Чёрчем. Лямбда-функция является, по сути, анонимной функцией. | Алонзо Чёрчем. Лямбда-функция является, по сути, анонимной функцией. | ||
Эта концепция показала себя удобной и сейчас активно используется во многих | Эта концепция показала себя удобной и сейчас активно используется во многих | ||
языках программирования. | языках программирования. | ||
− | Более формально, | + | Более формально, ''лямбда-функцию'' (или, ''лямбда-терм'') можно задать |
следующей грамматикой: | следующей грамматикой: | ||
− | + | {{Определение | |
− | + | |definition= | |
+ | <tex> | ||
\begin{array}{r c l} | \begin{array}{r c l} | ||
\langle Term \rangle & ::= & \langle Variable \rangle \\ | \langle Term \rangle & ::= & \langle Variable \rangle \\ | ||
Строка 196: | Строка 20: | ||
\langle Variable \rangle & ::= & \langle Char \rangle *\\ | \langle Variable \rangle & ::= & \langle Char \rangle *\\ | ||
\end{array} | \end{array} | ||
− | + | </tex> | |
+ | }} | ||
В первом случае функция является просто переменной. | В первом случае функция является просто переменной. | ||
− | Во втором происходит | + | Во втором происходит ''аппликация'' (''применение'') одной функции к другой. |
Это аналогично вычислению функции-левого операнда на аргументе-правом операнде. | Это аналогично вычислению функции-левого операнда на аргументе-правом операнде. | ||
− | В третьем | + | В третьем {{---}} ''абстракция'' по переменной. В данном случае происходит |
создание функции одного аргумента с заданными именем аргумента и телом функции. | создание функции одного аргумента с заданными именем аргумента и телом функции. | ||
− | Рассмотрим, например, функцию | + | Рассмотрим, например, функцию <tex>id = \lambda x \to x</tex>. Эта функция принимает аргумент и |
возвращает его неизменённым. Например, | возвращает его неизменённым. Например, | ||
− | + | <tex>id 2 \equiv 2</tex>. Аналогично, <tex>id y == y</tex>. | |
− | Ещё один пример функции: | + | Ещё один пример функции: <tex>sum = \lambda x \to \lambda y \to x + y|. Эта функция двух аргументов, |
которая возвращает их сумму. Правда, здесь мы немного вышли за написанную выше грамматику. | которая возвращает их сумму. Правда, здесь мы немного вышли за написанную выше грамматику. | ||
− | Ну да ладно. | + | Ну да ладно. <tex>sum 2 3 == 5</tex> |
− | + | ===Приоритет операций=== | |
− | + | * Применение левоассоциативно: <tex>x y z w == ((x y) z) w</tex> | |
− | + | * Аппликация забирает себе всё, до чего дотянется: <tex>\lambda x \to \lambda y \to \lambda z \to z y x \equiv \lambda x \to (\lambda y \to (\lambda z \to ((z y) x)))</tex> | |
− | + | * Скобки играют привычную роль группировки действий | |
− | |||
− | |||
− | |||
− | + | ===Свободные и связанные переменные=== | |
− | + | ''Связанными'' переменными называются все переменные, по которым выше в | |
дереве разбора были абстракции. Все остальные переменные называются свободными. | дереве разбора были абстракции. Все остальные переменные называются свободными. | ||
− | Например, в | + | Например, в <tex>\lambda x \to \lambda y \to x</tex>, <tex>x</tex> связана, а <tex>y</tex>{{---}} свободна. А в <tex>\lambda y \to x (\lambda x \to x)</tex> |
− | в своём первом вхождении переменная | + | в своём первом вхождении переменная <tex>x</tex> свободна, а во втором {{---}} связана. |
− | Рассмотрим функции | + | Рассмотрим функции <tex>\lambda y \to y</tex> и <tex>\lambda x \to y</tex>. В первой из них при взгляде на <tex>y</tex> |
понятно, что она имеет отношение к переменной, по которой производилась | понятно, что она имеет отношение к переменной, по которой производилась | ||
абстракция. Если по одной и той же | абстракция. Если по одной и той же | ||
переменной абстракция производилась более одного раза, то переменная связана | переменной абстракция производилась более одного раза, то переменная связана | ||
с самым поздним (самым нижним в дереве разбора) абстрагированием. Например, в | с самым поздним (самым нижним в дереве разбора) абстрагированием. Например, в | ||
− | + | <tex>\lambda x \to \lambda x \to \lambda y \to \lambda x \to x</tex>, переменная <tex>x</tex> связана с самой правой абстракцией | |
− | по | + | по <tex>x</tex>. |
− | + | ===<tex>\alpha</tex>-конверсия=== | |
− | Рассмотрим функции | + | Рассмотрим функции <tex>(\lambda x \to x) z</tex> и <tex>(\lambda y \to y) z</tex>. Интуитивно понятно, что они |
являются одинаковыми. | являются одинаковыми. | ||
− | + | {{Определение | |
− | + | |definition=''<tex>\alpha</tex>-конверсия'' {{---}} переименование связанной переменной. Выражение | |
− | где | + | <tex>\lambda x \to f</tex> можно заменить на <tex>\lambda y \to f[x := y]</tex>, если <tex>y</tex> не входит свободно в <tex>f</tex>, |
+ | где <tex>f[x:=y]</tex> означает замену всех свободных вхождений <tex>x</tex> в <tex>f</tex> на <tex>y</tex>. | ||
− | Функции, получающиеся одна из другой с помощью | + | Функции, получающиеся одна из другой с помощью <tex>\alpha</tex>-конверсий, называются |
− | + | ''<tex>\alpha</tex>-эквивалентными'' и обозначаются <tex>f \equiv_\alpha g</tex>. | |
− | Функции | + | Функции <tex>\lambda x \to \lambda y \to x y z</tex> и <tex>\lambda a \to \lambda x \to a x z</tex> являются <tex>\alpha</tex>-эквивалентными, |
− | а | + | а <tex>\lambda x \to \lambda y \to y z</tex> и <tex>\lambda y \to \lambda x \to y z</tex> {{---}} нет. |
\subsection{$\beta$-редукция} | \subsection{$\beta$-редукция} |
Версия 14:29, 6 декабря 2012
Содержание
Лямбда-исчисление
Лямбда-исчисление — формальная система, придуманная в 1930-х годах Алонзо Чёрчем. Лямбда-функция является, по сути, анонимной функцией. Эта концепция показала себя удобной и сейчас активно используется во многих языках программирования.
Более формально, лямбда-функцию (или, лямбда-терм) можно задать следующей грамматикой:
Определение: |
В первом случае функция является просто переменной.
Во втором происходит аппликация (применение) одной функции к другой.
Это аналогично вычислению функции-левого операнда на аргументе-правом операнде.
В третьем — абстракция по переменной. В данном случае происходит
создание функции одного аргумента с заданными именем аргумента и телом функции.
Рассмотрим, например, функцию
. Эта функция принимает аргумент и возвращает его неизменённым. Например, . Аналогично, .Ещё один пример функции:
Приоритет операций
- Применение левоассоциативно:
- Аппликация забирает себе всё, до чего дотянется:
- Скобки играют привычную роль группировки действий
Свободные и связанные переменные
Связанными переменными называются все переменные, по которым выше в дереве разбора были абстракции. Все остальные переменные называются свободными.
Например, в
, связана, а — свободна. А в в своём первом вхождении переменная свободна, а во втором — связана.Рассмотрим функции
и . В первой из них при взгляде на понятно, что она имеет отношение к переменной, по которой производилась абстракция. Если по одной и той же переменной абстракция производилась более одного раза, то переменная связана с самым поздним (самым нижним в дереве разбора) абстрагированием. Например, в , переменная связана с самой правой абстракцией по .-конверсия
Рассмотрим функции
и . Интуитивно понятно, что они являются одинаковыми.
Определение: |
можно заменить на , если не входит свободно в , где означает замену всех свободных вхождений в на . Функции, получающиеся одна из другой с помощью -конверсий, называются -эквивалентными и обозначаются .Функции и являются -эквивалентными, а и — нет.\subsection{$\beta$-редукция} $\beta$-редукция олицетворяет идею счёта значения функции. Выражение вида | -конверсия — переименование связанной переменной. Выражение
\rangle$. При этом, голова списка будет храниться как показатель степени при $p_{len}$.
\begin{code} empty = pair' `App` zero' `App` one' cons = Lam "h" $ Lam "t" $ pair' `App` (succ' `App` (fst `App` Var "t"))
`App` (mult' `App` (snd `App` Var "t") `App` (power' `App` (ithPrime `App` (fst `App` Var "t")) `App` Var "h" ))
head = Lam "list" $ getExponent `App` (snd `App` Var "list")
`App` (ithPrime `App` (pred' `App` (fst `App` Var "list")))
tail = Lam "list" $ pair' `App` (pred' `App` (fst `App` Var "list"))
`App` (eliminateMultiplier `App` (snd `App` Var "list") `App` (ithPrime `App` (pred' `App` (fst `App` Var "list" ))) )
eliminateMultiplier' = Lam "f" $ Lam "n" $ Lam "m" $ if `App` (isZero' `App` (mod' `App` Var "n" `App` Var "m"))
`App` (Var "f" `App` (div' `App` Var "n" `App` Var "m") `App` Var "m") `App` Var "n"
eliminateMultiplier = fix' `App` eliminateMultiplier'
getExponent' = Lam "f" $ Lam "n" $ Lam "m" $ if `App` (isZero' `App` (mod' `App` Var "n" `App` Var "m"))
`App` (succ' `App`(Var "f" `App` (div' `App` Var "n" `App` Var "m") `App` Var "m")) `App` zero'
getExponent = fix' `App` getExponent' \end{code}
На основе этого всего уже можно реализовать эмулятор машины тьюринга: с помощью пар, списков чисел можно хранить состояния. С помощью рекурсии можно обрабатывать переходы. Входная строка будет даваться, например, закодированной аналогично списку: пара из длины и числа, характеризующего список степенями простых. Я бы продолжил это писать, но уже на операции $head [1, 2]$ я не дождался окончания выполнения. Скорость лямбда-исчисления как вычислителя печальна.
\ignore{ \begin{code}
four' = norm $ succ' `App` three' five' = norm $ succ' `App` four'
list2 = norm $ cons `App` one' `App` empty list32 = cons `App` zero' `App` list2
normFiveFact = normIO 0 $ fact' `App` five'
-- fiftysix = mult twentyeight two -- fiftyfive = pred fiftysix -- six = pred seven
--main = do print $ fiftysix (+1) 0 main = do
-- f <- normIO 0 $ ithPrime `App` three' -- f <- normIO 0 $ getExponent `App` (norm $ plus' `App` four' `App` four') `App` two' f <- normIO 0 $ head `App` (tail `App` list32) print $ toInt f
\end{code} }
\end{document} [1]