SlideShare a Scribd company logo
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
Программа начинает работу в состоянии, заданном совокупностью значений переменных
(например, заданных оператором ввода данных), а результат программы – конечное состояние
(например, выведенное в конце работы оператором вывода).
2
Кубенский А.А. Функциональное программирование.
Глава 5. Системы исполнения функциональных программ.
Рассмотрим программу вычисления факториала.
Пример программы.
begin f := 1;
while n > 1 do begin
f := f * n;
n := n – 1
end
end
В начальном состоянии существенно только
значение переменной n; в конце работы результат
определяется значением переменной f.
Прежде всего, переведем программу в вид, удобный для обработки.
data Expression = { представление выражений }
data Operator = { представление операторов }
data Context = { представление контекста переменных }
Два способа обработки и исполнения программы:
 Интерпретация: interpret :: Operator -> Context -> Context
 Компиляция: compile :: Operator -> (Context -> Context)
На самом деле оба способа представлены одной и той же карринговой функцией!
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 -> Context
eval :: Expression -> Context -> Expression
eval v@(Integral n) _ = v
eval v@(Logical b) _ = v
eval (Variable x) ctx = assoc x ctx
eval (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
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 = ctx
interpret (Assignment x expr) ctx = replace x (eval expr ctx) ctx
interpret (Sequence []) ctx = ctx
interpret (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 ctx
interpret oper@(While expr s) ctx = case (eval expr ctx) of
(Logical True) -> interpret oper (interpret s ctx)
(Logical False) -> ctx
5
Кубенский А.А. Функциональное программирование.
Глава 5. Системы исполнения функциональных программ.
Пример компиляции и исполнения программы
begin f := 1;
while n > 1 do begin
f := f * n;
n := n – 1
end
end
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))]
6
Кубенский А.А. Функциональное программирование.
Глава 6. Введение в редукцию графов.
Глава 6. Введение в редукцию графов
6.1. Представление лямбда-выражений в виде графов
Будем исходить из представления программ в виде структур данных расширенного лямбда-
исчисления. Наша основная задача – корректно представить концепцию разделения переменных.
Константа c. c
Примитивная функция f. f
Лямбда-выражение λx.E.
λ
x E
Применение функции E1 E2.
@
E1 E2
Применение конструктора C x y z.
C
x zy
7
Кубенский А.А. Функциональное программирование.
Особенности представления некоторых типов выражений.
Представление лямбда-выражений в виде графов (продолжение).
Глава 6. Введение в редукцию графов.
Частичное применений примитивных функций и конструкторов.
1+2 + 1 2 + 1
@
+ 1
@
2
@
+ 1
1 : lst : 1 lst
:
1 lst
: 1
@
: 1
или :
1 t
λ
t
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 – моделируется с помощью циклических графов.
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
10
Кубенский А.А. Функциональное программирование.
• Нахождение самого левого из самых внешних редексов: проход по «левому гребню» графа.
Правила редукции графов.
Глава 6. Введение в редукцию графов.
2
x
x
@
succ
λ
@
• Копирование тела лямбда-выражения.
x
@
succ
• Подстановка аргумента вместо свободных вхождений переменной лямбда-выражения в тело.
• Замещение в дереве @-узла результатом «вычислений».
Некоторые особенности этой процедуры:
• Тело лямбда-выражения копируется, чтобы его можно было переиспользовать; «мусор»
удаляется
• Подстановка аргументов производится с помощью установки ссылок; тем самым
производится эффективное разделение переменных
• Результат редукции замещает редуцируемое выражение, тем самым все ссылки на этот
результат будут иметь новое значение
11
Кубенский А.А. Функциональное программирование.
Пример редукции графов.
Глава 6. Введение в редукцию графов.
(λf.λx.f (f x)) (λx.+ x 1) 2
2
λ
x
λ
f
f
@
x
@
f
λ
@
@
x @
@
+ x
1
12
Кубенский А.А. Функциональное программирование.
Глава 6. Введение в редукцию графов.
2
λ
@
@
x @
@
+ x
1
Пример редукции графов.
(λf.λx.f (f x)) (λx.+ x 1) 2
@
@
+
1
3
4
13
Кубенский А.А. Функциональное программирование.
δ-редукция в графовом представлении
Глава 6. Введение в редукцию графов.
Если при проходе по левому гребню находим константу, то это – примитивная функция
2
+
@
3
@
- сначала выполняем редукцию всех строгих аргументов;
- потом формируем результат в соответствии с правилами этой примитивной функции;
- результат замещает собой корень редекса.
@
@
*
6
12
14
Кубенский А.А. Функциональное программирование.
Общий алгоритм редукции графов (пока без учета рекурсии)
Глава 6. Введение в редукцию графов.
while (выражение не находится в СЗНФ) {
спуск от корня по левому гребню до первой вершины, отличной от @-вершины;
switch (тип вершины) {
case (примитивная функция):
if (число аргументов k > числа пройденных @-вершин)
выражение находится в СЗНФ;
else {
редуцировать все строгие аргументы;
сформировать результат согласно правилам примитивной функции;
заменить k-ю @-вершину этим результатом;
}
break;
case (λ-вершина):
if (выше нет @-вершин)
выражение находится в СЗНФ;
else {
создать копию тела с подстановкой (разделяемого) аргумента
вместо свободных вхождений переменной λ-выражения;
подставить результат вместо вершины редекса (первая @-вершина вверх по гребню);
}
break;
default: // константа-значение или конструктор
if (выше нет @-вершин)
выражение находится в СЗНФ;
else
ошибка типа !
break;
}
}
15
Кубенский А.А. Функциональное программирование.
Использование вершин-синонимов
Глава 6. Введение в редукцию графов.
При выполнении редукций есть одна проблема, связанная с копированием: в теле функции
переменная может быть в корне. Тогда вместо подстановки ссылки на аргумент придется делать
копию вершины, представляющей аргумент.
+
@
λ
@
x
1
2
x
@
x
@
Можно вместо копирования вершины создавать «вершину-синоним» - «прозрачную» по ссылкам.
Θ
При прохождении вершины-синонима можно оптимизировать их количество, убирать двойные
синонимы, заменять ссылки на синоним ссылками на саму вершину.
16
Кубенский А.А. Функциональное программирование.
Использование вершин-синонимов (продолжение)
Глава 6. Введение в редукцию графов.
Аналогичная проблема возникает при применении примитивных функций-селекторов, которые
не преобразуют, а просто выдают аргумент или его часть (например, head или tail).
head
head
@
@
:
:
1 nil
nil
head (cons (head (cons 1 nil)) nil)
Θ
Θ

