Кодирование Чёрча

Кодирование Чёрча ― способ представления при помощи лямбда-выражений данных, не являющихся функциями и переменными, например, натуральных чисел и других констант. Метод назван в честь Алонзо Чёрча, разработавшего лямбда-исчисление.

Поскольку в чистом (бестиповом) лямбда-исчислении, в отличие от многих формальных систем (где выделены в качестве термов, например, целые числа, булевы значения, пары), единственным примитивным типом являются функции, все остальные виды данных необходимо конструировать с использованием лямбда-выражений. Кодирование подразумевает соглашение о том, как определять те или иные примитивы; например, числа Чёрча — способ кодирования натуральных чисел, булеаны Чёрча — соглашение о кодировании логических значений, пары Чёрча — кодирование упорядоченных пар элементов, есть несколько способов закодировать списки.

Кодирование Чёрча, как правило, не используется для реализации примитивных типов данных в практических языках программирования из-за неэффективности, но при этом демонстрирует, что любые вычисления могут быть сведены исключительно к функциям и переменным в бестиповом лямбда-исчислении, а другие примитивные типы данных не обязательны.

В этой статье может быть использована сокращённая λ-нотация для абстракций, .

Пары Чёрча

Пары Чёрча — соглашение о кодировании упорядоченных пар, то есть наборов (кортежей) из двух элементов. Пара величин и представляется функцией, которая ожидает как свой единственный аргумент некую функцию , и применяет её к обоим элементам пары, и :

Здесь выступает в роли функции-продолжения, или функции-обработчика двух величин из пары.

Функции и , возвращающие соответственно первый и второй элемент пары, а также функция (два варианта, для примера), меняющая местами два элемента пары, определяются как:

Булеаны Чёрча

Булеаны Чёрча — представления булевых значений, то есть «истины» () и «лжи» () как выбора первого и второго аргумента соответственно:

Некоторые языки программирования, такие как Smalltalk и Pico[англ.], используют их в качестве модели реализации для булевой арифметики.

