Комбинаторная логика — это нотация, устраняющая необходимость в квантифицированных переменных в математической логике . Она была введена Мозесом Шёнфинкелем [1] и Хаскеллом Карри [ 2] и в последнее время использовалась в информатике как теоретическая модель вычислений , а также как основа для проектирования функциональных языков программирования . Она основана на комбинаторах , которые были введены Шёнфинкелем в 1920 году с идеей предоставления аналогичного способа построения функций и удаления любого упоминания переменных, особенно в логике предикатов . Комбинатор — это функция высшего порядка , которая использует только применение функций и ранее определенные комбинаторы для определения результата из своих аргументов.
Комбинаторная логика изначально задумывалась как «прелогика», которая проясняет роль квантифицированных переменных в логике, по сути, устраняя их. Другим способом устранения квантифицированных переменных является логика предикатных функторов Куайна . В то время как выразительная сила комбинаторной логики обычно превышает выразительную силу логики первого порядка , выразительная сила логики предикатных функторов идентична логике первого порядка (Quine 1960, 1966, 1976).
Первоначальный изобретатель комбинаторной логики, Моисей Шёнфинкель , не опубликовал ничего по комбинаторной логике после своей оригинальной статьи 1924 года. Хаскелл Карри заново открыл комбинаторы, работая преподавателем в Принстонском университете в конце 1927 года . [3] В конце 1930-х годов Алонзо Чёрч и его студенты в Принстоне изобрели конкурирующий формализм для функциональной абстракции, лямбда-исчисление , которое оказалось более популярным, чем комбинаторная логика. Результатом этих исторических обстоятельств стало то, что до тех пор, пока теоретическая информатика не начала интересоваться комбинаторной логикой в 1960-х и 1970-х годах, почти все работы по этой теме были выполнены Хаскеллом Карри и его студентами или Робертом Фейсом в Бельгии . Карри и Фейс (1958), а также Карри и др. (1972) рассматривают раннюю историю комбинаторной логики. Более современную трактовку комбинаторной логики и лямбда-исчисления можно найти в книге Барендрегта [4] , в которой рассматриваются модели, разработанные Даной Скоттом для комбинаторной логики в 1960-х и 1970-х годах.
В информатике комбинаторная логика используется как упрощенная модель вычислений , применяемая в теории вычислимости и теории доказательств . Несмотря на свою простоту, комбинаторная логика охватывает многие существенные особенности вычислений.
Комбинаторную логику можно рассматривать как вариант лямбда -исчисления , в котором лямбда-выражения (представляющие функциональную абстракцию) заменяются ограниченным набором комбинаторов , примитивных функций без свободных переменных . Лямбда-выражения легко преобразовать в комбинаторные выражения, а редукция комбинатора намного проще, чем редукция лямбда. Поэтому комбинаторная логика использовалась для моделирования некоторых нестрогих функциональных языков программирования и оборудования . Чистейшей формой этого представления является язык программирования Unlambda , единственными примитивами которого являются комбинаторы S и K, дополненные символьным вводом/выводом. Хотя Unlambda и не является практическим языком программирования, он представляет некоторый теоретический интерес.
Комбинаторной логике можно дать множество интерпретаций. Многие ранние работы Карри показали, как перевести наборы аксиом для обычной логики в уравнения комбинаторной логики. [5] Дэна Скотт в 1960-х и 1970-х годах показал, как объединить теорию моделей и комбинаторную логику.
Лямбда-исчисление имеет дело с объектами, называемыми лямбда-термами , которые могут быть представлены следующими тремя формами строк:
где — имя переменной, взятое из предопределенного бесконечного набора имен переменных, а и — лямбда-термы.
Термины вида называются абстракциями . Переменная v называется формальным параметром абстракции, а — телом абстракции. Термин представляет функцию, которая, примененная к аргументу, связывает формальный параметр v с аргументом, а затем вычисляет результирующее значение — то есть возвращает , при этом каждое вхождение v заменяется аргументом.
Термины формы называются приложениями . Приложения моделируют вызов или выполнение функции: функция, представленная , должна быть вызвана с в качестве аргумента, и результат вычисляется. Если (иногда называемый приложением ) является абстракцией, термин может быть сокращен : , аргумент, может быть подставлен в тело вместо формального параметра , и результатом будет новый лямбда-терм, который эквивалентен старому. Если лямбда-терм не содержит подтермов формы , то он не может быть сокращен, и говорят, что он находится в нормальной форме .
Выражение представляет собой результат взятия термина E и замены всех свободных вхождений v в нем на a . Таким образом, мы пишем
По соглашению мы принимаем как сокращение для (т.е. приложение левоассоциативно ).
Мотивация этого определения редукции заключается в том, что оно охватывает основное поведение всех математических функций. Например, рассмотрим функцию, которая вычисляет квадрат числа. Мы могли бы написать
(Используя " " для обозначения умножения.) x здесь — формальный параметр функции. Чтобы вычислить квадрат для конкретного аргумента, скажем, 3, мы вставляем его в определение вместо формального параметра:
Чтобы оценить полученное выражение , нам пришлось бы прибегнуть к нашим знаниям об умножении и числе 3. Поскольку любое вычисление является просто композицией оценки подходящих функций на подходящих примитивных аргументах, этого простого принципа подстановки достаточно, чтобы охватить основной механизм вычисления. Более того, в лямбда-исчислении такие понятия, как '3' и ' ', могут быть представлены без какой-либо необходимости во внешне определенных примитивных операторах или константах. В лямбда-исчислении можно определить термины, которые при соответствующей интерпретации ведут себя как число 3 и как оператор умножения, см. Church encoding .
Известно, что лямбда-исчисление по вычислительной мощности эквивалентно многим другим возможным моделям вычислений (включая машины Тьюринга ); то есть любое вычисление, которое может быть выполнено в любой из этих других моделей, может быть выражено в лямбда-исчислении, и наоборот. Согласно тезису Чёрча–Тьюринга , обе модели могут выразить любое возможное вычисление.
Возможно, удивительно, что лямбда-исчисление может представлять любые мыслимые вычисления, используя только простые понятия абстракции функций и применения, основанные на простой текстовой подстановке терминов вместо переменных. Но еще более примечательно то, что абстракция даже не требуется. Комбинаторная логика — это модель вычислений, эквивалентная лямбда-исчислению, но без абстракции. Преимущество этого в том, что оценка выражений в лямбда-исчислении довольно сложна, поскольку семантика подстановки должна быть указана с большой осторожностью, чтобы избежать проблем с захватом переменных. Напротив, оценка выражений в комбинаторной логике намного проще, поскольку нет понятия подстановки.
Поскольку абстракция является единственным способом создания функций в лямбда-исчислении, что-то должно заменить ее в комбинаторном исчислении. Вместо абстракции комбинаторное исчисление предоставляет ограниченный набор примитивных функций, из которых могут быть построены другие функции.
Комбинаторный термин имеет одну из следующих форм:
Примитивные функции — это комбинаторы , или функции, которые, если рассматривать их как лямбда-термы, не содержат свободных переменных .
Чтобы сократить обозначения, общее соглашение заключается в том, что , или даже , обозначает термин . Это то же общее соглашение (левая ассоциативность), что и для множественного применения в лямбда-исчислении.
В комбинаторной логике каждый примитивный комбинатор имеет правило редукции вида
где E — термин, упоминающий только переменные из множества { x 1 ... x n } . Именно таким образом примитивные комбинаторы ведут себя как функции.
Простейшим примером комбинатора является I , тождественный комбинатор, определяемый как
для всех членов x . Другой простой комбинатор — K , который производит постоянные функции: ( K x ) — это функция, которая для любого аргумента возвращает x , поэтому мы говорим
для всех терминов x и y . Или, следуя соглашению о множественном применении,
Третий комбинатор — S , который представляет собой обобщенную версию приложения:
S применяет x к y после первой подстановки z в каждый из них. Или, другими словами, x применяется к y внутри среды z .
Учитывая S и K , I сам по себе не нужен, поскольку его можно построить из двух других:
для любого термина x . Обратите внимание, что хотя (( SKK ) x ) = ( I x ) для любого x , сам ( SKK ) не равен I . Мы говорим, что термины являются экстенсионально равными . Экстенсиональное равенство охватывает математическое понятие равенства функций: что две функции равны, если они всегда производят одинаковые результаты для одних и тех же аргументов. Напротив, сами термины вместе с сокращением примитивных комбинаторов охватывают понятие интенсионального равенства функций: что две функции равны , только если они имеют идентичные реализации вплоть до расширения примитивных комбинаторов. Существует много способов реализовать функцию тождества; ( SKK ) и I являются одними из этих способов. ( SKS ) является еще одним. Мы будем использовать слово эквивалентный для обозначения экстенсионального равенства, резервируя равный для идентичных комбинаторных терминов.
Более интересным комбинатором является комбинатор с фиксированной точкой или Y -комбинатор, который можно использовать для реализации рекурсии .
S и K можно скомпоновать так, чтобы получить комбинаторы, которые экстенсионально равны любому лямбда-терму, и, следовательно, согласно тезису Чёрча, любой вычислимой функции. Доказательство состоит в том, чтобы представить преобразование T [ ] , которое преобразует произвольный лямбда-терм в эквивалентный комбинатор.
T [ ] можно определить следующим образом:
Обратите внимание, что T [ ] в данном случае не является хорошо типизированной математической функцией, а скорее средством переписывания термов: хотя в конечном итоге получается комбинатор, преобразование может генерировать промежуточные выражения, которые не являются ни лямбда-термами, ни комбинаторами, согласно правилу (5).
Этот процесс также известен как устранение абстракции . Это определение является исчерпывающим: любое лямбда-выражение будет подчиняться только одному из этих правил (см. Краткое изложение лямбда-исчисления выше).
Он связан с процессом абстракции скобок , который берет выражение E, построенное из переменных и применения, и создает комбинаторное выражение [x]E, в котором переменная x не является свободной, так что выполняется [ x ] E x = E. Очень простой алгоритм абстракции скобок определяется индукцией по структуре выражений следующим образом: [6]
Абстракция скобок вызывает перевод лямбда-терминов в комбинаторные выражения путем интерпретации лямбда-абстракций с использованием алгоритма абстракции скобок.
Например, мы преобразуем лямбда-терм λx . λy .( y x ) в комбинаторный терм:
Если мы применим этот комбинаторный термин к любым двум терминам x и y (подавая их в порядке очереди в комбинатор «справа»), то он сведется к следующему:
Комбинаторное представление ( S ( K ( SI )) ( S ( KK ) I )) намного длиннее представления в виде лямбда-терма λx . λy .(yx). Это типично. В общем случае конструкция T [ ] может расширить лямбда-терм длины n до комбинаторного терма длины Θ ( n 3 ). [7]
Преобразование T [ ] мотивировано желанием устранить абстракцию. Два особых случая, правила 3 и 4, тривиальны: λx . x явно эквивалентно I , а λx . E явно эквивалентно ( K T [ E ]), если x не появляется свободным в E .
Первые два правила также просты: переменные преобразуются в самих себя, а аппликации, которые разрешены в комбинаторных терминах, преобразуются в комбинаторы просто путем преобразования аппликанда и аргумента в комбинаторы.
Интерес представляют правила 5 и 6. Правило 5 просто говорит, что для преобразования сложной абстракции в комбинатор мы должны сначала преобразовать ее тело в комбинатор, а затем устранить абстракцию. Правило 6 фактически устраняет абстракцию.
λx .( E ₁ E ₂) — это функция, которая берет аргумент, скажем, a , и подставляет его в лямбда-терм ( E ₁ E ₂) вместо x , получая ( E ₁ E ₂)[ x : = a ]. Но подстановка a в ( E ₁ E ₂) вместо x — это то же самое, что подстановка его и в E ₁, и в E ₂, поэтому
По экстенсиональному равенству,
Следовательно, чтобы найти комбинатор, эквивалентный λx .( E ₁ E ₂), достаточно найти комбинатор, эквивалентный ( S λx . E ₁ λx . E ₂), и
очевидно, соответствует требованиям. E ₁ и E ₂ содержат строго меньше применений, чем ( E ₁ E ₂), поэтому рекурсия должна завершиться лямбда-термом без каких-либо применений вообще — либо переменной, либо термом формы λx . E .
Комбинаторы, генерируемые преобразованием T [ ], можно сделать меньше, если принять во внимание правило η-редукции :
λx .( E x) — это функция, которая принимает аргумент x и применяет к нему функцию E ; это экстенсионально равно самой функции E. Поэтому достаточно преобразовать E в комбинаторную форму.
Принимая во внимание это упрощение, приведенный выше пример становится следующим:
Этот комбинатор эквивалентен предыдущему, более длинному:
Аналогично, исходная версия преобразования T [ ] преобразовала функцию тождества λf . λx .( f x ) в ( S ( S ( KS ) ( S ( KK ) I )) ( KI )). С помощью правила η-редукции λf . λx .( f x ) преобразуется в I .
Существуют одноточечные базисы, из которых каждый комбинатор может быть составлен экстенсионально равным любому лямбда-терму. Простейшим примером такого базиса является { X }, где:
Нетрудно убедиться, что:
Поскольку { K , S } является базисом, то отсюда следует, что { X } также является базисом. Язык программирования Iota использует X в качестве своего единственного комбинатора.
Еще один простой пример одноточечной основы:
На самом деле таких баз существует бесконечно много. [8]
В дополнение к S и K , Шёнфинкель (1924) включил два комбинатора, которые теперь называются B и C , со следующими сокращениями:
Он также объясняет, как их, в свою очередь, можно выразить, используя только S и K :
Эти комбинаторы чрезвычайно полезны при переводе логики предикатов или лямбда-исчисления в выражения комбинаторов. Их также использовал Карри , а гораздо позже Дэвид Тернер , чье имя ассоциируется с их вычислительным использованием. Используя их, мы можем расширить правила преобразования следующим образом:
Используя комбинаторы B и C , преобразование λx . λy .( y x ) выглядит следующим образом:
И действительно, ( C I x y ) сводится к ( y x ):
Мотивация здесь в том, что B и C являются ограниченными версиями S. В то время как S принимает значение и подставляет его как в аппликанд, так и в его аргумент перед выполнением аппликации, C выполняет подстановку только в аппликанд, а B — только в аргумент.
Современные названия комбинаторов взяты из докторской диссертации Хаскелла Карри 1930 года (см. Система B, C, K, W ). В оригинальной статье Шёнфинкеля то, что мы сейчас называем S , K , I , B и C, называлось S , C , I , Z и T соответственно.
Уменьшение размера комбинатора, являющееся результатом новых правил преобразования, может быть достигнуто и без введения B и C , как показано в разделе 3.2 работы Тромпа (2008).
Необходимо провести различие между CL K , описанным в этой статье, и исчислением CL I. Это различие соответствует различию между исчислением λ K и исчислением λ I. В отличие от исчисления λ K , исчисление λ I ограничивает абстракции следующими областями:
Как следствие, комбинатор K отсутствует в исчислении λ I и в исчислении CL I. Константы CL I : I , B , C и S , которые образуют базис, из которого могут быть составлены все члены CL I (по модулю равенства). Каждый член λ I может быть преобразован в равный комбинатор CL I в соответствии с правилами, аналогичными представленным выше для преобразования членов λ K в комбинаторы CL K. См. главу 9 в Barendregt (1984).
Преобразование L [ ] из комбинаторных термов в лямбда-термы тривиально:
Однако следует отметить, что это преобразование не является обратным преобразованием ни одной из версий T [ ], которые мы видели.
Нормальная форма — это любой комбинаторный термин, в котором примитивные комбинаторы, которые встречаются, если таковые имеются, не применяются к достаточному количеству аргументов, чтобы их можно было упростить. Неразрешимо, имеет ли общий комбинаторный термин нормальную форму; эквивалентны ли два комбинаторных термина и т. д. Это можно показать аналогично соответствующим проблемам для лямбда-терминов.
Неразрешимые проблемы выше (эквивалентность, существование нормальной формы и т. д.) принимают в качестве входных данных синтаксические представления терминов в подходящей кодировке (например, кодировке Чёрча). Можно также рассмотреть игрушечную тривиальную модель вычислений, в которой мы «вычисляем» свойства терминов с помощью комбинаторов, применяемых непосредственно к самим терминам в качестве аргументов, а не к их синтаксическим представлениям. Точнее, пусть предикат будет комбинатором, который при применении возвращает либо T, либо F (где T и F представляют собой обычные кодировки Чёрча истинности и ложности, λx . λy . x и λx . λy . y , преобразованные в комбинаторную логику; комбинаторные версии имеют T = K и F = ( K I ) ). Предикат N нетривиален , если есть два аргумента A и B такие, что N A = T и N B = F . Комбинатор N является полным , если N M имеет нормальную форму для каждого аргумента M . Аналог теоремы Райса для этой игрушечной модели тогда говорит, что каждый полный предикат тривиален. Доказательство этой теоремы довольно простое. [9]
Доводя до абсурда. Предположим, что есть полный нетривиальный предикат, скажем N. Поскольку N должен быть нетривиальным, существуют комбинаторы A и B, такие что
Теорема о неподвижной точке дает: АБСУРД = (ОТРИЦАНИЕ АБСУРД), для
Поскольку N должно быть полным, то:
Следовательно ( N ABSURDUM) не является ни T , ни F , что противоречит предположению, что N будет полным нетривиальным предикатом. QED
Из этой теоремы о неопределимости немедленно следует, что не существует полного предиката, который может различать термины, имеющие нормальную форму, и термины, не имеющие нормальной формы. Также следует, что не существует полного предиката, например, EQUAL, такого, что:
Если бы EQUAL существовал, то для всех A , λx. (EQUAL x A ) должен был бы быть полным нетривиальным предикатом.
Однако следует отметить, что из этой теоремы о неопределимости немедленно следует, что многие свойства терминов, которые, очевидно, разрешимы, также не определяются полными предикатами: например, не существует предиката, который мог бы определить, является ли первая примитивная функциональная буква, встречающаяся в термине, буквой K. Это показывает, что определяемость предикатами не является разумной моделью разрешимости.
Дэвид Тернер использовал свои комбинаторы для реализации языка программирования SASL .
Кеннет Э. Айверсон использовал примитивы, основанные на комбинаторах Карри, в своем языке программирования J , преемнике APL . Это позволило сделать то, что Айверсон назвал неявным программированием , то есть программированием в функциональных выражениях, не содержащих переменных, вместе с мощными инструментами для работы с такими программами. Оказывается, неявное программирование возможно в любом языке типа APL с определяемыми пользователем операторами. [10]
Изоморфизм Карри–Ховарда подразумевает связь между логикой и программированием: каждое доказательство теоремы интуиционистской логики соответствует редукции типизированного лямбда-терма, и наоборот. Более того, теоремы могут быть идентифицированы с помощью сигнатур типа функции. В частности, типизированная комбинаторная логика соответствует системе Гильберта в теории доказательств .
Комбинаторы K и S соответствуют аксиомам
и применение функции соответствует правилу отсоединения (modus ponens)
Исчисление, состоящее из AK , AS и MP, является полным для импликационного фрагмента интуиционистской логики, который можно увидеть следующим образом. Рассмотрим множество W всех дедуктивно замкнутых множеств формул, упорядоченных по включению . Тогда — интуиционистская шкала Крипке , и мы определяем модель в этой шкале как
Это определение подчиняется условиям выполнения →: с одной стороны, если , и таково, что и , то по modus ponens. С другой стороны, если , то по теореме о дедукции , таким образом, дедуктивное замыкание является элементом таким, что , , и .
Пусть A — любая формула, которая не доказуема в исчислении. Тогда A не принадлежит дедуктивному замыканию X пустого множества, таким образом , и A не является интуиционистски валидной.
Перепечатано как Глава 23 Куайна (1996)
Статья, основавшая комбинаторную логику. Английский перевод: Шёнфинкель (1967)
Мягкое введение в комбинаторную логику, представленное в виде серии развлекательных головоломок с использованием метафор наблюдения за птицами.
Главы 17–20 представляют собой более формальное введение в комбинаторную логику с особым акцентом на результатах с фиксированной точкой.
Празднование развития комбинаторов, спустя сто лет после того, как они были представлены Шёнфинкелем (1924)(Электронная книга: ISBN 978-1-57955-044-8 )