Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / 8

.pdf
Скачиваний:
104
Добавлен:
29.01.2021
Размер:
107.09 Кб
Скачать

§ Базовые программные конструкции в нотации лямбда-исчисления.

Логические значения true и false определяются следующим образом:

TRUE = λxy.x (функция, всегда возвращающая первый аргумент)

FALSE = λxy.y (функция, всегда возвращающая второй аргумент)

Как известно, условный оператор IF имеет следующий вид: IF c THEN a ELSE b

Ему соответствует функция с 3 аргументами: IF (c, a, b)

λ-выражение конструкции IF с 3 аргументами согласно определению абстракции: IF = λc.λa.λb.X = λcab.X

Обратим внимание, что это запись соответствует тому, что абстракция интерпретируется ассоциативно вправо, то есть:

λcab.X означает (λc.(λa.(λb.(X))))

Напишем cab вместо X, то есть IF = λcab.cab.

Тогда, если c = true, то есть: IF true THEN a ELSE b

то это в функциональном смысле эквивалентно записи (true a b)

или (подставляя TRUE = λxy.x) λxy.x a b

или

a

(функция вернула первый аргумент)

Если c = false, то есть:

IF false THEN a ELSE b

то это в функциональном смысле эквивалентно записи (false a b)

или

λxy.y a b

или

b

(функция вернула второй аргумент)

1

Теперь запишем эти преобразования в форме редукций.

Итак, IF = λcab.cab и в это лямбда-выражение вместо c подставляем true, то есть λxy.x или, что то же самое согласно определению альфа-редукции (замене связанных переменных), λab.a. Получаем:

IF TRUE → λab.(λab.a)ab → λab.a

IF FALSE → λab.(λab.b)ab → λab.b

Пример реализации

c = FALSE

IF c 1 0 = (λcab.cab) (λxy.y) 1 0

Первая подстановка приводит к выражению (λab.(λxy.y)ab) 1 0

Далее есть два варианта подстановки:

Первый вариант:

[x/a], [y/b] в λxy.y: → (λab.b) 1 0 → 0

Второй вариант:

[a/1], [b/0]: → (λxy.y) 1 0 → 0

Реализация других логических операций (отрицания, конъюнкции, дизъюнкции):

NOT = λcab.cba

Пример: NOT TRUE = (λcab.cba) TRUE = (λab.(λxy.x) ba) = (λab.b) = FALSE

AND = λab.aba

OR = λab.aab

not p = if p then false else true p and q = if p then q else false p or q = if p then true else q

Проведем аналогию лямбда-исчисления и языка Haskell. Функции true, false, if можно записать следующим образом:

true a b = a false a b = b if c a b = c a b

Определения можно ввести и по-другому. В языке Haskell есть встроенный тип Bool:

data Bool = True | False

if :: Bool -> a -> a -> a if True t e = t

if False t e = e

В процедурных языках для преобразования выражений используется эквивалент аппликативной редукционной стратегии. В языке Haskell используется аналог нормальной стратегии.

Пары, кортежи, списки

Пара – упорядоченный набор двух значений, кортеж – упорядоченный набор n элементов.

struct pair {TYPE_1 first; TYPE_2 second;};

2

Введем выражения

first p = λp.p true second p = λp.p false

Тогда выражение

pair = λb.b p q или λxyf.fxy

создает пару (x,y), функция first возвращает первый элемент кортежа, second — второй.

first (p, q) = (p, q) true = (λb.b p q) true = true p q = (λxy. x) p q = p second (p, q) = (p, q) false = (λb.b p q) false = false p q = (λxy.y) p q = q

second (pair 4 5) → second ((λxyf.fxy) 4 5) → second ((λyf.f 4 y) 5) → second (λf.f 4 5) → (λp.p false) (λf.f 4 5) → (λf.f 4 5) false → false 4 5 → (λxy.y) 4 5 → 5

Аналогично можно определять другие структуры, скажем, IP-адрес:

IP = λabcdf.fabcd

IP_OCTET_A = λp.p (λabcd.a)

IP_OCTET_B = λp.p (λabcd.b)

IP_OCTET_C = λp.p (λabcd.c)

IP_OCTET_D = λp.p (λabcd.d)

Применение выражения pair к паре позволяет создавать кортежи из трёх и большего количества элементов, например pair x (pair y z) — кортеж из трёх элементов.

(p, q, r, s) = (p, (q, (r, s))) = λb.b p (q, (r, s)) = λb.b p (λb.b q (r, s)) = λb.b p (λb.b q (λb.b r s)) = λb.b p (λg.g q (λh.h r s))

С помощью лямбда-исчисления также можно строить связные списки. Каждый элемент списка должен содержать как минимум одно значение и ссылку на следующий элемент, то есть пару.

Для разграничения пар используем дополнительные пары с первым элементом, равным FALSE:

Создание пары: λxy.( pair false (pair x y))

Извлечение первого элемента пары: λx.(first (second x)) Извлечение второго элемента пары: λx.( second (second x)) Пустой список: NIL = λx.x

Проверка на пустой список: ISNULL = first

Аналоги всех введенных операций существуют в языке Lisp.

Числа в нумерации Черча.

В нумерации Черча числа выражаются функциями двух аргументов:

0 = FALSE = λfx.x

1 = λfx.fx

2 = λfx.f (fx)

3 = λfx.f ( f (fx))

n = λfx.f(...<n раз>...(fx)...) λfx. f n x,

и называются нумералами Черча.

Эти выражения фактически представляют собой запись чисел в системе счисления по основанию 1: 1, 11, 111, 1111, 11111, 111111, . . ..

Увеличение нумерала Черча на единицу: λnfx.n f (f x)

3

(λnfx.n f (f x)) (λfx.f n x) = λfx.(λfx.f n x) f (f x) = λfx.(λx.fn x)(f x) = λfx.fn (f x) = λfx.fn+1 x = n + 1 Проверка n на равенство нулю: λn.n (λx. false) true

Если ноль: (λn.n (λx.FALSE) TRUE) 0 = 0 (λx.FALSE) TRUE = λfx.x (λx.FALSE) TRUE = TRUE

Если не ноль: (λn.n (λx.FALSE) TRUE) 1 = 1 (λx.FALSE) TRUE = λfx.fx (λx.FALSE) TRUE = (λx.FALSE) TRUE = (λx.λab.b) TRUE = λab.b = FALSE

Сложение нумералов Черча: m+n = λfx.m f (n f x)

Произведение нумералов Черча: m n = λf x. m (n f) x

4

Соседние файлы в папке Лекции