Урок 8. Введение в редукцию графов

16
1 Кубенский А.А. Функциональное программирование. Глава 5. Системы исполнения функциональных программ. Глава 5. Системы исполнения функциональных программ 5.3. Функциональные модели последовательных процессов Рассмотрим простой язык императивного программирования без функций, переходов и сложных структур данных. Выражения: Целые числа: 12 25 0 Простые переменные целого типа: x myInt Унарные и бинарные операции с целыми результатами: (x+12) * (y-1) Логические константы и выражения (но не переменные): not (x < 5) Операторы: Присваивание: x := x+1 Последовательное исполнение: begin s1; s2; ... end Условный оператор: if b then s1 else s2 Пустой оператор: skip Оператор цикла: while b do s Программа начинает работу в состоянии, заданном совокупностью значений переменных (например, заданных оператором ввода данных), а результат программы – конечное состояни (например, выведенное в конце работы оператором вывода).

Upload: -mydls

Post on 12-Aug-2015

140 views

Category:

Education


9 download

TRANSCRIPT

Page 1: Урок 8. Введение в редукцию графов

1Кубенский А.А. Функциональное программирование.

Глава 5. Системы исполнения функциональных программ.

Глава 5. Системы исполнения функциональных программ5.3. Функциональные модели последовательных процессов

Рассмотрим простой язык императивного программирования без функций, переходов и сложных структур данных.

Выражения: Целые числа: 12 25 0

Простые переменные целого типа: x myInt

Унарные и бинарные операции с целыми результатами: (x+12) * (y-1)

Логические константы и выражения (но не переменные): not (x < 5)

Операторы:

Присваивание: x := x+1

Последовательное исполнение: begin s1; s2; ... end

Условный оператор: if b then s1 else s2

Пустой оператор: skip

Оператор цикла: while b do s

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

Page 2: Урок 8. Введение в редукцию графов

2Кубенский А.А. Функциональное программирование.

Глава 5. Системы исполнения функциональных программ.

Рассмотрим программу вычисления факториала.

Пример программы.

begin f := 1; while n > 1 do begin f := f * n; n := n – 1 endend

В начальном состоянии существенно только значение переменной n; в конце работы результат определяется значением переменной f.

Прежде всего, переведем программу в вид, удобный для обработки.

data Expression = { представление выражений }data Operator = { представление операторов }data Context = { представление контекста переменных }

Два способа обработки и исполнения программы:

Интерпретация: interpret :: Operator -> Context -> Context Компиляция: compile :: Operator -> (Context -> Context)

На самом деле оба способа представлены одной и той же карринговой функцией!

Page 3: Урок 8. Введение в редукцию графов

3Кубенский А.А. Функциональное программирование.

Глава 5. Системы исполнения функциональных программ.

Представление выражений и программ.

data Expression = Integral Int | Logical Bool | Variable String | Unary String Expression | Binary Expression String Expression

data Operator = Skip | Assignment String Expression | Sequence [Operator] | If Expression Operator Operator | While Expression Operator

type Context = [(String, Expression)]

interpret :: Operator -> Context -> Contexteval :: Expression -> Context -> Expression

eval v@(Integral n) _ = veval v@(Logical b) _ = veval (Variable x) ctx = assoc x ctxeval (Unary op ex) ctx = intrinsic op [eval ex ctx]eval (Binary e1 op e2) ctx = intrinsic op [eval e1 ctx, eval e2 ctx]

intrinsic "+" [(Integral a), (Integral b)] = Integral (a+b)intrinsic "-" [(Integral a)] = Integral (-a)intrinsic "and" [(Logical a), (Logical b)] = Logical (a && b)

intrinsic :: String -> [Expression] -> Expression

Page 4: Урок 8. Введение в редукцию графов

4Кубенский А.А. Функциональное программирование.

Глава 5. Системы исполнения функциональных программ.

Исполнение операторов.

replace :: String -> Expression -> Context -> Context

replace x val = map (\(y,v) -> (y,if x == y then val else v))

replace "f" (Integral 20) [("n", (Integral 4)), ("f", (Integral 5))]

Например:

даст в результате [("n", (Integral 4)), ("f", (Integral 20))]

interpret :: Operator -> Context -> Context

interpret Skip ctx = ctxinterpret (Assignment x expr) ctx = replace x (eval expr ctx) ctxinterpret (Sequence []) ctx = ctxinterpret (Sequence (s:seq)) ctx = interpret (Sequence seq) (interpret s ctx)interpret (If expr s1 s2) ctx = case (eval expr ctx) of (Logical True) -> interpret s1 ctx (Logical False) -> interpret s2 ctxinterpret oper@(While expr s) ctx = case (eval expr ctx) of (Logical True) -> interpret oper (interpret s ctx) (Logical False) -> ctx

Page 5: Урок 8. Введение в редукцию графов

5Кубенский А.А. Функциональное программирование.

Глава 5. Системы исполнения функциональных программ.

Пример компиляции и исполнения программы

begin f := 1; while n > 1 do begin f := f * n; n := n – 1 endend

program = Sequence [(Assignment "f" (Integral 1)), (While (Binary (Variable "n") ">" (Integral 1)) (Sequence [(Assignment "f" (Binary (Variable "f") "*" (Variable "n"))), (Assignment "n" (Binary (Variable "n") "-" (Integral 1)))])) ]

compile program - функция преобразования контекстов

interpret program [("f", (Integral 0)), ("n", (Integral 3))]

[("f", (Integral 6)), ("n", (Integral 0))]

Page 6: Урок 8. Введение в редукцию графов

6Кубенский А.А. Функциональное программирование.

