eval(Int(x)::S,E,C,D)

реклама
Сошников Дмитрий Валерьевич
к.ф.-м.н., доцент
dmitryso@microsoft.com
Факультет инноваций и высоких технологий
Московский физико-технический институт
Реализация функциональных
языков: интерпретаторы и
абстрактные машины
2
eval Let ("id",Lam ("x",Var "x"), Let ("sq",Lam ("z",App (App (PFunc "*",Var "z"),Var "z")), App (Var "sq",App (Var "id",Int 5)))) in []
eval Lam ("x",Var "x") in []
eval Let ("sq",Lam ("z",App (App (PFunc "*",Var "z"),Var "z")),App (Var "sq",App (Var "id",Int 5))) in [[id,Closure(Lam(“x”,Var(“x”)))]]
eval Lam ("z",App (App (PFunc "*",Var "z"),Var "z")) in [[id,Closure(Lam(“x”,Var(“x”)))]]
eval App (Var "sq",App (Var "id",Int 5)) in [[id,…]; [sq, …]] – вычисление внутреннего выражения sq(id 5)
eval Var "sq" in [[id,...]; [sq, ...]]
eval App (Var "id",Int 5) in [[id, …]; [sq, …]] - применение id 5
eval Var "id" in [[id,…]; [sq,…]]
eval Int 5 in [[id, …]; [sq, …]]
app (Closure (Lam ("x",Var "x"), [])) (Int 5) - применение (x.x)5
eval Var "x" in [[x,Int(5)]]
app (Closure(Lam ("z",App (App (PFunc "*",Var "z"),Var "z")), [[id,…]])) (Int 5) – применение (z.z*z)5
eval App (App (PFunc "*",Var "z"),Var "z") in [[id, …]; [z, Int(5)]] – подстановка z=5 в окружение
eval App (PFunc "*",Var "z") in [[id, …]; [z, Int(5)]]
eval PFunc "*" in [[id, …]; [z, Int(5)]]
eval Var "z" in [[id,…]; [z, Int(5)]]
app (Op ("*",2,[])) (Int 5) - применение (*)5
eval Var "z" in [[id, …]; [z, Int(5)]]
app (Op ("*",1,[Int 5])) (Int 5) – применение ((*)5)5
val it : expr = Int 25
3
©2008 Сошников Д.В.
let id = x.x in let sq = z.z*z in sq(id 5)
letrec fact =
fun x ->
if x<=1 then 1
else x*fact(x-1)
in fact 4;;
4
©2008 Сошников Д.В.
При вычислении fact 4 необходимо
вычислять (eval) fact в контексте,
содержащем само определение fact
 При этом будет происходить
вычисление fact в
последовательности контекстов с
x=4, 3, 2, 1.
 Для реализации вводим тип
выражения LetRec и Rclosure
 RClosure – вычисление замыкания, в
контекст которого надо добавить
определение самой функции

©2008 Сошников Д.В.
let rec eval exp env =
match exp with
...
| Let(id,e1,e2) ->
let r = eval e1 env in
eval e2 (Map.add id r env)
| LetRec(id,e1,e2) ->
eval e2 (Map.add id (RClosure(e1,env,id)) env)
...
and apply e1 e2 =
match e1 with
Closure(Lam(v,e),env) ->
eval e (Map.add v e2 env)
| RClosure(Lam(v,e),env,id) ->
eval e (Map.add v e2 (Map.add id e1 env))
...
5

©2008 Сошников Д.В.

При ленивых вычислениях f x мы сначала
начинаем вычислять f, а вычисление x
откладываем (задерживаем)
Для «откладывания» вводим конструкцию
Susp(expr,env)
 Похожа на Closure, теоретически можно
моделировать отложенность с помощью
замыканий, т.е. выражений вида (fun () -> expr)

При аппликации задерживаем вычисление
второго аргумента
6
©2008 Сошников Д.В.
let rec eval exp env =
match exp with
...
| App(e1,e2) -> apply (eval e1 env) (Susp(e2,env))
| Let(id,e1,e2) ->
let r = Susp(e1,env) in
eval e2 (Map.add id r env)
| Susp(e,envr) -> eval e envr
...
let rec funof = function
"+" -> (function [a;b] ->
let Int(x),Int(y)=
eval a Map.empty,eval b Map.empty
in Int(x+y))
...
7
8
©2008 Сошников Д.В.

Прямая интерпретация дерева программы не
всегда эффективна
 Рекурсивный алгоритм, в явном виде не
контролируем расходы памяти
 Хочется получить более простой алгоритм в
терминах низкоуровневых команд элементарного
исполнителя
 Алгоритм, пригодный для реализации на более
низкоуровневом языке

