Основы функционального программирования/Формализация функционального программирования на основе лямбда-исчисления: различия между версиями

Содержимое удалено Содержимое добавлено
Пока лишь копия текста из MS Word - необходима стилизация
 
Первоначальная викификация
Строка 1:
= Лекция 10. «Формализация Функционального Программирования на основе λ-исчисления»=
 
• Объект изучения: множество определений функций.
*Объект изучения: множество определений функций.
• Предположение: будет считаться, что любая функция может быть определена при помощи некоторого -выражения.
*Предположение: будет считаться, что любая функция может быть определена при помощи некоторого -выражения.
• Цель исследования: установить по двум определениям функций <f1> и <f2> их тождество на всей области определения — . (Здесь использована такая нотация: f — некоторая функция, <f> — определения этой функции в терминах -исчисления).
*Цель исследования: установить по двум определениям функций <f1> и <f2> их тождество на всей области определения — . (Здесь использована такая нотация: f — некоторая функция, <f> — определения этой функции в терминах -исчисления).
 
Проблема заключается в том, что обычно при описании функций задается интенсионал этих функций, а потом требуется установить экстенсиональное равенство. Под экстенсионалом функции понимается её график (ну или таблица в виде множества пар <аргумент, значение>). Под интенсионалом функции понимаются правила вычисления значения функции по заданному аргументу.
 
Возникает вопрос: как учесть семантику встроенных функций при сравнении их экстенсионалов (т.к. явно определения этих функций не известны)? Варианты ответов:
 
1. Можно попытаться выразить семантику встроенных функций при помощи механизма -исчисления. Этот процесс можно довести до случая, когда все встроенные функции не содержат непроинтерпретированных операций.
#Можно попытаться выразить семантику встроенных функций при помощи механизма -исчисления. Этот процесс можно довести до случая, когда все встроенные функции не содержат непроинтерпретированных операций.
2. Говорят, что <f1> и <f2> семантически равны (этот факт обозначается как |= f1 = f2), если f1 (x) = f2 (x) при любой интерпретации непроинтерпретированных идентификаторов.
#Говорят, что <f1> и <f2> семантически равны (этот факт обозначается как |= f1 = f2), если f1 (x) = f2 (x) при любой интерпретации непроинтерпретированных идентификаторов.
Понятие формальной системы
 
== Понятие формальной системы ==
 
Формальная система представляет собой четверку:
 
P = <V, Ф, A, R>, где
 
V — алфавит.
 
Ф — множество правильно построенных формул.
 
А — аксиомы (при этом А  Ф).
 
R — правила вывода.
 
В рассматриваемой задаче формулы имеют вид (t1 = t2), где t1 и t2 — -выражения. Если некоторая формула выводима в формальной системе, то этот факт записывается как (| t1 = t2).
 
Говорят, что формальная система корректна, если (| t1 = t2)  (|= t1 = t2).
 
Говорят, что формальная система полна, если (|= t1 = t2)  (| t1 = t2).
 
Семантическое определение понятия «конструкция» (обозначение — Exp):
1. # .
2. # .
3. # .
4. # .
5. #Никаких других Exp нет.
 
Примечание: Id — множество идентификаторов.
 
Говорят, что v свободна в M  Exp, если:
 
1. M = v.
2.#M = v.
#M = (M1M2), и v свободна в M1 или в M2.
3. #M = v’.M’, и v  v’, и v свободна в M’.
4. #M = (M’), и v свободна в M’.
 
Множество идентификаторов v, свободных в M, обозначается как FV (M).
 
Говорят, что v связана в M  Exp, если:
 
1. M = v’.M’, и v = v’.
#M = v’.M’, и v = v’.
2. M = (M1M2), и v связана в M1 или в M2 (т.е. один и тот же идентификатор может быть свободен и связан в Exp).
#M = (M1M2), и v связана в M1 или в M2 (т.е. один и тот же идентификатор может быть свободен и связан в Exp).
3. M = (M’), и v связана в M’.
#M = (M’), и v связана в M’.
Пример 26. Свободные и связанные идентификаторы.
 
1. M = v. v — свободна.
'''Пример 26. Свободные и связанные идентификаторы.'''
2. M = x.xy. x — связана, y — свободна.
 
3. M = (v.v)v. v входит в это выражение как свободно, так и связанно.
4. #M = VWv. V и Wvсвободнысвободна.
#M = x.xy. x — связана, y — свободна.
#M = (v.v)v. v входит в это выражение как свободно, так и связанно.
#M = VW. V и W — свободны.
 
Правило подстановки: подстановка в выражение E выражения E’ вместо всех свободных вхождений переменной x обозначается как E[x  E’]. Во время подстановки иногда случается так, что получается конфликт имён, т.е. коллизия переменных. Примеры коллизий:
 
(x.yx)[y  z.z] = x.(z.z)x = x.x — корректная подстановка
 
