Вы находитесь на странице: 1из 18

Лекция 2.

λ-исчисление как формальная система

Введение в Функциональное программирование

Джон Харрисон

Университет Кембриджа

10 сентября 2008 г.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Темы

Зачем нужна формальная система


Свободные и связанные переменные
Подстановка
Правила преобразования и эквивалентность λ-термов
Редукция, стратегии вычисления и теорема Чёрча-Россера
Комбинаторы

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Зачем нужна формальная система?

Мы принимаем некоторые факты, как «очевидные», например

(λx y . x + y ) 1 2 = (λy . 1 + y ) 2 = 1 + 2

потому что они согласуются с интуитивным пониманием. Сейчас


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

x −3=5−x

в
2x = 5 + 3
не раздумывая о том, какой за этим скрывается смысл.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Цитата Уайтхеда

К вопросу об обозначениях и формальных правилах вывода.


[. . . ] с помощью обозначений мы можем делать переходы в
рассуждениях почти механически; без обозначений нам бы
потребовались высшие способности мозга. [. . . ]
Цивилизация развивается за счёт увеличения числа важных
операций, которые могут быть выполнены машинально.
А. Н. Уайтхед: «Введение в математику», 1919 г.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Формальный синтаксис λ-термов

λ-термы строятся по индукции следующим образом:


Переменные, например x, u и v3 .
Константы, например c, 0 и false.
Применения, а именно s t где s и t – λ-термы, например f (x).
Абстракции, а именно λx. s, например λx.
Это может быть выражено следующей грамматикой BNF:

Exp = Var | Const | Exp Exp | λ Var . Exp

Так как синтаксис задан по индукции, то мы можем определять


сущности с помощью примитивной рекурсии и доказывать сущности
с помощью структурной индукции.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Примитивная рекурсия: FV

В качестве пояснения к тому, как можно определять функции


рекурсивно, используя синтаксис λ-термов, я приведу формальное
определение множества свободных переменных, записываемое как
FV (t) для терма t.

FV (x) = {x}
FV (c) = ∅
FV (s t) = FV (s) ∪ FV (t)
FV (λx. s) = FV (s) − {x}

В общем случае, мы всегда можем определить значение функции


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

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Структурная индукция: FV – конечно

В качестве примера структурной индукции мы докажем, что для


любого λ-терма t множество FV (t) всегда конечно.
Если t является переменной v , то FV (t) = {v } по определению,
и это множество определённо конечно.
Если t является константой c, то FV (t) = ∅, которое заведомо
конечно.
Если t является применением s1 s2 , то по предположению
индукции FV (s1 ) и FV (s2 ) конечны. Но
FV (t) = FV (s1 ) ∪ FV (s2 ), а объединение двух конечных
множеств — конечно.
Если t — это абстракция λx. s, то по предположению индукции
FV (s) — конечно. Но FV (t) = FV (s) − {x}, которое должно
быть конечным, ибо его мощность меньше.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Подстановка

Для того, чтобы выразить определённые правила, нам надо


формализовать понятие подстановки терма вместо переменной в
другой терм.
Мы записываем t[s/x] как результат подстановки терма s вместо
переменной x в другой терм t. Иногда записывают t[x := s] и даже
t[x/s].
Нашу запись можно запомнить, проведя аналогию с умножении
дробей:

x[t/x] = t

Например:

(λz. x + z + x)[y /x] = λz. y + z + y


Конечно, мы делаем подстановку только для свободных
переменных, поэтому (λx. x)[y /x] = λx. x.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Простая подстановка

На первый взгляд, кажется, что мы можем определить подстановку,


используя примитивную рекурсию следующим образом:

x[t/x] = t
y [t/x] = y if x 6= y
c[t/x] = c
(s1 s2 )[t/x] = s1 [t/x] s2 [t/x]
(λx. s)[t/x] = λx. s
(λy . s)[t/x] = λy . (s[t/x]) if x 6= y

Однако, это не так. Имеем (λy . x + y )[y /x] = λy . y + y — захват


переменной. Нам следует сначала переименовать переменную, чтобы
получить λw . x + w , и только потом совершить простую подстановку.

(λw . x + w )[y /x] = λw . y + w

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Подстановка переименовывания

Рассмотрим два случая, определяя (λy . s)[t/x] для x 6= y .


Если x 6∈ FV (s) либо y 6∈ FV (t), то можно сделать подстановку
как ни в чём ни бывало; захвата переменной не произойдёт.
Иначе мы берём новую переменную z 6∈ FV (s) ∪ FV (t) и
составляем выражение λz. (s[z/y ][t/x]). Сначала мы
переименовываем связанную переменную y в z, а потом
продолжаем делать подстановку как ни в чём ни бывало.
Для определённости мы можем взять z как самую первую
лексикографическую переменную, которая не является свободной ни
в s, ни в t.
Указанное выше определение гарантирует, что подстановка не
нарушает интуитивного представления. Теперь мы можем свободно
пользоваться этой операцией.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Правила преобразования