Выход: использование абстрактных
(стековых) машин
9
©2008 Сошников Д.В.

SECD-машина – это абстрактная машина,
состояние которой состоит из 4-х стеков:
 S – Stack – стек объектов для вычисления
выражений
 E – Environment – среда для означивания
переменных, контекст
 C – Control – управляющая строка, оставшаяся
часть вычисляемого выражения
 D – Dump – стек возвратов для обработки
вложенных конткестов (вызовы функций)
10
©2008 Сошников Д.В.

1+2
S
E
C
D
[]
[]
[App(App(+,1),2)]
[]
[]
[]
[2,App(+,1),@]
[]
[2]
[]
[App(+,1),@]
[]
[2]
[]
[1,+,@,@]
[]
[1,2]
[]
[+,@,@]
[]
[+,1,2]
[]
[@,@]
[]
[(+1),2]
[]
[@]
[]
[3]
[]
[]
[]
11
©2008 Сошников Д.В.

(λf. λx.(f f x)) succ 0
S
E
C
D
[]
[]
[A(A(L(f,L(x,A(f,A(f,x))),succ),0)]
[]
[]
[]
[0, A(L(f,L(x,A(f,A(f,x))),succ),@]
[]
[0]
[]
[A(L(f,L(x,A(f,A(f,x))),succ),@]
[]
[0]
[]
[succ, L(f,L(x,A(f,A(f,x)))),@,@]
[]
[succ,0]
[]
[L(f,L(x,A(f,A(f,x)))),@,@]
[]
[C(f,L(x,A(f,A(f,x))),[]),
succ,0]
[]
[@,@]
[]
[]
[(f,succ)]
[L(x,A(f,A(f,x)))]
[([0],[],[@])]
[C(x, A(f,A(f,x)),
(f,succ))]
[(f,succ)]
[]
[([0],[],[@])]
Вызов
функции
12
E
C
©2008 Сошников Д.В.
S
D
[C(x, A(f,A(f,x)),
(f,succ))]
[(f,succ)]
[]
[([0],[],[@])]
[C(x, A(f,A(f,x)),
(f,succ)),0]
[]
[@]
[]
[]
[(f,succ), (x,0)]
[A(f,A(f,x))]
[([],[],[])]
[]
[(f,succ), (x,0)]
[A(f,x),f,@]
[([],[],[])]
[]
[(f,succ), (x,0)]
[x,f,f,@,@]
[([],[],[])]
[0]
[(f,succ), (x,0)]
[f,f,@,@]
[([],[],[])]
[0,succ,succ]
[(f,succ), (x,0)]
[@,@]
[([],[],[])]
[1,succ]
[(f,succ), (x,0)]
[@]
[([],[],[])]
[2]
[(f,succ), (x,0)]
[]
[([],[],[])]
[2]
[]
[]
[]
13
©2008 Сошников Д.В.
type id = string;;
type expr =
Var of id
| Lam of id*expr
| App of expr*expr
| PFunc of (expr->expr)
| AT
| Int of int
| Closure of id*expr*env
and env = Map<id,expr>;;
;;
type
type
type
type
stack = expr list;;
control = expr list;;
dump = (stack*env*control) list;;
state = stack*env*control*dump;;
14
©2008 Сошников Д.В.
let rec eval SECD =
match SECD with
(Res::S, E, C, D) when C=[] && D=[] -> Res
| (x::S, E, C, (S1,E1,C1)::D) when C=[]
-> eval
(x::S1,E1,C1,D)
| (S,E,Var(x)::C,D) -> eval ((Map.find x E)::S,E,C,D)
| (S,E,Lam(x,b)::C,D) -> eval (Closure(x,b,E)::S,E,C,D)
| (S,E,Int(x)::C,D) -> eval(Int(x)::S,E,C,D)
| (S,E,PFunc(x)::C,D) -> eval(PFunc(x)::S,E,C,D)
| (Closure(x,b,E1)::(arg::S),E,AT::C,D) ->
eval ([],Map.add x arg E1,[b],(S,E,C)::D)
| (PFunc(f)::(arg::S),E,AT::C,D) -> eval (f(arg)::S,E,C,D)
| (S,E,App(f,a)::C,D) -> eval (S,E,a::(f::(AT::C)),D)
;;
Обратите внимание на хвостовую рекурсию!
15
©2008 Сошников Д.В.


Условный оператор
Реализация рекурсии
 При помощи комбинатора неподвижной точки Y
▪ Вариант для энергичной стратегии вычислений
Y’=λh.(λx.h(λy.xxy))(λx.h(λy.xxy)))
 При помощи помеченных выражений
Ленивая SECD-машина
 Доказательство эквивалентности конверсии и вычислений SECD-машины (см.
Филд, Харрисон)

16
Скачать