(x.yx)[y  xx] = x.(xx)x — коллизия имён переменных
 
(z.yz)[y  xx] = z.(xx)z — корректная подстановка
 
Точное определение базисной подстановки:
 
1. x[x  E’] = E’
2. y#x[x  E’] = yE’
3.#y[x  E’] = y
#(x.E)[x  E’] = x.E
4. #(y.E)[x  E’] = y.E[x  E’], при условии, что y  FV (E’)
5. #(y.E)[x  E’] = (z.E[y  z])[x  E’], при условии, что y  FV (E’)
6. #(E1E2)[x  E’] = (E1[x  E’]E2[x  E’])
 
Построение формальной системы
== Построение формальной системы ==

Таким образом, сейчас уже все готово для того, чтобы перейти к построению формальной системы, определяющей Функциональное Программирование в терминах λ-исчисления.
 
Правильно построенные формулы выглядят так: Exp = Exp.
 
Аксиомы:
 
|- x.E = y.E[x  y] ()
 
|- (x.E)E’ = E[x  E’] ()
 
|- t = t, в случае, если t — идентификаторы ()
 
Правила вывода:
 
t1 = t2  t1t3 = t2t3 ()
 
t1 = t2  t3t1 = t3t2 ()
 
t1 = t2  t2 = t1 ()
 
t1 = t2, t2 = t3  t1 = t3 ()
 
t1 = t2  x.t1 = x.t2 ()
 
Пример 27. Доказать выводимость формулы: (x.xy)(z.(u.zu))v = (v.yv)v
'''Пример 27. Доказать выводимость формулы: (x.xy)(z.(u.zu))v = (v.yv)v'''
 
(x.xy)(z.(u.zu))v = (v.yv)v
 
(): (x.xy)(z.(u.zu)) = (v.yv)
 
(): (z.(u.zu))y = (v.yv)
 
(): u.yu = v.yv — выводима.
 
Во втором варианте формализации Функционального Программирования можно воспользоваться не свойством симметричности отношения «=», а свойством несимметричности отношения «».
 
Во второй формальной системе правильно построенные формулы выглядят абсолютно так же, как и в первом варианте. Однако аксиомы принимают несколько иной вид:
 
|- x.M  y.M[x  y] (’)
 
|- (x.M)N  M[x  N] (’)
 
|- M  M (’)
 
Правило вывода во втором варианте формальной системы одно:
 
t1  t1’, t2  t2’  t1t2  t1’t2’ ()
 
По существу это правило вывода гласит, что в любом выражении можно выделить вхождения подвыражения и заменить их все любой редукцией из этого подвыражения.
 
Определения:
 
• Выражение вида x.M называется -редексом.
*Выражение вида (x.M)N называется -редексом.
*Выражение вида (x.M)N называется -редексом.
• Выражения, не содержащие -редексов, называются выражениями в нормальной форме.
*Выражения, не содержащие -редексов, называются выражениями в нормальной форме.
 
Несколько теорем (без доказательств):
 
• |- E1 = E2  E1  E2  E2  E1.
*|- E1 = E2  E1  E2  E2  E1.
*E  E1  E  E2  F : E1  F  E2  F. (Теорема Чёрча-Россера).
*Если E имеет нормальные формы E1 и E2, то они эквивалентны с точностью до -конверсии, т.е. различаются только обозначением связанных переменных.
 
Стратегия редукции
== Стратегия редукции ==
1. Нормальная редукционная стратегия. На каждом шаге редукции выбирается текстуально самый левый -редекс. Доказано, что нормальная редукционная стратегия гарантирует получение нормальной формы выражения, если она существует.
 
2. Аппликативная редукционная стратегия. На каждом шаге редукции выбирается  редекс, не содержащий внутри себя других -редексов. Далее будет показано, что аппликативная редукционная стратегия не всегда позволяет получить нормальную форму выражения.
#Нормальная редукционная стратегия. На каждом шаге редукции выбирается текстуально самый левый -редекс. Доказано, что нормальная редукционная стратегия гарантирует получение нормальной формы выражения, если она существует.
Пример 28. Редукция выражения M = (y.x)(EE), где E = x.xx
#Аппликативная редукционная стратегия. На каждом шаге редукции выбирается  редекс, не содержащий внутри себя других -редексов. Далее будет показано, что аппликативная редукционная стратегия не всегда позволяет получить нормальную форму выражения.
1. НРС: (y.x)(EE) = (y.x)[y  EE] = x.
 
2. АРС: (y.x)(EE) = (y.x)((x.xx)(x.xx)) = (y.x)((x.xx)(x.xx)) = ...
'''Пример 28. Редукция выражения M = (y.x)(EE), где E = x.xx'''
 