Такое определение позволяет использовать предикаты (функции, возвращающие логические значения) как условия в условных выражениях. Над и могут быть реализованы стандартные логические операторы (конъюнкция, дизъюнкция, отрицание, исключающее «или»:

Реализация тернарной условной операции:

.

Предикаты — функции, возвращающие логическое значение — реализуются естественным образом, как функции возвращающие Булеаны как результат.

Числа Чёрча

Число Чёрча, соответствующее натуральному числу , определяется как функция от двух параметров и , последовательно раз применяющая функцию начиная с  — другими словами, число Чёрча отображает функцию в её -кратную композицию:

значит «не применять функцию к вообще», значит «применять функцию 1 раз» и так далее:

Число Определение нумерала Лямбда-выражение

Вычисления над числами Чёрча

Арифметические операции над числами можно выразить в лямбда-исчислении как функции над числами Чёрча.

Операция сложения, отображая тождество , то есть , определяется как:

Добавление единицы выводится из сложения посредством -редукции, полагая :

Для умножения замечаем, что -кратное повторение функции это -кратное повторение -кратно повторенной функции , :

Возведение в степень это умножение на , повторенное раз, :

Число-предшественник выполняет данную ему функцию на один раз меньше, подменяя её функцией тождества, один только раз, при первом применении:

Для примера, .

Вычитание числа достигается повторным вычитанием единицы, раз:

Похожим образом могли бы быть определены:

Аналогично функции определяются и другие функции, как например:

вычисляющие целочисленное деление на 2, и факториал (выполняющий, к примеру, ).

Предикаты для чисел Чёрча

Предикат , возвращающий , если его аргумент является числом Чёрча , и в ином случае, вводится таким образом:

Предикат над числами Чёрча, который проверяет, меньше или равен его первый аргумент второму:

Из тождества получается предикат проверки на равенство :

Предикат «меньше» это

Числа по Скотту

Для сравнения, кодирование чисел по Скотту определено как[1]

Кодировка Скотта для каждого алгебраического типа данных напрямую соответствует его определению. Натуральные числа по Пеано — это суммарный тип данных с двумя вариантами, 0 и не-0:

.

Соответственно, числo по Скотту это функция, ожидающaя две функции-обработчика, по числу вариантов.

Число по Скотту являет собой уже совершённое сопоставление с образцом, и вызывает соответствующую функцию-обработчик в соответствии с тем, является ли оно нулём или нет. В случае нуля дополнительных данных нет, так что это не функция а просто некая величина , . В случае же не-нулевого числа, дополнительным данным явлается его предшествующее число, например .

В то время как в кодировке Чёрча , в кодировке Скотта , , и . Соответственно и функции перевода в другой тип тоже разнятся,

Как видим, определение перевода чисел Скотта рекурсивно, и требует использования оператора неподвижной точки, или соответственного переопределения с использованием само-применения, «вручную»:

Сложение определяется через повторение операции , с использованием явной рекурсии:

Так же с использованием явной рекурсии приходится определять и все остальные операции над числами Скотта:

Зато операция вычитания (и следовательно деления) в целом более проста чем в кодировании Чёрча, благодаря простоте операции для чисел Скотта. Аналогично и предикаты равенства и «меньше чем» гораздо проще (в смысле сложности вычислений):

Списки

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

Представление в виде двух пар

При представлении в виде пары первый элемент содержит первый элемент списка, а второй — «хвост» списка, содержащий все остальные элементы. Поскольку таким способом не может быть выражен пустой список, то используется дополнительная обёртка — первый элемент указывает, является ли список пустым, а второй элемент содержит пару из первого элемента списка и хвоста списка.

Базовые операции со списками в этой схеме кодирования можно выразить следующим образом[2]:

 — пустой список;
 — возвращает первый элемент пары, который и означает, является ли список пустым;
 — конструирует новый непустой список из первого элемента (головы списка) и хвоста ;
 — первый элемент пары во втором элементе — голова списка;
 — второй элемент пары во втором элементе — хвост списка.

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

хотя оно рекурсивно, что недопустимо в лямбда исчислении и требует дальнейшего применения комбинатора неподвижной точки. Возможно и более непосредственное определение, как

В пустом списке доступ ко второму элементу никогда не применяется, поскольку к нему не применимы понятия головы и хвоста списка.

Представление в виде одной пары

В качестве альтернативы списки можно определить следующим образом ( здесь соответствует пустому списку, непустые задаются парой головы и хвоста)[3]:

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

Списки по Чёрчу

В качестве альтернативы кодированию с использованием пар, кодировка Чёрча отождествляет список с функцией которая осуществляет его свёртку справа. Например, список из трёх элементов , и представляется функцией , которая ожидает комбинирующую функцию и значение , и возвращает значение свёртки :

Здесь используются мнемонические имена переменных для (голова списка), для (хвост списка), и для рекурсивного результата свертки хвоста списка.

Таким образом, и . Функция определена таким же путём что и функция для чисел Чёрча — передачей комбинирующей функции вперёд по цепочке после её одноразовой замены в самом начале на функцию пропускающую самый первый элемент (и соотвестственно, одноразовой замены данной функции на функцию тождества в случае чисел Чёрча, для выполнения операции на один раз меньше).

Легко определяются добавочные функции, как например:

Итак списки Чёрча — это функции свёртки, и операция это тождественная функция ( свёртывает список составленный из эндофункций). Числа же по Чёрчу (как видно и из определения ) — это свертка справа унарного представления натуральных чисел, то есть списка из неразличимых, неинтересных элементов, длиной равной величине числа. Поэтому соответствует функции , а соответствует , с исключением аргумента в обоих случаях.

Списки по Скотту

Ещё одним альтернативным представлением является представление списков через кодирование Скотта[англ.], которое использует идеи продолжения и сопоставления с образцом, и может привести к упрощению программного кода[4], а может и к усложнению.

Списки — это суммарный тип данных с двумя вариантами. В соответствии с общими принципами кодировки Скотта, каждый список представлен функцией которая ожидает два аргумента, две функции-получателя соответствующие этим двум вариантам: одна для варианта пустого списка и другая для непустого. Функция для непустого варианта получит головной элемент и хвост, а для пустого никаких данных нет, так что это не функция а просто величина:

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

Как числа по Чёрчу соответствуют спискам по Чёрчу с игнорированием их элементов, так же и для кодировок Скотта.

В отличие от кодирования Чёрча, которое, будучи сверткой, уже содержит в себе рекурсию для рекурсивных типов, кодирование Скотта игнорирует рекурсивность и представляет любые типы с одинаковым подходом, просто отображая их внешнюю структуру. Поэтому в отличие от списков Чёрча где мы просто передаём списку новую функцию свёртки и всю работу выполняет он сам, рекурсивные функции для списков Скотта проходится кодировать с явной рекурсией:

Примечания

  1. History of Lambda-calculus and Combinatory Logic, 2006, by Felice Cardone and J. Roger Hindley, p. 18, note 38
  2. Pierce, Benjamin C.[англ.]. Types and Programming Languages[англ.]. — MIT Press, 2002. — С. 500. — ISBN 978-0-262-16209-8.
  3. Tromp, John. 14. Binary Lambda Calculus and Combinatory Logic // Randomness And Complexity, From Leibniz To Chaitin (англ.) / Calude, Cristian S.. — World Scientific, 2007. — P. 237—262. — ISBN 978-981-4474-39-9.
    As PDF: Tromp, John. Binary Lambda Calculus and Combinatory Logic (PDF) (14 мая 2014). Дата обращения: 24 ноября 2017. Архивировано 1 июня 2018 года.
  4. Jansen, Jan Martin. Programming in the λ-Calculus: From Church to Scott and Back (англ.) // LNCS[англ.] : journal. — 2013. — Vol. 8106. — P. 168—180. — doi:10.1007/978-3-642-40355-2_12.

Литература

Prefix: a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9

Portal di Ensiklopedia Dunia

Kembali kehalaman sebelumnya