λ-исчисление основано на трёх фундаментальных «конверсиях»,


которые преобразовывают одни термы в другие, интуитивно
эквивалентные термы. Конверсии традиционно обозначаются
греческими буквами: α (alpha), β (beta) и η (eta). Самая важная для
нас это β-конверсия.
α-конверсия: λx. s −→ λy . s[y /x], где y 6∈ FV (s). Например,
α
λu. u v −→ λw . w v , но λu. u v 6−→ λv . v v . Это ограничение
α α
позволяет избежать захвата переменной.
β-конверсия: (λx. s) t −→ s[t/x].
β
η-конверсия: λx. t x −→ t, где x 6∈ FV (t). Например,
η
λu. v u −→ v , но λu. u u 6−→ u.
η η

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Эквивалентность λ-термов

Говорят, что два терма s и t равны, если существует конечная


последовательность α, β или η конверсий, которая переводит один
терм в другой. Это записывается как s = t.
Формально это отношение определяется по индукции (см.
следующий слайд).
Заметим, что понятие «равенство» определено, поэтому это не то
же самое, что и синтаксическое равенство. Синтаксическим
равенством мы называем «тождество» и используем знак ≡.
Например, λx. x = λy . y , но λx. x 6≡ λy . y .
Отношение равенства экстенсионально, т.е. если две функции f и g
дают одинаковые значения для всех аргументов, то эти функции
равны. Действительно, если f и g обладают таким свойством, то
взяв переменную y , которая не является свободной ни в f , ни в g ,
получим f y = g y . Поэтому λy . f y = λy . g y . Применив
η-конверсию пару раз, получим f = g .

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Эквивалентность λ-термов: определение


s −→ t or s −→ t or s −→ t
α β η
s=t

t=t
s=t
t=s
s = t and t = u
s=u
s=t
su=tu
s=t
us=ut
s=t
λx. s = λx. t
Джон Харрисон Введение в Функциональное программирование
Лекция 2. λ-исчисление как формальная система

λ-редукция
Вот «подправленное» определение эквивалентности λ-термов.
s −→ t or s −→ t or s −→ t
α β η
s −→ t

t −→ t
s −→ t and t −→ u
s −→ u
s −→ t
s u −→ t u
s −→ t
u s −→ u t
s −→ t
λx. s −→ λx. t

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Стратегия вычислений

Идея заключается в том, что редукция соответствует постоянным


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

(λx. y ) ((λx. x x x) (λx. x x x))


−→ (λx. y ) ((λx. x x x) (λx. x x x) (λx. x x x))
−→ (λx. y ) (· · · )

и так до бесконечности. Однако, мы можем редуцировать самый


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

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Теорема Чёрча-Россера

Теорема гласит, что если s −→ t1 и s −→ t2 , то существует терм u


такой, что t1 −→ u и t2 −→ u.
Применяя это действие неоднократно, мы получим более сильное
утверждение о том, что если t1 = t2 , то существует терм u такой,
что t1 −→ u и t2 −→ u.
Таким образом, если терм редуцируется или в общем случае равен
терму в нормальной форме, то эта нормальная форма единственна с
точностью до α-конверсии.
Также из теоремы следует, что эквивалентность λ-термов
нетривиальна, так как если два терма в нормальной форме не
α-эквивалентны, то они не равны. Например λx y . x 6= λx y . y .
Другая теорема (тоже доказанная Чёрчем и Россером) гласит, что
если хоть какая-то последовательность редукций завершается, то с
тем же результатом завершится и постоянное редуцирование самого
левого внешнего редекса.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Комбинаторы

Оказывается, мы можем освободиться от λ-абстракций, введя три


простых комбинатора:

I = λx. x
K = λx y . x
S = λf g x. (f x)(g x)

Их названия можно запомнить так: I = Identity (тождество), K =


Konstant (константа) и S = Sharing (выделение).
Комбинаторная полнота: для каждого λ-терма существует
эквивалент без λ-абстракций с теми же свободными переменными,
записанный с помощью комбинаторов.
Это достаточно интересный факт, так как с его помощью можно
избежать таких трудностей, как захват переменной.

Джон Харрисон Введение в Функциональное программирование


Лекция 2. λ-исчисление как формальная система

Комбинаторная полнота

Достаточно найти комбинаторный эквивалент для любого λx. t, где


t — λ-свободен. Тогда мы сможем применить такую процедуру
повторно восходящим способом к самым внутренним абстракциям.
Если t – переменная, то либо t = x, тогда λx. x = I , либо t 6= x,
тогда λx. y = K y .
Если t – константа, скажем, c, тогда λx. y = K c.
Если t – абстракция, скажем s u тогда по предположению
индукции существуют λ-свободные термы s 0 и u 0 такие, что
s 0 = λx. s и u 0 = λx. u. Простое вычисление показывает, что
λx. s u = S s 0 u 0 .
На самом деле достаточно использования S и K , ибо I = S K K .

Джон Харрисон Введение в Функциональное программирование

Вам также может понравиться