#НРС: (y.x)(EE) = (y.x)[y  EE] = x.
#АРС: (y.x)(EE) = (y.x)((x.xx)(x.xx)) = (y.x)((x.xx)(x.xx)) = ...
 
В этом примере видно, как апликативная редукционная стратегия может привести к выпадению в дурную бесконечность. Получить нормальную форму выражения M в случае применения аппликативной редукционной стратегии невозможно.
 
Примечание: красным шрифтом выделен -редекс, редуцируемый следующим шагом.
 
Пример 29. Редукция выражения M = (x.xyxx)((z.z)w)
'''Пример 29. Редукция выражения M = (x.xyxx)((z.z)w)'''
1. НРС: (x.xyxx)((z.z)w) = ((z.z)w)y((z.z)w)((z.z)w) = wy((z.z)w)((z.z)w) = wyw((z.z)w) = wyww.
 
2. АРС: (x.xyxx)((z.z)w) = (x.xyxx)w = wyww.
#НРС: (x.xyxx)((z.z)w) = ((z.z)w)y((z.z)w)((z.z)w) = wy((z.z)w)((z.z)w) = wyw((z.z)w) = wyww.
#АРС: (x.xyxx)((z.z)w) = (x.xyxx)w = wyww.
 
В программировании нормальная редукционная стратегия соответствует вызову по имени. Т.е. аргумент выражения не вычисляется до тех пор, пока к нему не возникнет обращения в теле выражения. Аппликативная редукционная стратегия соответствует вызову по значению.
 
Соответствие между вычислениями функциональных программ и редукцией
== Соответствие между вычислениями функциональных программ и редукцией ==
 
Работа интерпретатора описывается несколькими шагами:
 
1. В выражении необходимо выделить некоторое обращение к рекурсивной или встроенной функции с полностью означенными аргументами. Если выделенное обращение к встроенной функции существует, то происходит его выполнение и возврат к началу первого шага.
2. Если выделенноевыражении нанеобходимо первомвыделить шагенекоторое обращение к рекурсивной функции,или товстроенной вместофункции негос подставляетсяполностью телоозначенными функцииаргументами. сЕсли фактическимивыделенное параметрамиобращение (т.к. онивстроенной ужефункции означены).существует, Далеето происходит переходего навыполнение и возврат к началоначалу первого шага.
#Если выделенное на первом шаге обращение к рекурсивной функции, то вместо него подставляется тело функции с фактическими параметрами (т.к. они уже означены). Далее происходит переход на начало первого шага.
3. Если больше обращений нет, то происходит остановка.
#Если больше обращений нет, то происходит остановка.
 
В принципе, вычисления в функциональной парадигме повторяют шаги редукции, но дополнительно содержат вычисления встроенных функций.
 
Представление определений функций в виде -выражений
== Представление определений функций в виде λ-выражений ==
 
Показано, что любое определение функции можно представить в виде -выражения, не содержащего рекурсии. Например:
 
fact = n.if n == 0 then 1 else n * fact (n – 1)
fact = n.if n == 0 then 1 else n * fact (n – 1)
 
То же самое определение можно описать при помощи использования некоторого функционала:
 
fact = (f.n.if n == 0 then 1 else n * f (n – 1)) fact
fact = (f.n.if n == 0 then 1 else n * f (n – 1)) fact
 
Жирным шрифтом в представленном выражении выделен функционал F. Таким образом, функцию вычисления факториала можно записать так: fact = F fact. Можно видеть, что любое рекурсивное определение некоторой функции f можно представить в таком виде:
 
f = F f
f = F f
 
Это выражение можно трактовать как уравнение, в котором рекурсивная функция f является неподвижной точкой функционала F. Соответственно интерпретатор функционального языка можно в таком же ключе рассматривать как численный метод решения этого уравнения.
 
Можно сделать предположение, что этот численный метод (т.е. интерпретатор) в свою очередь может быть реализован при помощи некоторой функции Y, которая для функционала F находит его неподвижную точку (соответственно определяя искомую функцию) — f = Y F.
 
Свойства функции Y определяются равенством:
 
Y F = F (Y F)
Y F = F (Y F)
 
Теорема (без доказательства):
 
Любой -терм имеет неподвижную точку.
Любой λ-терм имеет неподвижную точку.
-исчисление позволяет выразить любую функцию через чистое -выражение без использования встроенных функций. Например:
 
1. prefix = xyz.zxy
λ-исчисление позволяет выразить любую функцию через чистое λ-выражение без использования встроенных функций. Например:
head = p.p(xy.x)
 
tail = p.p(xy.y)
#prefix = λxyz.zxy
2. Моделирование условных выражений:
head = λp.p(λxy.x)
True  xy.x
tail = λp.p(λxy.y)
False  xy.y
#Моделирование условных выражений:
if B then M else N  BNM, где B  {True, False}.
True = λxy.x
False = λxy.y
if B then M else N = BNM, где B = {True, False}.