<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=83.234.102.107&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=83.234.102.107&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/83.234.102.107"/>
		<updated>2026-06-22T23:28:18Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D1%8F%D0%BC%D0%B1%D0%B4%D0%B0-%D0%B8%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5&amp;diff=36482</id>
		<title>Лямбда-исчисление</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D1%8F%D0%BC%D0%B1%D0%B4%D0%B0-%D0%B8%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5&amp;diff=36482"/>
				<updated>2014-04-26T09:46:04Z</updated>
		
		<summary type="html">&lt;p&gt;83.234.102.107: /* Комбинатор неподвижной точки */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
'''Лямбда-исчисление'''(''lambda calculus'') {{---}} формальная система, придуманная в 1930-х годах &lt;br /&gt;
Алонзо Чёрчем. Лямбда-функция является, по сути, анонимной функцией.&lt;br /&gt;
Эта концепция показала себя удобной и сейчас активно используется во многих&lt;br /&gt;
языках программирования.&lt;br /&gt;
&lt;br /&gt;
== Лямбда-исчисление==&lt;br /&gt;
&lt;br /&gt;
Более формально, ''лямбда-функцию'' (или, ''лямбда-терм'') можно задать &lt;br /&gt;
следующей грамматикой:&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\begin{array}{r c l}&lt;br /&gt;
\langle Term \rangle &amp;amp; ::= &amp;amp; \langle Variable \rangle \\&lt;br /&gt;
                       &amp;amp; | &amp;amp; \langle Term \rangle \langle Term \rangle \\&lt;br /&gt;
                       &amp;amp; | &amp;amp; \lambda \langle Variable \rangle\ .\ \langle Term \rangle\\&lt;br /&gt;
                       &amp;amp; | &amp;amp; ( \langle Term \rangle )\\&lt;br /&gt;