More Related Content

PPT
Характерные черты функциональных языков программирования
PDF
Функциональное программирование и Clojure
PPT
PPTX
Урок 6. Чистое лямбда-исчисление.
PPTX
Урок 4. "Завязывание узлов". Классы
PDF
Discovering Lambdas in Java 8
PPT
практика 4
PPT
Характерные черты функциональных языков программирования
Функциональное программирование и Clojure
Урок 6. Чистое лямбда-исчисление.
Урок 4. "Завязывание узлов". Классы
Discovering Lambdas in Java 8
практика 4

What's hot (20)

PPT
PPTX
алгоритмы stl
PPTX
Урок 1. Что такое функциональное программирование
PPT
2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы
PDF
Математическое обоснование SOLID принципов - Евгений Тюменцев Dev2Dev v2.0 30...
PPTX
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
PPTX
структура программы
PDF
Алгоритмы решения задачи о булевой выполнимости (SAT) и их применение в крипт...
PDF
Лекция №5. Линейные структуры данных. Предмет "Структуры и алгоритмы обработк...
PPTX
Cpp/cli types
PPTX
Урок 7. Интерпретация и компиляция функциональных программ.
PPT
теория рекурсивных функций
PDF
A System of Deductive Verification of Predicate Programs
PPTX
особенности программирования на с++
PDF
Python: Модули и пакеты
PPT
Математическое обоснование S.O.L.I.D принципов
PPTX
стандартная библиотека с++: введение
PPTX
Java8. Innovations
PPT
Discovering Lambdas (Speech)
алгоритмы stl
Урок 1. Что такое функциональное программирование
2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы
Математическое обоснование SOLID принципов - Евгений Тюменцев Dev2Dev v2.0 30...
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
структура программы
Алгоритмы решения задачи о булевой выполнимости (SAT) и их применение в крипт...
Лекция №5. Линейные структуры данных. Предмет "Структуры и алгоритмы обработк...
Cpp/cli types
Урок 7. Интерпретация и компиляция функциональных программ.
теория рекурсивных функций
A System of Deductive Verification of Predicate Programs
особенности программирования на с++
Python: Модули и пакеты
Математическое обоснование S.O.L.I.D принципов
стандартная библиотека с++: введение
Java8. Innovations
Discovering Lambdas (Speech)
Ad

Viewers also liked (17)