Глава 6. Введение в редукцию графов.

Глава 6. Введение в редукцию графов6.1. Представление лямбда-выражений в виде графов

Будем исходить из представления программ в виде структур данных расширенного лямбда-исчисления. Наша основная задача – корректно представить концепцию разделения переменных.

Константа c. c

Примитивная функция f. f

Лямбда-выражение λx.E.λ

x E

Применение функции E1 E2.@

E1 E2

Применение конструктора C x y z.C

x zy

Page 7: Урок 8. Введение в редукцию графов

7Кубенский А.А. Функциональное программирование.

Особенности представления некоторых типов выражений.

Представление лямбда-выражений в виде графов (продолжение).

Глава 6. Введение в редукцию графов.

Частичное применений примитивных функций и конструкторов.

1+2 + 1 2 + 1

@

+ 1

@

2

@

+ 1

1 : lst : 1 lst

:

1 lst

: 1

@

: 1

или :

1 t

λ

t

Page 8: Урок 8. Введение в редукцию графов

8Кубенский А.А. Функциональное программирование.

Представление лямбда-выражений в виде графов (продолжение).

Глава 6. Введение в редукцию графов.

Блоки let x = E1 in E2 и letrec x1 = E1;... xk = Ek in E.

let x = E1 in E2 (λx.E2) E1

E2

λ

x

@

E1

letrec x1 = E1;... xk = Ek in E – моделируется с помощью циклических графов.

Page 9: Урок 8. Введение в редукцию графов

9Кубенский А.А. Функциональное программирование.

let twice = λf.λx.f (f x) in twice (λx.+ x 1) 2

Пример представления выражения в виде графа.

Глава 6. Введение в редукцию графов.

(λf.λx.f (f x)) (λx.+ x 1) 2

2

λ

x

λ

f

f

@

x

@

f

λ

@

@

x @

@

+ x

1

Page 10: Урок 8. Введение в редукцию графов

10Кубенский А.А. Функциональное программирование.

• Нахождение самого левого из самых внешних редексов: проход по «левому гребню» графа.

Правила редукции графов.

Глава 6. Введение в редукцию графов.

2

x

x

@

succ

λ

@

• Копирование тела лямбда-выражения.

x

@

succ

• Подстановка аргумента вместо свободных вхождений переменной лямбда-выражения в тело.

• Замещение в дереве @-узла результатом «вычислений».

Некоторые особенности этой процедуры:• Тело лямбда-выражения копируется, чтобы его можно было переиспользовать; «мусор»

удаляется• Подстановка аргументов производится с помощью установки ссылок; тем самым

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

результат будут иметь новое значение

Page 11: Урок 8. Введение в редукцию графов

11Кубенский А.А. Функциональное программирование.

Пример редукции графов.

Глава 6. Введение в редукцию графов.

(λf.λx.f (f x)) (λx.+ x 1) 2

2

λ

x

λ

f

f

@

x

@

f

λ

@

@

x @

@

+ x

1

Page 12: Урок 8. Введение в редукцию графов

12Кубенский А.А. Функциональное программирование.

Глава 6. Введение в редукцию графов.

2

λ

@

@

x @

@

+ x

1

Пример редукции графов.

(λf.λx.f (f x)) (λx.+ x 1) 2

@

@

+

1

3

4

Page 13: Урок 8. Введение в редукцию графов

13Кубенский А.А. Функциональное программирование.

δ-редукция в графовом представлении

Глава 6. Введение в редукцию графов.

Если при проходе по левому гребню находим константу, то это – примитивная функция

2+

@

3

@

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

@

@

*

612

Page 14: Урок 8. Введение в редукцию графов

14Кубенский А.А. Функциональное программирование.

Общий алгоритм редукции графов (пока без учета рекурсии)

Глава 6. Введение в редукцию графов.

while (выражение не находится в СЗНФ) { спуск от корня по левому гребню до первой вершины, отличной от @-вершины; switch (тип вершины) { case (примитивная функция): if (число аргументов k > числа пройденных @-вершин) выражение находится в СЗНФ; else { редуцировать все строгие аргументы; сформировать результат согласно правилам примитивной функции; заменить k-ю @-вершину этим результатом; } break; case (λ-вершина): if (выше нет @-вершин) выражение находится в СЗНФ; else { создать копию тела с подстановкой (разделяемого) аргумента вместо свободных вхождений переменной λ-выражения; подставить результат вместо вершины редекса (первая @-вершина вверх по гребню); } break; default: // константа-значение или конструктор if (выше нет @-вершин) выражение находится в СЗНФ; else ошибка типа ! break; }}

Page 15: Урок 8. Введение в редукцию графов

15Кубенский А.А. Функциональное программирование.

Использование вершин-синонимов

Глава 6. Введение в редукцию графов.

При выполнении редукций есть одна проблема, связанная с копированием: в теле функциипеременная может быть в корне. Тогда вместо подстановки ссылки на аргумент придется делатькопию вершины, представляющей аргумент.

+

@

λ@

x

1

2

x

@

x@

Можно вместо копирования вершины создавать «вершину-синоним» - «прозрачную» по ссылкам.

Θ

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

Page 16: Урок 8. Введение в редукцию графов

16Кубенский А.А. Функциональное программирование.

Использование вершин-синонимов (продолжение)

Глава 6. Введение в редукцию графов.

Аналогичная проблема возникает при применении примитивных функций-селекторов, которыене преобразуют, а просто выдают аргумент или его часть (например, head или tail).

head

head

@

@

:

:

1 nil

nil

head (cons (head (cons 1 nil)) nil)

Θ

Θ