\langle Variable \rangle &amp;amp; ::= &amp;amp; \langle Char \rangle +\\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В первом случае функция является просто переменной. &lt;br /&gt;
Во втором происходит ''аппликация'' (''применение'') одной функции к другой.&lt;br /&gt;
Это аналогично вычислению функции-левого операнда на аргументе-правом операнде.&lt;br /&gt;
В третьем {{---}} ''абстракция'' по переменной. В данном случае происходит &lt;br /&gt;
создание функции одного аргумента с заданными именем аргумента и телом функции.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим, например, функцию &amp;lt;tex&amp;gt;\operatorname{id} = \lambda x\ .\ x&amp;lt;/tex&amp;gt;. Эта функция принимает аргумент и &lt;br /&gt;
возвращает его неизменённым. Например, &lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{id}\ 2 \equiv 2&amp;lt;/tex&amp;gt;. Аналогично, &amp;lt;tex&amp;gt;\operatorname{id}\ y \equiv y&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Ещё один пример функции: &amp;lt;tex&amp;gt;\operatorname{sum} = \lambda x\ .\ \lambda y\ .\ x + y&amp;lt;/tex&amp;gt;. Эта функция двух аргументов,&lt;br /&gt;
которая возвращает их сумму. Правда, здесь мы немного вышли за написанную выше грамматику.&lt;br /&gt;
Ну да ладно. &amp;lt;tex&amp;gt;\operatorname{sum}\ 2\ 3 \equiv 5&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Приоритет операций===&lt;br /&gt;
* Применение левоассоциативно: &amp;lt;tex&amp;gt;x\ y\ z\ w \equiv ((x\ y)\ z)\ w&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Аппликация забирает себе всё, до чего дотянется: &amp;lt;tex&amp;gt;\lambda x\ .\ \lambda y\ .\ \lambda z\ .\ z\ y\ x \equiv \lambda x\ .\ (\lambda y\ .\ (\lambda z\ .\ ((z\ y)\ x)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Скобки играют привычную роль группировки действий&lt;br /&gt;
&lt;br /&gt;
===Свободные и связанные переменные===&lt;br /&gt;
''Связанными'' переменными называются все переменные, по которым выше в &lt;br /&gt;
дереве разбора были абстракции. Все остальные переменные называются свободными.&lt;br /&gt;
&lt;br /&gt;
Например, в &amp;lt;tex&amp;gt;\lambda x\ .\ \lambda y\ .\ x&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; связана, а &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;{{---}} свободна. А в &amp;lt;tex&amp;gt;\lambda y\ .\ x (\lambda x\ .\ x)&amp;lt;/tex&amp;gt;&lt;br /&gt;
в своём первом вхождении переменная &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; свободна, а во втором {{---}} связана.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функции &amp;lt;tex&amp;gt;\lambda y\ .\ y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\lambda x\ .\ y&amp;lt;/tex&amp;gt;. В первой из них при взгляде на &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;&lt;br /&gt;
понятно, что она имеет отношение к переменной, по которой производилась &lt;br /&gt;
абстракция. Если по одной и той же&lt;br /&gt;
переменной абстракция производилась более одного раза, то переменная связана&lt;br /&gt;
с самым поздним (самым нижним в дереве разбора) абстрагированием. Например, в&lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda x\ .\ \lambda x\ .\ \lambda y\ .\ \lambda x\ .\ x&amp;lt;/tex&amp;gt;, переменная &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; связана с самой правой абстракцией &lt;br /&gt;
по &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===α-конверсия===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функции &amp;lt;tex&amp;gt;(\lambda x\ .\ x) z&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(\lambda y\ .\ y) z&amp;lt;/tex&amp;gt;. Интуитивно понятно, что они &lt;br /&gt;
являются одинаковыми. &lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=''&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;-конверсия'' {{---}} переименование связанной переменной. Выражение&lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda x\ .\ f&amp;lt;/tex&amp;gt; можно заменить на &amp;lt;tex&amp;gt;\lambda y\ .\ f[x := y]&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; не входит свободно в &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt;,&lt;br /&gt;
где &amp;lt;tex&amp;gt;f[x:=y]&amp;lt;/tex&amp;gt; означает замену всех свободных вхождений &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Функции, получающиеся одна из другой с помощью &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;-конверсий, называются &lt;br /&gt;
''&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;-эквивалентными'' и обозначаются &amp;lt;tex&amp;gt;f \equiv_\alpha g&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функции &amp;lt;tex&amp;gt;\lambda x\ .\ \lambda y\ .\ x\ y\ z&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\lambda a\ .\ \lambda x\ .\ a\ x\ z&amp;lt;/tex&amp;gt; являются &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;-эквивалентными,&lt;br /&gt;
а &amp;lt;tex&amp;gt;\lambda x\ .\ \lambda y\ .\ y\ z&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\lambda y\ .\ \lambda x\ .\ y\ z&amp;lt;/tex&amp;gt; {{---}} нет.&lt;br /&gt;
&lt;br /&gt;
===β-редукция===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукция олицетворяет идею счёта значения функции. Выражение вида &lt;br /&gt;
&amp;lt;tex&amp;gt;(\lambda x\ .\ f)\ y&amp;lt;/tex&amp;gt; можно заменить на &amp;lt;tex&amp;gt;f[x := y]&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;f[x:=y]&amp;lt;/tex&amp;gt;, как и ранее, означает&lt;br /&gt;
замену всех свободных вхождений &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Через &amp;lt;tex&amp;gt;f \to_\beta g&amp;lt;/tex&amp;gt; обозначают сведение &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; с помощью одной &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукции.&lt;br /&gt;
А через &amp;lt;tex&amp;gt;f \to_\beta^* g&amp;lt;/tex&amp;gt; {{---}} за ноль или более.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Нотация Де Брюина==&lt;br /&gt;
Существует также альтернативное эквивалентное определение &amp;lt;tex&amp;gt;\lambda&amp;lt;/tex&amp;gt;-исчисления.&lt;br /&gt;
В оригинальном определении для обозначения переменных использовались имена,&lt;br /&gt;
и была проблема с тем, что не были запрещены одинаковые имена в разных&lt;br /&gt;
абстракциях. &lt;br /&gt;
&lt;br /&gt;
От этой проблемы можно избавиться следующим образом. Вместо имени переменной &lt;br /&gt;
будет храниться натуральное число {{---}} количество абстракций в дереве разбора,&lt;br /&gt;
на которое нужно подняться, чтобы найти ту лямбду, с которой данная переменная &lt;br /&gt;
связана. В данной нотации получаются несколько более простые определения &lt;br /&gt;
свободных переменных и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукции. &lt;br /&gt;
&lt;br /&gt;
Переменная называется свободной, если ей соответствует число, которое больше&lt;br /&gt;
количества абстракций на пути до неё в дереве разбора.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукции же нужно будет ко всем свободным переменным заменяющего &lt;br /&gt;
дерева при каждой замене прибавить число, равное разницы уровней раньше и сейчас.&lt;br /&gt;
Это будет соответствовать тому, что эта переменная продолжит &amp;lt;&amp;lt;держаться&amp;gt;&amp;gt; за&lt;br /&gt;
ту же лямбду, что и раньше.&lt;br /&gt;
&lt;br /&gt;
==Нумералы Чёрча и программирование на &amp;lt;tex&amp;gt;\lambda&amp;lt;/tex&amp;gt;-исчислении==&lt;br /&gt;
&lt;br /&gt;
===Определение===&lt;br /&gt;
Введём на основе лямбда-исчисления аналог натуральных чисел, основанный на идее, &lt;br /&gt;
что натуральное число {{---}} это или ноль, или увеличенное на единицу натуральное &lt;br /&gt;
число.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;\bar 0 = \lambda s\ .\ \lambda z\ .\ z&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt;\bar 1 = \lambda s\ .\ \lambda z\ .\ s\ z&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt;\bar 2 = \lambda s\ .\ \lambda z\ .\ s\ (s\ z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt;\bar 3 = \lambda s\ .\ \lambda z\ .\ s\ (s\ (s\ z))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждое число будет функцией двух аргументов: какой-то функции и начального значения.&lt;br /&gt;
Число &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз применять функцию к начальному значению и возвращать &lt;br /&gt;
результат. Если такому &amp;lt;&amp;lt;числу&amp;gt;&amp;gt; дать на вход функцию &amp;lt;tex&amp;gt;(+1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; в качестве &lt;br /&gt;
начального значения, то на выходе как раз будет ожидаемое от функции число:&lt;br /&gt;
&amp;lt;tex&amp;gt;\bar 3\ (+1)\ 0 \equiv 3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===+1===&lt;br /&gt;
Функция, прибавляющая 1 к числу, должна принимать первым аргументом число.&lt;br /&gt;
Но число {{---}} функция двух аргументов. Значит, эта функция должна принимать три&lt;br /&gt;
аргумента: &amp;lt;&amp;lt;число&amp;gt;&amp;gt; &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, которое хочется увеличить, функция, которую надо будет&lt;br /&gt;
&amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; раз применить, и начальное значение.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{succ} = \lambda n\ .\ \lambda s\ .\ \lambda z\ .\ s\ (n\ s\ z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;tex&amp;gt;n\ s\ z&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз применённая к &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; функция &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Но нужно применить &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; &lt;br /&gt;
раз. Отсюда &amp;lt;tex&amp;gt;s\ (n\ s\ z)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Сложение===&lt;br /&gt;
Сложение двух чисел похоже на прибавление единицы. Но только надо прибавить не единицу, а второе число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{plus} = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ n\ s\ (m\ s\ z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз применить &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; к применённому &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; раз &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(\operatorname{plus}\ \bar 3\ \bar 3)\ (+1)\ 0 \equiv 6&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Умножение===&lt;br /&gt;
Умножение похоже на сложение, но прибавлять надо не единицу, а второе число.&lt;br /&gt;
Или, в терминах нумералов Чёрча, в качестве применяемой несколько раз&lt;br /&gt;
функции должна быть не &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, а функция, применяющая &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{mult} = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ n\ (m\ s)\ z&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;tex&amp;gt;m\ s&amp;lt;/tex&amp;gt; {{---}} функция, которая &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; раз применит &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; к тому, что дадут ей на &lt;br /&gt;
вход. С помощью &amp;lt;tex&amp;gt;\eta&amp;lt;/tex&amp;gt;-редукции можно немного сократить эту формулу&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{mult} = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ n\ (m\ s)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(\operatorname{mult} \bar 3\ \bar 3)\ (+1)\ 0 \equiv 9&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Возведение в степень===&lt;br /&gt;
It's a kind of magic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{power} = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ m\ n\ s\ z&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(\operatorname{power}\ \bar 3\ (\operatorname{succ}\ \bar 3))\ (+1)\ 0 \equiv 81&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Логические значения===&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{true} = \lambda a\ .\ \lambda b\ .\ a&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{false} = \lambda a\ .\ \lambda b\ .\ b&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Функции двух аргументов, возвращающие первый и второй, соответственное, аргументы.&lt;br /&gt;
Забавный факт: &amp;lt;tex&amp;gt;\operatorname{false} \equiv_\alpha \operatorname{zero}&amp;lt;/tex&amp;gt;. Эти функции сделаны такими для того, &lt;br /&gt;
чтобы красиво написать функцию &amp;lt;tex&amp;gt;\operatorname{if}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{if} = \lambda p\ .\ \lambda t\ .\ \lambda e\ .\ p\ t\ e&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ей в качестве первого аргумента дадут &amp;lt;tex&amp;gt;\operatorname{true}&amp;lt;/tex&amp;gt;, то вернётся &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, иначе {{---}} &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Стандартные функции булевой логики:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{and} = \lambda n\ .\ \lambda m\ .\ \operatorname{if} n\ m\ \operatorname{false}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{or} = \lambda n\ .\ \lambda m\ .\ \operatorname{if} n\ \operatorname{true} m&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{not} = \lambda b\ .\ \operatorname{if} b\ \operatorname{false} \operatorname{true}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ещё одной важной функцией является функция проверки, является ли число нулём:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isZero} = \lambda n\ .\ n\ (\lambda c\ .\ \operatorname{false})\ \operatorname{true}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Функция выглядит несколько странно. &amp;lt;tex&amp;gt;\lambda c -&amp;gt; \operatorname{false}&amp;lt;/tex&amp;gt; {{---}} функция, которая независимо&lt;br /&gt;
от того, что ей дали на вход, возвращает &amp;lt;tex&amp;gt;\operatorname{false}&amp;lt;/tex&amp;gt;. Тогда, если в качестве &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
будет дан ноль, то функция, по определению нуля, не выполнится ни разу, и будет&lt;br /&gt;
возвращено значение по умолчанию &amp;lt;tex&amp;gt;\operatorname{true}&amp;lt;/tex&amp;gt;. Иначе же функция будет запущено, и &lt;br /&gt;
вернётся &amp;lt;tex&amp;gt;\operatorname{false}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Пара===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{pair} = \lambda a\ .\ \lambda b\ .\ \lambda t\ .\ t\ a\ b&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fst} = \lambda p\ .\ p\ \operatorname{true}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{snd} = \lambda p\ .\ p\ \operatorname{false}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;tex&amp;gt;\operatorname{pair}&amp;lt;/tex&amp;gt; принимает два значения и запаковывает их в пару так, чтобы к ним можно было обращаться по &amp;lt;tex&amp;gt;\operatorname{fst}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\operatorname{snd}&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\operatorname{fst}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\operatorname{snd}&amp;lt;/tex&amp;gt; вместо &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\operatorname{pair}&amp;lt;/tex&amp;gt; будет подставлено &amp;lt;tex&amp;gt;\operatorname{true}&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;\operatorname{false}&amp;lt;/tex&amp;gt;, возвращающие, соответственно, первый и второй аргументы, то есть &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, соответственно.&lt;br /&gt;
&lt;br /&gt;
===Вычитание===&lt;br /&gt;
В отличие от всех предыдущих функций, вычитание для натуральных чисел определено только в случае, если уменьшаемое больше вычитаемого. Положим в противном случае результат равным нулю. Пусть уже есть функция, которая вычитает из числа единицу. Тогда на её основе легко сделать, собственно, вычитание.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{minus} = \lambda n\ .\ \lambda m\ .\ m\ \operatorname{pred} n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это то же самое, что &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; раз вычесть единицу из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Осталось, собственно, функция для вычитания единицы. Однако, это не так просто, как может показаться на первый взгляд. Проблема в том, что, имея функцию, которую нужно применить для того, чтобы продвинуться вперёд, продвинуться назад будет проблематично. Если попробовать воспользоваться идеей о том, чтобы, начав от нуля, идти вперёд, и пройти на один шаг меньше, то будет не очень понятно, как же остановиться ровно за один шаг до конца. Для реализации вычитания единицы сделаем следующее. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз выполним следующее: имея пару &amp;lt;tex&amp;gt;\langle n-1, n-2\rangle&amp;lt;/tex&amp;gt; построим пару &amp;lt;tex&amp;gt;\langle n, n-1\rangle&amp;lt;/tex&amp;gt;. Тогда после &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов во втором элементе пары будет записано число &amp;lt;tex&amp;gt;n-1&amp;lt;/tex&amp;gt;, которое и хочется получить. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{pred} = \lambda n\ .\ \lambda s\ .\ \lambda z.\ \operatorname{snd}\ (&lt;br /&gt;
   n\ (&lt;br /&gt;
          \lambda p\ .\ \operatorname{pair}\ (s\ (\operatorname{fst} p))\ (\operatorname{fst} p)&lt;br /&gt;
     )\ (\operatorname{pair}\ z\ z))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если вы ничего не поняли, не огорчайтесь. Вычитание придумал Клини, когда ему вырывали зуб мудрости. А сейчас наркоз уже не тот.&lt;br /&gt;
&lt;br /&gt;
===Сравнение===&lt;br /&gt;
Так как вычитание определено таким способом, чтобы для случая, в котором уменьшаемое больше, чем вычитаемое, возвращать ноль, можно определить сравнение на больше-меньше через него. Равными же числа &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; считаются, если &amp;lt;tex&amp;gt;a - b = 0 \wedge b - a = 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{le} = \lambda n\ .\ \lambda m\ .\ \operatorname{isZero}\ (\operatorname{minus}\ n\ m)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{less} = \lambda n\ .\ \lambda m\ .\ \operatorname{le}\ n\ (\operatorname{pred} m)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{eq} = \lambda n\ .\ \lambda m\ .\ \operatorname{and}\ (\operatorname{isZero}\ (\operatorname{minus}\ n\ m))\ &lt;br /&gt;
(\operatorname{isZero}\ (\operatorname{minus}\ m\ n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Комбинатор неподвижной точки===&lt;br /&gt;
Попробуем выразить в лямбда-исчислении какую-нибудь функцию, использующую рекурсию. Напрмер, факториал.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fact} = \lambda x\ .\ \operatorname{if}\ (\operatorname{isZero}\ x)\ \bar 1\ (\operatorname{fact}\ (\operatorname{pred}\ x))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Мы столкнулись с проблемой. В определении функции &amp;lt;tex&amp;gt;\operatorname{fact}&amp;lt;/tex&amp;gt; используется функция &amp;lt;tex&amp;gt;\operatorname{fact}&amp;lt;/tex&amp;gt;. При формальной замене, получим бесконечную функцию. Можно попытаться решить эту проблему следующим образом&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fact} = (\lambda f\ .\ \lambda x\ .\ \operatorname{if}\ (\operatorname{isZero}\ x)\ \bar 1\ (f\ (\operatorname{pred}\ x)))\ \operatorname{fact}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=''Неподвижной точкой'' лямбда-функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; назовём такую функцию &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, что&lt;br /&gt;
&amp;lt;tex&amp;gt;f\ x \to_\beta^* x&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Лямбда исчисление обладаем замечательным свойством: у каждой функции есть неподвижная точка!&lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую функцию. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fix} = \lambda f\ .\ (\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tex&amp;gt;\operatorname{fix} \to_\beta^* \lambda f\ .\ f\ ((\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Или, что то же самое, &lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda f\ .\ (\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)) \to_\beta^*&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda f\ .\ f\ ((\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fact'} = \lambda f\ .\ \lambda x\ .\ \operatorname{if}\ (\operatorname{isZero}\ x)\ \bar 1\ (\operatorname{mult}\ x\ (f\ (\operatorname{pred}\ x)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как было показано выше, &amp;lt;tex&amp;gt;\operatorname{fix} f \to_\beta^* f\ (\operatorname{fix} f)&amp;lt;/tex&amp;gt;, то есть, &amp;lt;tex&amp;gt;\operatorname{fix}\ \operatorname{fact'} \to_\beta^* \operatorname{fact}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\operatorname{fact}&amp;lt;/tex&amp;gt; {{---}} искомая функция, считающая факториал.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fact} = \operatorname{fix}\ \operatorname{fact'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это даст функцию, которая посчитает факториал числа. Но делать она это будет мееедленно-меееедленно. Для того, чтобы посчитать &amp;lt;tex&amp;gt;5!&amp;lt;/tex&amp;gt; потребовалось сделать 66066 &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукций.&lt;br /&gt;
&lt;br /&gt;
Тут правда ничего не понятно? :'(&lt;br /&gt;
&lt;br /&gt;
===Деление===&lt;br /&gt;
Воспользовавшись идеей о том, что можно делать рекурсивные функции, сделаем функцию, которая будет искать частное двух чисел.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{div'} = \lambda div\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname{if}\ (\operatorname{less}\ n\ m)\ \bar 0\ (\operatorname{succ}\ (div\ (\operatorname{minus}\ n\ m)\ m))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{div} = \operatorname{fix}\ \operatorname{div'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И остатка от деления&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{mod'} = \lambda mod\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname{if}\ (\operatorname{less}\ n\ m)\ n\ (mod\ (\operatorname{minus}\ n\ m)\ m)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{mod} = \operatorname{fix}\ \operatorname{mod'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка на простоту===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isPrimeHelp}&amp;lt;/tex&amp;gt; {{---}} принимает число, которое требуется проверить на простоту и то, на что его надо опытаться поделить, перебирая это от 2 до &amp;lt;tex&amp;gt;p-1&amp;lt;/tex&amp;gt;. Если на что-нибудь разделилось, то число {{---}} составное, иначе {{---}} простое.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isPrimeHelp'} =&amp;lt;/tex&amp;gt;&amp;lt;tex&amp;gt;\lambda f\ .\ \lambda p\ .\ \lambda i\ .\ \operatorname{if}\ (\operatorname{le}\ p\ i)\ \operatorname{true}\ (\operatorname{if}\ (\operatorname{isZero}\ (\operatorname{mod}\ p\ i))\ \operatorname{false}\ (f\ p\ (\operatorname{succ}\ i)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isPrimeHelp} = \operatorname{fix}\ \operatorname{isPrimeHelp'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isPrime} = \lambda p\ .\ \operatorname{isPrimeHelp}\ p\ \bar 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следующее простое число. &amp;lt;tex&amp;gt;\operatorname{nextPrime'}&amp;lt;/tex&amp;gt; {{---}} следующее, больше либо равное заданного, &amp;lt;tex&amp;gt;\operatorname{nextPrime}&amp;lt;/tex&amp;gt; {{---}} следующее, большее заданного.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{nextPrime''} = \lambda f\ .\ \lambda p\ .\ \operatorname{if}\ (\operatorname{isPrime}\ p)\ p\ (f\ (\operatorname{succ}\ p)) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{nextPrime'} = \operatorname{fix}\ \operatorname{nextPrime'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{nextPrime} = \lambda p\ .\ \operatorname{nextPrime'}\ (\operatorname{succ}\ p)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{ithPrimeStep}&amp;lt;/tex&amp;gt; пропрыгает &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; простых чисел вперёд. &amp;lt;tex&amp;gt;\operatorname{ithPrime}&amp;lt;/tex&amp;gt; принимает число &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и пропрыгивает столько простых чисел вперёд, начиная с двойки.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{ithPrimeStep'} = \lambda f\ .\ \lambda p\ .\ \lambda i\ .\ \operatorname{if}\ (\operatorname{isZero}\ i)\ p\ (f\  (\operatorname{nextPrime}\ p)\ (\operatorname{pred}\ i))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{ithPrimeStep} = \operatorname{fix}\ \operatorname{ithPrimeStep'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{ithPrime} = \lambda i\ .\ \operatorname{ithPrimeStep}\ \bar 2\ i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...и всего через 314007 &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукций вы узнаете, что третье простое число {{---}} семь!&lt;br /&gt;
&lt;br /&gt;
===Списки===&lt;br /&gt;
&lt;br /&gt;
Для работы со списками чисел нам понадобятся следующие функции:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{empty}&amp;lt;/tex&amp;gt; {{---}} возвращает пустой список&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{cons}&amp;lt;/tex&amp;gt; {{---}} принимает первый элемент и оставшийся список, склеивает их&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{head}&amp;lt;/tex&amp;gt; {{---}} вернуть голову списка&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{tail}&amp;lt;/tex&amp;gt; {{---}} вернуть хвост списка&lt;br /&gt;
&lt;br /&gt;
Список будем хранить в следующем виде: &amp;lt;tex&amp;gt;\langle len, p_1^{a_1}p_2^{a_2}\ldots p_{len}^{a_{len}} \rangle&amp;lt;/tex&amp;gt;. При этом, голова списка будет храниться как показатель степени при &amp;lt;tex&amp;gt;p_{len}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{empty} = \operatorname{pair}\ \operatorname{zero}\ \bar 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{cons} = \lambda h\ .\ \lambda t\ .\ \operatorname{pair}\ (\operatorname{succ}\ (\operatorname{fst}\ t))\ (\operatorname{mult}\ (\operatorname{snd}\ t)\ (\operatorname{power}\ (\operatorname{ithPrime}\ (\operatorname{fst}\ t))\ h))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{head} = \lambda list\ .\ \operatorname{getExponent}\ (\operatorname{snd}\ list)\ (\operatorname{ithPrime}\ (\operatorname{pred}\ (\operatorname{fst}\ list)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{tail} = \lambda list\ .\ \operatorname{pair}\ (\operatorname{pred}\ (\operatorname{fst}\ list))&lt;br /&gt;
 (\operatorname{eliminateMultiplier}\ (\operatorname{snd}\ list)\ (\operatorname{ithPrime}\ (\operatorname{pred}\ (\operatorname{fst}\ list))))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{eliminateMultiplier'} =&amp;lt;/tex&amp;gt;&amp;lt;tex&amp;gt; \lambda f\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname{if}\ (\operatorname{isZero}\ (\operatorname{mod}\ n\ m))\ (f\ (\operatorname{div}\ n\ m)\ m)\ n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{eliminateMultiplier} = \operatorname{fix}\ \operatorname{eliminateMultiplier'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{getExponent'} =&amp;lt;/tex&amp;gt;&amp;lt;tex&amp;gt; \lambda f\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname{if}\ (\operatorname{isZero}\ (\operatorname{mod}\ n\ m))\ (\operatorname{succ}\ (f\ (\operatorname{div}\ n\ m)\ m))\ \bar 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{getExponent} = \operatorname{fix}\ \operatorname{getExponent'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выводы==&lt;br /&gt;
&lt;br /&gt;
На основе этого всего уже можно реализовать эмулятор машины тьюринга: с помощью пар, списков чисел можно хранить состояния. С помощью рекурсии можно обрабатывать переходы. Входная строка будет даваться, например, закодированной аналогично списку: пара из длины и числа, характеризующего список степенями простых. Я бы продолжил это писать, но уже на операции &amp;lt;tex&amp;gt;\operatorname{head} [1, 2]&amp;lt;/tex&amp;gt; я не дождался окончания выполнения. Скорость лямбда-исчисления как вычислителя печальна.&lt;br /&gt;
&lt;br /&gt;
==Примеры (слабонервным не смотреть)==&lt;br /&gt;
&lt;br /&gt;
====fact====&lt;br /&gt;
(\f.(\x.f (x x)) (\x.f (x x))) (\f.\x.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) (x)) (\s.\z.s z) ((\n.\m.\s.n (m s)) (x) (f ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (x)))))&lt;br /&gt;
&lt;br /&gt;
====head====&lt;br /&gt;
\list.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\n.\m.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) ((\f.(\x.f (x x)) (\x.f (x x))) (\mod.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) n (mod ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m)) n m)) ((\n.\s.\z.s (n s z)) (f ((\f.(\x.f (x x)) (\x.f (x x))) (\div.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) (\s.\z.z) ((\n.\s.\z.s (n s z)) (div ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m))) n m) m)) (\s.\z.z)) ((\p.p (\a.\b.b)) (list)) ((\i.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.\i.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) (i)) p (f ((\p.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.(\p.\t.\e.p t e) ((\p.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.\i.(\p.\t.\e.p t e) ((\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (p) i) (\a.\b.a) ((\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) ((\f.(\x.f (x x)) (\x.f (x x))) (\mod.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) n (mod ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m)) p i)) (\a.\b.b) (f p ((\n.\s.\z.s (n s z)) (i))))) p (\s.\z.s (s z))) (p)) p (f ((\n.\s.\z.s (n s z)) (p)))) ((\n.\s.\z.s (n s z)) (p))) (p)) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (i)))) (\s.\z.s (s z)) i) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) ((\p.p (\a.\b.a)) (list))))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====tail====&lt;br /&gt;
\list.(\a.\b.\t.t a b) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) ((\p.p (\a.\b.a)) (list))) ((\f.(\x.f (x x)) (\x.f (x x))) (\f.\n.\m.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) ((\f.(\x.f (x x)) (\x.f (x x))) (\mod.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) n (mod ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m)) n m)) (f ((\f.(\x.f (x x)) (\x.f (x x))) (\div.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) (\s.\z.z) ((\n.\s.\z.s (n s z)) (div ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m))) n m) m) n) ((\p.p (\a.\b.b)) (list)) ((\i.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.\i.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) (i)) p (f ((\p.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.(\p.\t.\e.p t e) ((\p.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.\i.(\p.\t.\e.p t e) ((\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (p) i) (\a.\b.a) ((\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) ((\f.(\x.f (x x)) (\x.f (x x))) (\mod.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) n (mod ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m)) p i)) (\a.\b.b) (f p ((\n.\s.\z.s (n s z)) (i))))) p (\s.\z.s (s z))) (p)) p (f ((\n.\s.\z.s (n s z)) (p)))) ((\n.\s.\z.s (n s z)) (p))) (p)) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (i)))) (\s.\z.s (s z)) i) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) ((\p.p (\a.\b.a)) (list)))))&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Lambda-calculus Английская Википедия]&lt;br /&gt;
&lt;br /&gt;
[http://ru.wikipedia.org/wiki/%D0%9B%D1%8F%D0%BC%D0%B1%D0%B4%D0%B0-%D0%B8%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5 Русская Википедия]&lt;br /&gt;
&lt;br /&gt;
[http://rain.ifmo.ru/~komarov/Turing.lhs Тут можно это всё потыкать]&lt;br /&gt;
&lt;br /&gt;
[http://worrydream.com/AlligatorEggs А это игра про крокодильчиков]&lt;/div&gt;</summary>
		<author><name>83.234.102.107</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D1%8F%D0%BC%D0%B1%D0%B4%D0%B0-%D0%B8%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5&amp;diff=36481</id>
		<title>Лямбда-исчисление</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D1%8F%D0%BC%D0%B1%D0%B4%D0%B0-%D0%B8%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5&amp;diff=36481"/>
				<updated>2014-04-26T09:24:38Z</updated>
		
		<summary type="html">&lt;p&gt;83.234.102.107: Поправил mult без η-редукции&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
'''Лямбда-исчисление'''(''lambda calculus'') {{---}} формальная система, придуманная в 1930-х годах &lt;br /&gt;
Алонзо Чёрчем. Лямбда-функция является, по сути, анонимной функцией.&lt;br /&gt;
Эта концепция показала себя удобной и сейчас активно используется во многих&lt;br /&gt;
языках программирования.&lt;br /&gt;
&lt;br /&gt;
== Лямбда-исчисление==&lt;br /&gt;
&lt;br /&gt;
Более формально, ''лямбда-функцию'' (или, ''лямбда-терм'') можно задать &lt;br /&gt;
следующей грамматикой:&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\begin{array}{r c l}&lt;br /&gt;
\langle Term \rangle &amp;amp; ::= &amp;amp; \langle Variable \rangle \\&lt;br /&gt;
                       &amp;amp; | &amp;amp; \langle Term \rangle \langle Term \rangle \\&lt;br /&gt;
                       &amp;amp; | &amp;amp; \lambda \langle Variable \rangle\ .\ \langle Term \rangle\\&lt;br /&gt;
                       &amp;amp; | &amp;amp; ( \langle Term \rangle )\\&lt;br /&gt;
\langle Variable \rangle &amp;amp; ::= &amp;amp; \langle Char \rangle +\\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В первом случае функция является просто переменной. &lt;br /&gt;
Во втором происходит ''аппликация'' (''применение'') одной функции к другой.&lt;br /&gt;
Это аналогично вычислению функции-левого операнда на аргументе-правом операнде.&lt;br /&gt;
В третьем {{---}} ''абстракция'' по переменной. В данном случае происходит &lt;br /&gt;
создание функции одного аргумента с заданными именем аргумента и телом функции.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим, например, функцию &amp;lt;tex&amp;gt;\operatorname{id} = \lambda x\ .\ x&amp;lt;/tex&amp;gt;. Эта функция принимает аргумент и &lt;br /&gt;
возвращает его неизменённым. Например, &lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{id}\ 2 \equiv 2&amp;lt;/tex&amp;gt;. Аналогично, &amp;lt;tex&amp;gt;\operatorname{id}\ y \equiv y&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Ещё один пример функции: &amp;lt;tex&amp;gt;\operatorname{sum} = \lambda x\ .\ \lambda y\ .\ x + y&amp;lt;/tex&amp;gt;. Эта функция двух аргументов,&lt;br /&gt;
которая возвращает их сумму. Правда, здесь мы немного вышли за написанную выше грамматику.&lt;br /&gt;
Ну да ладно. &amp;lt;tex&amp;gt;\operatorname{sum}\ 2\ 3 \equiv 5&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Приоритет операций===&lt;br /&gt;
* Применение левоассоциативно: &amp;lt;tex&amp;gt;x\ y\ z\ w \equiv ((x\ y)\ z)\ w&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Аппликация забирает себе всё, до чего дотянется: &amp;lt;tex&amp;gt;\lambda x\ .\ \lambda y\ .\ \lambda z\ .\ z\ y\ x \equiv \lambda x\ .\ (\lambda y\ .\ (\lambda z\ .\ ((z\ y)\ x)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Скобки играют привычную роль группировки действий&lt;br /&gt;
&lt;br /&gt;
===Свободные и связанные переменные===&lt;br /&gt;
''Связанными'' переменными называются все переменные, по которым выше в &lt;br /&gt;
дереве разбора были абстракции. Все остальные переменные называются свободными.&lt;br /&gt;
&lt;br /&gt;
Например, в &amp;lt;tex&amp;gt;\lambda x\ .\ \lambda y\ .\ x&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; связана, а &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;{{---}} свободна. А в &amp;lt;tex&amp;gt;\lambda y\ .\ x (\lambda x\ .\ x)&amp;lt;/tex&amp;gt;&lt;br /&gt;
в своём первом вхождении переменная &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; свободна, а во втором {{---}} связана.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функции &amp;lt;tex&amp;gt;\lambda y\ .\ y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\lambda x\ .\ y&amp;lt;/tex&amp;gt;. В первой из них при взгляде на &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;&lt;br /&gt;
понятно, что она имеет отношение к переменной, по которой производилась &lt;br /&gt;
абстракция. Если по одной и той же&lt;br /&gt;
переменной абстракция производилась более одного раза, то переменная связана&lt;br /&gt;
с самым поздним (самым нижним в дереве разбора) абстрагированием. Например, в&lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda x\ .\ \lambda x\ .\ \lambda y\ .\ \lambda x\ .\ x&amp;lt;/tex&amp;gt;, переменная &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; связана с самой правой абстракцией &lt;br /&gt;
по &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===α-конверсия===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функции &amp;lt;tex&amp;gt;(\lambda x\ .\ x) z&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(\lambda y\ .\ y) z&amp;lt;/tex&amp;gt;. Интуитивно понятно, что они &lt;br /&gt;
являются одинаковыми. &lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=''&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;-конверсия'' {{---}} переименование связанной переменной. Выражение&lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda x\ .\ f&amp;lt;/tex&amp;gt; можно заменить на &amp;lt;tex&amp;gt;\lambda y\ .\ f[x := y]&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; не входит свободно в &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt;,&lt;br /&gt;
где &amp;lt;tex&amp;gt;f[x:=y]&amp;lt;/tex&amp;gt; означает замену всех свободных вхождений &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Функции, получающиеся одна из другой с помощью &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;-конверсий, называются &lt;br /&gt;
''&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;-эквивалентными'' и обозначаются &amp;lt;tex&amp;gt;f \equiv_\alpha g&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функции &amp;lt;tex&amp;gt;\lambda x\ .\ \lambda y\ .\ x\ y\ z&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\lambda a\ .\ \lambda x\ .\ a\ x\ z&amp;lt;/tex&amp;gt; являются &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;-эквивалентными,&lt;br /&gt;
а &amp;lt;tex&amp;gt;\lambda x\ .\ \lambda y\ .\ y\ z&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\lambda y\ .\ \lambda x\ .\ y\ z&amp;lt;/tex&amp;gt; {{---}} нет.&lt;br /&gt;
&lt;br /&gt;
===β-редукция===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукция олицетворяет идею счёта значения функции. Выражение вида &lt;br /&gt;
&amp;lt;tex&amp;gt;(\lambda x\ .\ f)\ y&amp;lt;/tex&amp;gt; можно заменить на &amp;lt;tex&amp;gt;f[x := y]&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;f[x:=y]&amp;lt;/tex&amp;gt;, как и ранее, означает&lt;br /&gt;
замену всех свободных вхождений &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Через &amp;lt;tex&amp;gt;f \to_\beta g&amp;lt;/tex&amp;gt; обозначают сведение &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; с помощью одной &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукции.&lt;br /&gt;
А через &amp;lt;tex&amp;gt;f \to_\beta^* g&amp;lt;/tex&amp;gt; {{---}} за ноль или более.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Нотация Де Брюина==&lt;br /&gt;
Существует также альтернативное эквивалентное определение &amp;lt;tex&amp;gt;\lambda&amp;lt;/tex&amp;gt;-исчисления.&lt;br /&gt;
В оригинальном определении для обозначения переменных использовались имена,&lt;br /&gt;
и была проблема с тем, что не были запрещены одинаковые имена в разных&lt;br /&gt;
абстракциях. &lt;br /&gt;
&lt;br /&gt;
От этой проблемы можно избавиться следующим образом. Вместо имени переменной &lt;br /&gt;
будет храниться натуральное число {{---}} количество абстракций в дереве разбора,&lt;br /&gt;
на которое нужно подняться, чтобы найти ту лямбду, с которой данная переменная &lt;br /&gt;
связана. В данной нотации получаются несколько более простые определения &lt;br /&gt;
свободных переменных и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукции. &lt;br /&gt;
&lt;br /&gt;
Переменная называется свободной, если ей соответствует число, которое больше&lt;br /&gt;
количества абстракций на пути до неё в дереве разбора.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукции же нужно будет ко всем свободным переменным заменяющего &lt;br /&gt;
дерева при каждой замене прибавить число, равное разницы уровней раньше и сейчас.&lt;br /&gt;
Это будет соответствовать тому, что эта переменная продолжит &amp;lt;&amp;lt;держаться&amp;gt;&amp;gt; за&lt;br /&gt;
ту же лямбду, что и раньше.&lt;br /&gt;
&lt;br /&gt;
==Нумералы Чёрча и программирование на &amp;lt;tex&amp;gt;\lambda&amp;lt;/tex&amp;gt;-исчислении==&lt;br /&gt;
&lt;br /&gt;
===Определение===&lt;br /&gt;
Введём на основе лямбда-исчисления аналог натуральных чисел, основанный на идее, &lt;br /&gt;
что натуральное число {{---}} это или ноль, или увеличенное на единицу натуральное &lt;br /&gt;
число.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;\bar 0 = \lambda s\ .\ \lambda z\ .\ z&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt;\bar 1 = \lambda s\ .\ \lambda z\ .\ s\ z&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt;\bar 2 = \lambda s\ .\ \lambda z\ .\ s\ (s\ z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt;\bar 3 = \lambda s\ .\ \lambda z\ .\ s\ (s\ (s\ z))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждое число будет функцией двух аргументов: какой-то функции и начального значения.&lt;br /&gt;
Число &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз применять функцию к начальному значению и возвращать &lt;br /&gt;
результат. Если такому &amp;lt;&amp;lt;числу&amp;gt;&amp;gt; дать на вход функцию &amp;lt;tex&amp;gt;(+1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; в качестве &lt;br /&gt;
начального значения, то на выходе как раз будет ожидаемое от функции число:&lt;br /&gt;
&amp;lt;tex&amp;gt;\bar 3\ (+1)\ 0 \equiv 3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===+1===&lt;br /&gt;
Функция, прибавляющая 1 к числу, должна принимать первым аргументом число.&lt;br /&gt;
Но число {{---}} функция двух аргументов. Значит, эта функция должна принимать три&lt;br /&gt;
аргумента: &amp;lt;&amp;lt;число&amp;gt;&amp;gt; &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, которое хочется увеличить, функция, которую надо будет&lt;br /&gt;
&amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; раз применить, и начальное значение.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{succ} = \lambda n\ .\ \lambda s\ .\ \lambda z\ .\ s\ (n\ s\ z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;tex&amp;gt;n\ s\ z&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз применённая к &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; функция &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Но нужно применить &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; &lt;br /&gt;
раз. Отсюда &amp;lt;tex&amp;gt;s\ (n\ s\ z)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Сложение===&lt;br /&gt;
Сложение двух чисел похоже на прибавление единицы. Но только надо прибавить не единицу, а второе число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{plus} = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ n\ s\ (m\ s\ z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз применить &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; к применённому &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; раз &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(\operatorname{plus}\ \bar 3\ \bar 3)\ (+1)\ 0 \equiv 6&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Умножение===&lt;br /&gt;
Умножение похоже на сложение, но прибавлять надо не единицу, а второе число.&lt;br /&gt;
Или, в терминах нумералов Чёрча, в качестве применяемой несколько раз&lt;br /&gt;
функции должна быть не &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, а функция, применяющая &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{mult} = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ n\ (m\ s)\ z&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь &amp;lt;tex&amp;gt;m\ s&amp;lt;/tex&amp;gt; {{---}} функция, которая &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; раз применит &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; к тому, что дадут ей на &lt;br /&gt;
вход. С помощью &amp;lt;tex&amp;gt;\eta&amp;lt;/tex&amp;gt;-редукции можно немного сократить эту формулу&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{mult} = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ n\ (m\ s)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(\operatorname{mult} \bar 3\ \bar 3)\ (+1)\ 0 \equiv 9&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Возведение в степень===&lt;br /&gt;
It's a kind of magic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{power} = \lambda n\ .\ \lambda m\ .\ \lambda s\ .\ \lambda z\ .\ m\ n\ s\ z&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(\operatorname{power}\ \bar 3\ (\operatorname{succ}\ \bar 3))\ (+1)\ 0 \equiv 81&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Логические значения===&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{true} = \lambda a\ .\ \lambda b\ .\ a&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{false} = \lambda a\ .\ \lambda b\ .\ b&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Функции двух аргументов, возвращающие первый и второй, соответственное, аргументы.&lt;br /&gt;
Забавный факт: &amp;lt;tex&amp;gt;\operatorname{false} \equiv_\alpha \operatorname{zero}&amp;lt;/tex&amp;gt;. Эти функции сделаны такими для того, &lt;br /&gt;
чтобы красиво написать функцию &amp;lt;tex&amp;gt;\operatorname{if}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{if} = \lambda p\ .\ \lambda t\ .\ \lambda e\ .\ p\ t\ e&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если ей в качестве первого аргумента дадут &amp;lt;tex&amp;gt;\operatorname{true}&amp;lt;/tex&amp;gt;, то вернётся &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, иначе {{---}} &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Стандартные функции булевой логики:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{and} = \lambda n\ .\ \lambda m\ .\ \operatorname{if} n\ m\ \operatorname{false}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{or} = \lambda n\ .\ \lambda m\ .\ \operatorname{if} n\ \operatorname{true} m&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{not} = \lambda b\ .\ \operatorname{if} b\ \operatorname{false} \operatorname{true}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ещё одной важной функцией является функция проверки, является ли число нулём:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isZero} = \lambda n\ .\ n\ (\lambda c\ .\ \operatorname{false})\ \operatorname{true}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Функция выглядит несколько странно. &amp;lt;tex&amp;gt;\lambda c -&amp;gt; \operatorname{false}&amp;lt;/tex&amp;gt; {{---}} функция, которая независимо&lt;br /&gt;
от того, что ей дали на вход, возвращает &amp;lt;tex&amp;gt;\operatorname{false}&amp;lt;/tex&amp;gt;. Тогда, если в качестве &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
будет дан ноль, то функция, по определению нуля, не выполнится ни разу, и будет&lt;br /&gt;
возвращено значение по умолчанию &amp;lt;tex&amp;gt;\operatorname{true}&amp;lt;/tex&amp;gt;. Иначе же функция будет запущено, и &lt;br /&gt;
вернётся &amp;lt;tex&amp;gt;\operatorname{false}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Пара===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{pair} = \lambda a\ .\ \lambda b\ .\ \lambda t\ .\ t\ a\ b&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fst} = \lambda p\ .\ p\ \operatorname{true}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{snd} = \lambda p\ .\ p\ \operatorname{false}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;tex&amp;gt;\operatorname{pair}&amp;lt;/tex&amp;gt; принимает два значения и запаковывает их в пару так, чтобы к ним можно было обращаться по &amp;lt;tex&amp;gt;\operatorname{fst}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\operatorname{snd}&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\operatorname{fst}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\operatorname{snd}&amp;lt;/tex&amp;gt; вместо &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\operatorname{pair}&amp;lt;/tex&amp;gt; будет подставлено &amp;lt;tex&amp;gt;\operatorname{true}&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;\operatorname{false}&amp;lt;/tex&amp;gt;, возвращающие, соответственно, первый и второй аргументы, то есть &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, соответственно.&lt;br /&gt;
&lt;br /&gt;
===Вычитание===&lt;br /&gt;
В отличие от всех предыдущих функций, вычитание для натуральных чисел определено только в случае, если уменьшаемое больше вычитаемого. Положим в противном случае результат равным нулю. Пусть уже есть функция, которая вычитает из числа единицу. Тогда на её основе легко сделать, собственно, вычитание.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{minus} = \lambda n\ .\ \lambda m\ .\ m\ \operatorname{pred} n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это то же самое, что &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; раз вычесть единицу из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Осталось, собственно, функция для вычитания единицы. Однако, это не так просто, как может показаться на первый взгляд. Проблема в том, что, имея функцию, которую нужно применить для того, чтобы продвинуться вперёд, продвинуться назад будет проблематично. Если попробовать воспользоваться идеей о том, чтобы, начав от нуля, идти вперёд, и пройти на один шаг меньше, то будет не очень понятно, как же остановиться ровно за один шаг до конца. Для реализации вычитания единицы сделаем следующее. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз выполним следующее: имея пару &amp;lt;tex&amp;gt;\langle n-1, n-2\rangle&amp;lt;/tex&amp;gt; построим пару &amp;lt;tex&amp;gt;\langle n, n-1\rangle&amp;lt;/tex&amp;gt;. Тогда после &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов во втором элементе пары будет записано число &amp;lt;tex&amp;gt;n-1&amp;lt;/tex&amp;gt;, которое и хочется получить. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{pred} = \lambda n\ .\ \lambda s\ .\ \lambda z.\ \operatorname{snd}\ (&lt;br /&gt;
   n\ (&lt;br /&gt;
          \lambda p\ .\ \operatorname{pair}\ (s\ (\operatorname{fst} p))\ (\operatorname{fst} p)&lt;br /&gt;
     )\ (\operatorname{pair}\ z\ z))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если вы ничего не поняли, не огорчайтесь. Вычитание придумал Клини, когда ему вырывали зуб мудрости. А сейчас наркоз уже не тот.&lt;br /&gt;
&lt;br /&gt;
===Сравнение===&lt;br /&gt;
Так как вычитание определено таким способом, чтобы для случая, в котором уменьшаемое больше, чем вычитаемое, возвращать ноль, можно определить сравнение на больше-меньше через него. Равными же числа &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; считаются, если &amp;lt;tex&amp;gt;a - b = 0 \wedge b - a = 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{le} = \lambda n\ .\ \lambda m\ .\ \operatorname{isZero}\ (\operatorname{minus}\ n\ m)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{less} = \lambda n\ .\ \lambda m\ .\ \operatorname{le}\ n\ (\operatorname{pred} m)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{eq} = \lambda n\ .\ \lambda m\ .\ \operatorname{and}\ (\operatorname{isZero}\ (\operatorname{minus}\ n\ m))\ &lt;br /&gt;
(\operatorname{isZero}\ (\operatorname{minus}\ m\ n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Комбинатор неподвижной точки===&lt;br /&gt;
Попробуем выразить в лямбда-исчислении какую-нибудь функцию, использующую рекурсию. Напрмер, факториал.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fact} = \lambda x\ .\ \operatorname{if}\ (\operatorname{isZero}\ x)\ \bar 1\ (\operatorname{fact}\ (\operatorname{pred}\ x))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Мы столкнулись с проблемой. В определении функции &amp;lt;tex&amp;gt;\operatorname{fact}&amp;lt;/tex&amp;gt; используется функция &amp;lt;tex&amp;gt;\operatorname{fact}&amp;lt;/tex&amp;gt;. При формальной замене, получим бесконечную функцию. Можно попытаться решить эту проблему следующим образом&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fact} = (\lambda f\ .\ \lambda x\ .\ \operatorname{if}\ (\operatorname{isZero}\ x)\ \bar 1\ (f\ (\operatorname{pred}\ x)))\ \operatorname{fact}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=''Неподвижной точкой'' лямбда-функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; назовём такую функцию &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, что&lt;br /&gt;
&amp;lt;tex&amp;gt;f\ x \to_\beta^* x&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Лямбда исчисление обладаем замечательным свойством: у каждой функции есть неподвижная точка!&lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую функцию. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fix} = \lambda f\ .\ (\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tex&amp;gt;\operatorname{fix} \to_\beta^* \lambda f\ .\ f\ ((\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Или, что то же самое, &lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda f\ .\ (\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)) \to_\beta^*&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda f\ .\ f\ ((\lambda x\ .\ f\ (x\ x))\ (\lambda x\ .\ f\ (x\ x)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fact'} = \lambda f\ .\ \lambda x\ .\ \operatorname{if}\ (\operatorname{isZero}\ x)\ \bar 1\ (\operatorname{mult}\ x\ (f\ (\operatorname{pred}\ x)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как было показано выше, &amp;lt;tex&amp;gt;\operatorname{fix} f \to_\beta^* f\ (\operatorname{fix} f)&amp;lt;/tex&amp;gt;, то есть, &amp;lt;tex&amp;gt;\operatorname{fix}\ \operatorname{fact'} \to_\beta^* \operatorname{fact}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\operatorname{fact}&amp;lt;/tex&amp;gt; {{---}} искомая функция, считающая факториал.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{fact} = \operatorname{fix}\ \operatorname{fact'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это даст функцию, которая посчитает факториал числа. Но делать она это будет мееедленно-меееедленно. Для того, чтобы посчитать &amp;lt;tex?5!&amp;lt;/tex&amp;gt; потребовалось сделать 66066 &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукций.&lt;br /&gt;
&lt;br /&gt;
Тут правда ничего не понятно? :'(&lt;br /&gt;
&lt;br /&gt;
===Деление===&lt;br /&gt;
Воспользовавшись идеей о том, что можно делать рекурсивные функции, сделаем функцию, которая будет искать частное двух чисел.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{div'} = \lambda div\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname{if}\ (\operatorname{less}\ n\ m)\ \bar 0\ (\operatorname{succ}\ (div\ (\operatorname{minus}\ n\ m)\ m))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{div} = \operatorname{fix}\ \operatorname{div'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И остатка от деления&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{mod'} = \lambda mod\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname{if}\ (\operatorname{less}\ n\ m)\ n\ (mod\ (\operatorname{minus}\ n\ m)\ m)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{mod} = \operatorname{fix}\ \operatorname{mod'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Проверка на простоту===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isPrimeHelp}&amp;lt;/tex&amp;gt; {{---}} принимает число, которое требуется проверить на простоту и то, на что его надо опытаться поделить, перебирая это от 2 до &amp;lt;tex&amp;gt;p-1&amp;lt;/tex&amp;gt;. Если на что-нибудь разделилось, то число {{---}} составное, иначе {{---}} простое.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isPrimeHelp'} =&amp;lt;/tex&amp;gt;&amp;lt;tex&amp;gt;\lambda f\ .\ \lambda p\ .\ \lambda i\ .\ \operatorname{if}\ (\operatorname{le}\ p\ i)\ \operatorname{true}\ (\operatorname{if}\ (\operatorname{isZero}\ (\operatorname{mod}\ p\ i))\ \operatorname{false}\ (f\ p\ (\operatorname{succ}\ i)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isPrimeHelp} = \operatorname{fix}\ \operatorname{isPrimeHelp'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{isPrime} = \lambda p\ .\ \operatorname{isPrimeHelp}\ p\ \bar 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следующее простое число. &amp;lt;tex&amp;gt;\operatorname{nextPrime'}&amp;lt;/tex&amp;gt; {{---}} следующее, больше либо равное заданного, &amp;lt;tex&amp;gt;\operatorname{nextPrime}&amp;lt;/tex&amp;gt; {{---}} следующее, большее заданного.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{nextPrime''} = \lambda f\ .\ \lambda p\ .\ \operatorname{if}\ (\operatorname{isPrime}\ p)\ p\ (f\ (\operatorname{succ}\ p)) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{nextPrime'} = \operatorname{fix}\ \operatorname{nextPrime'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{nextPrime} = \lambda p\ .\ \operatorname{nextPrime'}\ (\operatorname{succ}\ p)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{ithPrimeStep}&amp;lt;/tex&amp;gt; пропрыгает &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; простых чисел вперёд. &amp;lt;tex&amp;gt;\operatorname{ithPrime}&amp;lt;/tex&amp;gt; принимает число &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и пропрыгивает столько простых чисел вперёд, начиная с двойки.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{ithPrimeStep'} = \lambda f\ .\ \lambda p\ .\ \lambda i\ .\ \operatorname{if}\ (\operatorname{isZero}\ i)\ p\ (f\  (\operatorname{nextPrime}\ p)\ (\operatorname{pred}\ i))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{ithPrimeStep} = \operatorname{fix}\ \operatorname{ithPrimeStep'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{ithPrime} = \lambda i\ .\ \operatorname{ithPrimeStep}\ \bar 2\ i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...и всего через 314007 &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt;-редукций вы узнаете, что третье простое число {{---}} семь!&lt;br /&gt;
&lt;br /&gt;
===Списки===&lt;br /&gt;
&lt;br /&gt;
Для работы со списками чисел нам понадобятся следующие функции:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{empty}&amp;lt;/tex&amp;gt; {{---}} возвращает пустой список&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{cons}&amp;lt;/tex&amp;gt; {{---}} принимает первый элемент и оставшийся список, склеивает их&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{head}&amp;lt;/tex&amp;gt; {{---}} вернуть голову списка&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{tail}&amp;lt;/tex&amp;gt; {{---}} вернуть хвост списка&lt;br /&gt;
&lt;br /&gt;
Список будем хранить в следующем виде: &amp;lt;tex&amp;gt;\langle len, p_1^{a_1}p_2^{a_2}\ldots p_{len}^{a_{len}} \rangle&amp;lt;/tex&amp;gt;. При этом, голова списка будет храниться как показатель степени при &amp;lt;tex&amp;gt;p_{len}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{empty} = \operatorname{pair}\ \operatorname{zero}\ \bar 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{cons} = \lambda h\ .\ \lambda t\ .\ \operatorname{pair}\ (\operatorname{succ}\ (\operatorname{fst}\ t))\ (\operatorname{mult}\ (\operatorname{snd}\ t)\ (\operatorname{power}\ (\operatorname{ithPrime}\ (\operatorname{fst}\ t))\ h))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{head} = \lambda list\ .\ \operatorname{getExponent}\ (\operatorname{snd}\ list)\ (\operatorname{ithPrime}\ (\operatorname{pred}\ (\operatorname{fst}\ list)))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{tail} = \lambda list\ .\ \operatorname{pair}\ (\operatorname{pred}\ (\operatorname{fst}\ list))&lt;br /&gt;
 (\operatorname{eliminateMultiplier}\ (\operatorname{snd}\ list)\ (\operatorname{ithPrime}\ (\operatorname{pred}\ (\operatorname{fst}\ list))))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{eliminateMultiplier'} =&amp;lt;/tex&amp;gt;&amp;lt;tex&amp;gt; \lambda f\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname{if}\ (\operatorname{isZero}\ (\operatorname{mod}\ n\ m))\ (f\ (\operatorname{div}\ n\ m)\ m)\ n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{eliminateMultiplier} = \operatorname{fix}\ \operatorname{eliminateMultiplier'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{getExponent'} =&amp;lt;/tex&amp;gt;&amp;lt;tex&amp;gt; \lambda f\ .\ \lambda n\ .\ \lambda m\ .\ \operatorname{if}\ (\operatorname{isZero}\ (\operatorname{mod}\ n\ m))\ (\operatorname{succ}\ (f\ (\operatorname{div}\ n\ m)\ m))\ \bar 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{getExponent} = \operatorname{fix}\ \operatorname{getExponent'}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Выводы==&lt;br /&gt;
&lt;br /&gt;
На основе этого всего уже можно реализовать эмулятор машины тьюринга: с помощью пар, списков чисел можно хранить состояния. С помощью рекурсии можно обрабатывать переходы. Входная строка будет даваться, например, закодированной аналогично списку: пара из длины и числа, характеризующего список степенями простых. Я бы продолжил это писать, но уже на операции &amp;lt;tex&amp;gt;\operatorname{head} [1, 2]&amp;lt;/tex&amp;gt; я не дождался окончания выполнения. Скорость лямбда-исчисления как вычислителя печальна.&lt;br /&gt;
&lt;br /&gt;
==Примеры (слабонервным не смотреть)==&lt;br /&gt;
&lt;br /&gt;
====fact====&lt;br /&gt;
(\f.(\x.f (x x)) (\x.f (x x))) (\f.\x.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) (x)) (\s.\z.s z) ((\n.\m.\s.n (m s)) (x) (f ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (x)))))&lt;br /&gt;
&lt;br /&gt;
====head====&lt;br /&gt;
\list.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\n.\m.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) ((\f.(\x.f (x x)) (\x.f (x x))) (\mod.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) n (mod ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m)) n m)) ((\n.\s.\z.s (n s z)) (f ((\f.(\x.f (x x)) (\x.f (x x))) (\div.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) (\s.\z.z) ((\n.\s.\z.s (n s z)) (div ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m))) n m) m)) (\s.\z.z)) ((\p.p (\a.\b.b)) (list)) ((\i.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.\i.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) (i)) p (f ((\p.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.(\p.\t.\e.p t e) ((\p.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.\i.(\p.\t.\e.p t e) ((\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (p) i) (\a.\b.a) ((\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) ((\f.(\x.f (x x)) (\x.f (x x))) (\mod.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) n (mod ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m)) p i)) (\a.\b.b) (f p ((\n.\s.\z.s (n s z)) (i))))) p (\s.\z.s (s z))) (p)) p (f ((\n.\s.\z.s (n s z)) (p)))) ((\n.\s.\z.s (n s z)) (p))) (p)) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (i)))) (\s.\z.s (s z)) i) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) ((\p.p (\a.\b.a)) (list))))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====tail====&lt;br /&gt;
\list.(\a.\b.\t.t a b) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) ((\p.p (\a.\b.a)) (list))) ((\f.(\x.f (x x)) (\x.f (x x))) (\f.\n.\m.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) ((\f.(\x.f (x x)) (\x.f (x x))) (\mod.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) n (mod ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m)) n m)) (f ((\f.(\x.f (x x)) (\x.f (x x))) (\div.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) (\s.\z.z) ((\n.\s.\z.s (n s z)) (div ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m))) n m) m) n) ((\p.p (\a.\b.b)) (list)) ((\i.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.\i.(\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) (i)) p (f ((\p.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.(\p.\t.\e.p t e) ((\p.(\f.(\x.f (x x)) (\x.f (x x))) (\f.\p.\i.(\p.\t.\e.p t e) ((\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (p) i) (\a.\b.a) ((\p.\t.\e.p t e) ((\n.n (\c.\a.\b.b) (\a.\b.a)) ((\f.(\x.f (x x)) (\x.f (x x))) (\mod.\n.\m.(\p.\t.\e.p t e) ((\n.\m.(\n.\m.(\n.n (\c.\a.\b.b) (\a.\b.a)) ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m)) (n) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (m))) (n) m) n (mod ((\n.\m.m (\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) n) (n) m) m)) p i)) (\a.\b.b) (f p ((\n.\s.\z.s (n s z)) (i))))) p (\s.\z.s (s z))) (p)) p (f ((\n.\s.\z.s (n s z)) (p)))) ((\n.\s.\z.s (n s z)) (p))) (p)) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) (i)))) (\s.\z.s (s z)) i) ((\n.\s.\z.(\p.p (\a.\b.b)) (n (\p.(\a.\b.\t.t a b) (s ((\p.p (\a.\b.a)) (p))) ((\p.p (\a.\b.a)) (p))) ((\a.\b.\t.t a b) (z) z))) ((\p.p (\a.\b.a)) (list)))))&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Lambda-calculus Английская Википедия]&lt;br /&gt;
&lt;br /&gt;
[http://ru.wikipedia.org/wiki/%D0%9B%D1%8F%D0%BC%D0%B1%D0%B4%D0%B0-%D0%B8%D1%81%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5 Русская Википедия]&lt;br /&gt;
&lt;br /&gt;
[http://rain.ifmo.ru/~komarov/Turing.lhs Тут можно это всё потыкать]&lt;br /&gt;
&lt;br /&gt;
[http://worrydream.com/AlligatorEggs А это игра про крокодильчиков]&lt;/div&gt;</summary>
		<author><name>83.234.102.107</name></author>	</entry>

	</feed>