PPTX
Урок 3. Карринг и ленивые вычисления.
PDF
Fifty Years of Global LNG, Trafigura White Paper
PPTX
World wonders - Learning new words
PPTX
Функциональное программирование.Списки. Функции высших порядков
PDF
Foundations for Growth: Infrastructure Investment in Emerging Markets
PDF
The Economics of Commodity Trading Firms - White Paper
PDF
Not Too Big To Fail – Systemic Risk, Regulation, and the Economics of Commodi...
PDF
The economics of commodity trading firms in english (abridged)
PDF
Trafigura 2015 Interim Report
PDF
Trafigura 2013 Full Annual Report
PPTX
Урок 9. Комбинаторная редукция
PDF
Trafigura 2014 Full Annual Report
PDF
2015 Trafigura Responsibility Report
PDF
2-Epidemiological studies
PPT
презентація до дипломної роботи кулєш ю.а. 2013
PDF
Trafigura 2014 Interim Report
PPTX
project ppt
Урок 3. Карринг и ленивые вычисления.
Fifty Years of Global LNG, Trafigura White Paper
World wonders - Learning new words
Функциональное программирование.Списки. Функции высших порядков
Foundations for Growth: Infrastructure Investment in Emerging Markets
The Economics of Commodity Trading Firms - White Paper
Not Too Big To Fail – Systemic Risk, Regulation, and the Economics of Commodi...
The economics of commodity trading firms in english (abridged)
Trafigura 2015 Interim Report
Trafigura 2013 Full Annual Report
Урок 9. Комбинаторная редукция
Trafigura 2014 Full Annual Report
2015 Trafigura Responsibility Report
2-Epidemiological studies
презентація до дипломної роботи кулєш ю.а. 2013
Trafigura 2014 Interim Report
project ppt
Ad

Similar to Урок 8. Введение в редукцию графов (20)

