Ken Wakita (https://wakita.github.io/fp2017/)
Oct. 25, 2017
let rec iter n e = (* Iterative optimization *)
if n = 0 then e else
let e' = Elim.f (ConstFold.f (Inline.f (Assoc.f (Beta.f e)))) in
if e = e' then e else
iter (n - 1) e'
let lexbuf outchan l =
...... .......
(..........
(......
(.........
(.........
(iter !limit
(.......
(.........
(........
(.......... ........... .)))))))))
βε(let x=e1 in e2)={βε,x↦y(e2)βε(e1) is a variable (y)let x=βε(e1) in βε(e2)Otherwise
When a let
expression is an alias/renaming (x↦y), the let
is removed and occurrences of x in e2 are substituted by y.
Beta.g : (Id.t M.t) -> KNormal.t -> KNormal.t
| Let((x, t), e1, e2) -> (* Beta-reduction of `let` expressions *)
(match g env e1 with
| Var(y) ->
Format.eprintf "beta-reducing %s = %s@." x y;
g (M.add x y env) e2
| e1' ->
let e2' = g env e2 in
Let((x, t), e1', e2'))
βε(let x=e1 in e2)={βε,x↦y(e2)βε(e1) is a variable (y)let x=βε(e1) in βε(e2)Otherwise
# beta_p
let x = 1 in
let y = x in
x + y
# alpha beta_p
Let (Ti5_6,
Let (x_7, 1,
Let (y_8, x_7, Add(x_7, y_8))), ...)
# beta beta_p
Let (Ti1_2,
Let (x_3, 1, Add(x_3, x_3)), ...)
A(let x=e1 in e2)=let ... in let x=e′1inA(e2)
A(e1) is a nested let
form (let ... in e′, where let ... is a sequence of one or more let
’s), and e′1 is not a let
form.
| Let(xt, e1, e2) -> insert (f e1)
where
let rec insert = function
| Let(yt, e3, e4) -> Let(yt, e3, insert e4)
| LetRec(fundefs, e) -> LetRec(fundefs, insert e)
| LetTuple(yts, z, e) -> LetTuple(yts, z, insert e)
| e -> Let(xt, e, f e2) in
(* assoc_let_p*)
let x =
let y = 1 in
let z = 2 in
y + z in
x
(* alpha assoc_let_p *)
Let (Ti1_2,
Let (x_3,
Let (y_4, 1,
Let (z_5, 2, Add (y_4, z_5))),
x.3), ...)
(* assoc assoc_let_p *)
Let (y_9, 1,
Let (z_10, 2,
Let (x_8, Add (y_9, z_10),
Let (Ti6_7, x_8, ...))))
(* assoc_letrec_p *)
let x =
let rec f x = x + 1 in
f 1 in
x
(* alpha assoc_letrec_p *)
Let (Ti3_4,
Let (x_5,
LetRec
({name = f_6; args = [x_7];
body = Let (Ti2_9, 1, Add (x_7, Ti2_9))},
Let (Ti1_8, 1, App (f_6, [Ti1_8]))),
Var x_5), ...)
(* assoc assoc_letrec_p *)
LetRec
({name = f_15; args = [x_16];
body = Let (Ti11_18, 1, Add (x_16, Ti11_18))},
Let (Ti10_17, 1,
Let (x_14, App (f_15, [Ti10_17]),
Let (Ti12_13, x_14, ...))))
let x = (1, 2) in (* assoc_tuple_p *)
let (a, b) = x
in a + b
Let (Ti3_4, (* alpha assoc_tuple_p *)
Let (x_5,
Let (Ti1_8, 1,
Let (Ti2_9, 2, Tuple [Ti1_8; Ti2_9])),
LetTuple ([a_6; b_7], x_5, Add (a_6, b_7))), ...)
Let (Ti10_17, 1, (* assoc assoc_tuple_p *)
Let (Ti11_18, 2,
Let (x_14,
Tuple [Ti10_17; Ti11_18],
LetTuple ([a_15; b_16], x_14,
Let (Ti12_13, Add (a_15, b_16), ...)))))
For a definition of smaller functions:
Iε(let rec x y1…yn=e1 in e2)=let rec x y1…yn=Iε′(e1) in Iε′(e2)where ε′=ε,x↦((y1,…,yn),e1)
What’s α-conversion for? What kind of problems we will see if α-conversion were not applied? Find Min-Caml programs that give incorrect answers in absence of proper α-conversion.
Are optimization modules interdependent? Yes, but in what way? Find a pair of optimization modules A and B such that for a program P, B is effective when it is applied after A:
∃P.B(P)=P but B(A(P))≠A(P)
and maybe one more, thinking…