PDF
Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...
PDF
fp intro
PDF
Лекция о языке программирования Haskell
PPTX
Functional Programing
PPT
Программирование разветвляющихся алгоритмов
PPT
лекция 3
PPT
формальные языки и грамматики
PDF
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
PDF
Функциональное программирование - Александр Алексеев
PPTX
Николай Паламарчук "Functional Programming basics for PHP developers"
PPT
лекция 16
PDF
Рекурсия (2017)
PDF
Математические основы методов решений систем логических уравнений
DOC
лекция 3. программирование циклов
PPS
22.01.2015 решение задач 11 и 14 информатика егэ 2015 (1)
PDF
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
PDF
20110224 systems of_typed_lambda_calculi_moskvin_lecture01
PPTX
[DD] 3. Combinational circuits
Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...
fp intro
Лекция о языке программирования Haskell
Functional Programing
Программирование разветвляющихся алгоритмов
лекция 3
формальные языки и грамматики
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Функциональное программирование - Александр Алексеев
Николай Паламарчук "Functional Programming basics for PHP developers"
лекция 16
Рекурсия (2017)
Математические основы методов решений систем логических уравнений
лекция 3. программирование циклов
22.01.2015 решение задач 11 и 14 информатика егэ 2015 (1)
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
20110224 systems of_typed_lambda_calculi_moskvin_lecture01
[DD] 3. Combinational circuits

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

  • 1. 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 Программа начинает работу в состоянии, заданном совокупностью значений переменных (например, заданных оператором ввода данных), а результат программы – конечное состояние (например, выведенное в конце работы оператором вывода).
  • 2. 2 Кубенский А.А. Функциональное программирование. Глава 5. Системы исполнения функциональных программ. Рассмотрим программу вычисления факториала. Пример программы. begin f := 1; while n > 1 do begin f := f * n; n := n – 1 end end В начальном состоянии существенно только значение переменной n; в конце работы результат определяется значением переменной f. Прежде всего, переведем программу в вид, удобный для обработки. data Expression = { представление выражений } data Operator = { представление операторов } data Context = { представление контекста переменных } Два способа обработки и исполнения программы:  Интерпретация: interpret :: Operator -> Context -> Context  Компиляция: compile :: Operator -> (Context -> Context) На самом деле оба способа представлены одной и той же карринговой функцией!
  • 3. 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 -> Context eval :: Expression -> Context -> Expression eval v@(Integral n) _ = v eval v@(Logical b) _ = v eval (Variable x) ctx = assoc x ctx eval (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
  • 4. 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 = ctx interpret (Assignment x expr) ctx = replace x (eval expr ctx) ctx interpret (Sequence []) ctx = ctx interpret (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 ctx interpret oper@(While expr s) ctx = case (eval expr ctx) of (Logical True) -> interpret oper (interpret s ctx) (Logical False) -> ctx
  • 5. 5 Кубенский А.А. Функциональное программирование. Глава 5. Системы исполнения функциональных программ. Пример компиляции и исполнения программы begin f := 1; while n > 1 do begin f := f * n; n := n – 1 end end 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))]
  • 6. 6 Кубенский А.А. Функциональное программирование. Глава 6. Введение в редукцию графов. Глава 6. Введение в редукцию графов 6.1. Представление лямбда-выражений в виде графов Будем исходить из представления программ в виде структур данных расширенного лямбда- исчисления. Наша основная задача – корректно представить концепцию разделения переменных. Константа c. c Примитивная функция f. f Лямбда-выражение λx.E. λ x E Применение функции E1 E2. @ E1 E2 Применение конструктора C x y z. C x zy
  • 7. 7 Кубенский А.А. Функциональное программирование. Особенности представления некоторых типов выражений. Представление лямбда-выражений в виде графов (продолжение). Глава 6. Введение в редукцию графов. Частичное применений примитивных функций и конструкторов. 1+2 + 1 2 + 1 @ + 1 @ 2 @ + 1 1 : lst : 1 lst : 1 lst : 1 @ : 1 или : 1 t λ t
  • 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 – моделируется с помощью циклических графов.
  • 9. 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
  • 10. 10 Кубенский А.А. Функциональное программирование. • Нахождение самого левого из самых внешних редексов: проход по «левому гребню» графа. Правила редукции графов. Глава 6. Введение в редукцию графов. 2 x x @ succ λ @ • Копирование тела лямбда-выражения. x @ succ • Подстановка аргумента вместо свободных вхождений переменной лямбда-выражения в тело. • Замещение в дереве @-узла результатом «вычислений». Некоторые особенности этой процедуры: • Тело лямбда-выражения копируется, чтобы его можно было переиспользовать; «мусор» удаляется • Подстановка аргументов производится с помощью установки ссылок; тем самым производится эффективное разделение переменных • Результат редукции замещает редуцируемое выражение, тем самым все ссылки на этот результат будут иметь новое значение
  • 11. 11 Кубенский А.А. Функциональное программирование. Пример редукции графов. Глава 6. Введение в редукцию графов. (λf.λx.f (f x)) (λx.+ x 1) 2 2 λ x λ f f @ x @ f λ @ @ x @ @ + x 1
  • 12. 12 Кубенский А.А. Функциональное программирование. Глава 6. Введение в редукцию графов. 2 λ @ @ x @ @ + x 1 Пример редукции графов. (λf.λx.f (f x)) (λx.+ x 1) 2 @ @ + 1 3 4
  • 13. 13 Кубенский А.А. Функциональное программирование. δ-редукция в графовом представлении Глава 6. Введение в редукцию графов. Если при проходе по левому гребню находим константу, то это – примитивная функция 2 + @ 3 @ - сначала выполняем редукцию всех строгих аргументов; - потом формируем результат в соответствии с правилами этой примитивной функции; - результат замещает собой корень редекса. @ @ * 6 12
  • 14. 14 Кубенский А.А. Функциональное программирование. Общий алгоритм редукции графов (пока без учета рекурсии) Глава 6. Введение в редукцию графов. while (выражение не находится в СЗНФ) { спуск от корня по левому гребню до первой вершины, отличной от @-вершины; switch (тип вершины) { case (примитивная функция): if (число аргументов k > числа пройденных @-вершин) выражение находится в СЗНФ; else { редуцировать все строгие аргументы; сформировать результат согласно правилам примитивной функции; заменить k-ю @-вершину этим результатом; } break; case (λ-вершина): if (выше нет @-вершин) выражение находится в СЗНФ; else { создать копию тела с подстановкой (разделяемого) аргумента вместо свободных вхождений переменной λ-выражения; подставить результат вместо вершины редекса (первая @-вершина вверх по гребню); } break; default: // константа-значение или конструктор if (выше нет @-вершин) выражение находится в СЗНФ; else ошибка типа ! break; } }
  • 15. 15 Кубенский А.А. Функциональное программирование. Использование вершин-синонимов Глава 6. Введение в редукцию графов. При выполнении редукций есть одна проблема, связанная с копированием: в теле функции переменная может быть в корне. Тогда вместо подстановки ссылки на аргумент придется делать копию вершины, представляющей аргумент. + @ λ @ x 1 2 x @ x @ Можно вместо копирования вершины создавать «вершину-синоним» - «прозрачную» по ссылкам. Θ При прохождении вершины-синонима можно оптимизировать их количество, убирать двойные синонимы, заменять ссылки на синоним ссылками на саму вершину.
  • 16. 16 Кубенский А.А. Функциональное программирование. Использование вершин-синонимов (продолжение) Глава 6. Введение в редукцию графов. Аналогичная проблема возникает при применении примитивных функций-селекторов, которые не преобразуют, а просто выдают аргумент или его часть (например, head или tail). head head @ @ : : 1 nil nil head (cons (head (cons 1 nil)) nil) Θ Θ