tim sheard oregon graduate institute lecture 8: operational semantics of metaml cse 510 section fsc...
TRANSCRIPT
Tim SheardOregon Graduate Institute
Lecture 8: Operational Semantics of MetaML
CSE 510 Section FSCCSE 510 Section FSC
Winter 2005Winter 2005
2Cse583 Winter 2002
AssignmentsReading Assignment A Methodology for Generating Verified Combin
atorial Circuits.
By Kiseyov, Swadi, and Taha. Available on the readings page of the course
web-site
Homework # 5 assigned Tuesday Feb. 1, 2005 due in class Tuesday Feb. 8, 2005 Details on the assignment page of the course
web-site.
3Cse583 Winter 2002
Map of today’s lecture
Thanks to Walid Taha. Todays lecture comes from chapter 4 of his thesis Simple interpreter for lambda calculus Addition of constants for
Operators If-then-else over integer Y combinator
Add staging annotations Fix up environment mess
4Cse583 Winter 2002
Terms and Valuesdatatype exp =
EI of int (* integers *)
| EA of exp * exp (* applications *)
| EL of string * exp (* lambda-abs *)
| EV of string; (* variables *)
datatype value =
VI of int
| VF of (value -> value);
5Cse583 Winter 2002
Example terms
val ID = EL("x",EV "x");
val COMPOSE =
EL("f",
EL("g",
EL("x",EA(EV "f",
EA(EV "g",EV "x")))));
fn x => x
fn f => fn g => fn x => f(g x)
6Cse583 Winter 2002
Example Valuesval id = VF(fn x => x);
val compose =
VF(fn (VF f) =>
VF (fn (VF g) =>
VF(fn x => f(g x))));
val square = VF (fn (VI x) => VI(x * x));
val bang =
let fun fact n = if n=0 then 1 else n*(fact (n-1))
in VF (fn (VI x) => VI(fact x)) end;
Note how “primitive”
functions can be implemented
7Cse583 Winter 2002
An interpreter
The interpreter ev0 : (string -> value) -> exp -> value
Environmentstype env =string -> value;
exception NotBound of string
val env0 =
fn x => (print x; raise (NotBound x));
fun ext env x v =
(fn y => if x=y then v else env y);
8Cse583 Winter 2002
Semantics in 8 linesfun ev0 env e =
case e of
EI i => VI i
| EA(e1,e2) => (case (ev0 env e1,ev0 env e2) of
(VF f,v) => f v)
| EL(x,e1) => VF(fn v => ev0 (ext env x v) e1)
| EV x => env x;
-| val ex1 = ev0 env0 (EA(ID,EI 5));
val ex1 = VI 5 : value
9Cse583 Winter 2002
Printing Terms
fun showe e =
case e of
EI n => show n
| EA(f,x as EA(_,_)) =>
(showe f)^" ("^(showe x)^")"
| EA(f,x) => (showe f)^" "^(showe x)
| EL(x,e) => "(fn "^x^" => "^(showe e)^")"
| EV x => x
10Cse583 Winter 2002
Making it usefulThe interpreter is good for the lambda calculus with integer constants, but we have no operations on integers
Need to add primitive operations Arithmetic Case analysis over integers Recursion over integers
This is accomplished by adding an initial environment with values for some constants
11Cse583 Winter 2002
Arithmeticval plus =
VF(fn (VI x) => VF(fn (VI y) => VI(x+y)));
val minus =
VF(fn (VI x) => VF(fn (VI y) => VI(x-y)));
val times =
VF(fn (VI x) => VF(fn (VI y) => VI(x*y)));
val env1 = ext env0 "*" times;
val SQUARE = EL("x",EA(EA(EV "*",EV "x"),EV "x"));
-| val ex2 = ev0 env1 (EA (SQUARE,EI 5));
val ex2 = VI 25 : value
12Cse583 Winter 2002
If-zero functionfun Z n tf ff = if n=0 then tf 0 else ff n;
val Z : int -> (int -> 'a ) -> (int -> 'a ) -> 'a
val ifzero =
VF(fn (VI n) =>
VF(fn (VF tf) =>
VF(fn (VF ff) => if n=0 then tf(VI 0) else ff(VI n))));
13Cse583 Winter 2002
Recursionfun Y f = f (fn v => (Y f) v);
Y : (('b -> 'a ) -> 'b -> 'a ) -> 'b -> 'a
val recur =
let fun recur' (VF f) =
f(VF (fn v=>
(case (recur' (VF f)) of
VF fp => fp v
| w => error “not function“ )))
in VF recur' end;
14Cse583 Winter 2002
New initial environmentval env1 =
ext(ext(ext(ext(ext env0 "+" plus)
"-" minus)
"*" times)
"Z" ifzero)
"Y" recur;
15Cse583 Winter 2002
Using the constants
Start with a recursive function in MLTransform it removing ML features
Example function
fun h1 n z =
if n=0
then z
else (fn x => (h1 (n-1) (x+z))) n;
16Cse583 Winter 2002
Steps
Remove recursion by using Yval h1 =
Y(fn h1' => fn n => fn z =>
if n=0 then z
else (fn x => (h1' (n-1) (x+z))) n);
Remove ifval h1 =
Y(fn h1' => fn n => fn z =>
Z n (fn _ => z)
(fn n => (fn x => (h1' (n-1) (x+z))) n));
17Cse583 Winter 2002
Make a termfun minus x y = EA(EA(EV "-",x),y);
fun plus x y = EA(EA(EV "+",x),y);
val H1 =
EA(EV "Y",EL("h1",EL("n",EL("z",
EA(EA(EA(EV "Z",EV "n")
,EL("w",EV "z"))
,EL("n",EA(EL("x",EA(EA(EV "h1",
minus (EV "n") (EI 1))
,plus (EV "x") (EV "z")))
,EV "n")))))));
18Cse583 Winter 2002
What does it look like?-| print(showe H1);
Y (fn h1 =>
(fn n =>
(fn z =>
Z n (fn w => z)
(fn n =>
(fn x => h1 (- n 1)(+ x z))
n))))
19Cse583 Winter 2002
Running it
-| val IT = EA(EA(H1,EI 3),EI 4);
-| val answer = ev0 env1 IT;
val answer = VI 10 : value
20Cse583 Winter 2002
Adding Staging
What are the new kinds of values Code Represented as embedding exp in value
What are the new kinds of terms Brackets Escapes Run Cross stage persistent constants
21Cse583 Winter 2002
Terms and valuesdatatype value =
VI of int
| VF of (value -> value)
| VC of exp
and exp =
EI of int (* integers *)
| EA of exp * exp (* applications *)
| EL of string * exp (* lambda-abstractions *)
| EV of string (* variables *)
| EB of exp (* brackets *)
| ES of exp (* escape *)
| ER of exp (* run *) | EC of string * value; (* cross-stage constants *)
22Cse583 Winter 2002
Generalizing environmentstype env = string -> exp;
fun env0 x = EV x;
val env1 =
ext(ext(ext(ext(ext env0 "+" (EC("+",plus)))
"-" (EC("-",minus)))
"*" (EC("*",times)))
"Z" (EC("if",ifzero)))
"Y" (EC("Y",recur));
Note the initial values in the environment are cross-stage persistent Expressions. Other values will also be injected using EC
23Cse583 Winter 2002
Printing termsfun showe e =
case e of
EI n => show n
| EA(f,x as EA(_,_)) =>
(showe f)^" ("^(showe x)^")"
| EA(f,x) => (showe f)^" "^(showe x)
| EL(x,e) => "(fn "^x^" => "^(showe e)^")"
| EV x => x
| EB e => "<"^(showe e)^">"
| ES(EV x) => "~"^x
| ES e => "~("^(showe e)^")"
| ER e => "run("^(showe e)^")"
| EC(s,v) => "%"^s;
24Cse583 Winter 2002
Fresh Variablesval ctr = ref 0;
fun NextVar s =
let val _ = ctr := (!ctr) + 1
in s^(toString (! ctr)) end;
-| NextVar "x";
val it = "x1" : string
-| NextVar "x";
val it = "x2" : string
25Cse583 Winter 2002
The interpreterfun ev1 env e = case e of
EI i => VI i
| EA(e1,e2) =>
(case (ev1 env e1,ev1 env e2) of
(VF f,v) => f v)
| EL(x,e1) =>
VF(fn v => ev1 (ext env x (EC(x,v))) e1)
| EV x => (case env x of EC(_,v) => v | w => VC w)
| EB e1 => VC(eb1 1 env e1)
| ER e1 =>
(case ev1 env e1 of VC e2 => ev1 env0 e2)
| EC(_,v) => v
| ES e1 => error "escape at level 0"
26Cse583 Winter 2002
Rebuilding termsand eb1 n env e = case e of
EI i => EI i
| EA(e1,e2) => EA(eb1 n env e1,eb1 n env e2)
| EL(x,e1) =>
let val x' = NextVar x
in EL(x',eb1 n (ext env x (EV x')) e1) end
| EV y => env y
| EB e1 => EB(eb1 (n+1) env e1)
| ES e1 => if n=1
then (case ev1 env e1 of VC e => e)
else ES(eb1 (n-1) env e1)
| ER e1 => ER(eb1 n env e1)
| EC(s,v) => EC(s,v)
27Cse583 Winter 2002
Staging H1val H2 = let fun minus x y = EA(EA(EV "-",x),y)
fun plus x y = EA(EA(EV "+",x),y)
in EA(EV "Y",EL("h1",EL("n",EL("z",
EA(EA(EA(EV "Z",EV "n")
,EL("w",EV "z"))
,EL("n",EB(EA(EL("x",ES(EA(EA(EV "h1",
minus (EV "n")
(EI 1))
,EB(plus (EV "x")
(ES (EV "z"))))))
,EV "n"))))))))
end;
-| print(showe H2);
Y (fn h1 => (fn n => (fn z =>
Z n (fn w => z)
(fn n => <(fn x => ~(h1 (- n 1) <+ x ~z>)) n>))))
28Cse583 Winter 2002
Generating codeval VC answer = ev1 env1 IT;
-| val answer = EA (EL ("x7",
EA (EL ("x8",
EA (EL ("x9",
EA (EA (EC ("+",VF fn ),EV "x9"),
EA (EA (EC ("+",VF fn ),EV "x8"),
EA (EA (EC ("+",VF fn ),EV "x7"),EI 4)))),
EC ("n",VI 1))),
EC ("n",VI 2))),
EC ("n",VI 3))
-| showe answer;
val it =
"(fn x7 => (fn x8 => (fn x9 =>
%+ x9 (%+ x8 (%+ x7 4))) %n) %n) %n"
29Cse583 Winter 2002
A problem-| val puzzle =
run ((run <fn a =>
~( (fn x => <x>)
(fn w => <a>) )
5>)
3);
-| val puzzle = 3 : int
30Cse583 Winter 2002
In our language(* (fn x => <x>) *)
val t1 = EL("x",EB(EV "x"));
(* (fn w => <a>) *)
val t2 = EL("w",EB(EV "a"));
(* <fn a => ~( (fn x => <x>) (fn w => <a>) ) 5> *)
val t3 = EB(EL("a",EA(ES(EA(t1,t2)),EI 5)));
val puzzle = ER(EA(ER t3,EI 3));
-| showe puzzle;
val it =
"run(run(<(fn a => ~((fn x => <x>) (fn w => <a>)) 5)>) 3)“
31Cse583 Winter 2002
Running itrun(run(<(fn a => ~((fn x => <x>)
(fn w => <a>))
5)>)
3)“
-| ev1 env1 puzzle;
val it = VC EV "a14" : value
What’s gone wrong?
32Cse583 Winter 2002
Coversfun coverE env e =case e of EI i => EI i| EA(e1,e2) => EA(coverE env e1,coverE env e2)| EL(x,e1) => EL(x,coverE env e1)| EV y => env y| EB e1 => EB(coverE env e1)| ES e1 => ES(coverE env e1)| ER e1 => ER(coverE env e1)| EC(s,v) => EC(s,coverV env v)
and coverV env v =case v of VI i => VI i| VF f => VF((coverV env) o f)| VC e => VC(coverE env e);
33Cse583 Winter 2002
Final interpreterfun ev1 env e =
case e of
EI i => VI i
| EA(e1,e2) =>
(case (ev1 env e1,ev1 env e2) of (VF f,v) => f v)
| EL(x,e1) =>
VF(fn v => ev1 (ext env x (EC(x,v))) e1)
| EV x => (case env x of EC(_,v) => v | w => VC w)
| EB e1 => VC(eb1 1 env e1)
| ER e1 => (case ev1 env e1 of VC e2 => ev1 env0 e2)
| EC(s,v) => coverV env v
34Cse583 Winter 2002
Final rebuilderand eb1 n env e = case e of
EI i => EI i
| EA(e1,e2) => EA(eb1 n env e1,eb1 n env e2)
| EL(x,e1) =>
let val x' = NextVar x
in EL(x',eb1 n (ext env x (EV x')) e1) end
| EV y => env y
| EB e1 => EB(eb1 (n+1) env e1)
| ES e1 => if n=1
then (case ev1 env e1 of VC e => e)
else ES(eb1 (n-1) env e1)
| ER e1 => ER(eb1 n env e1)
| EC(s,v) => EC(s,coverV env v)
35Cse583 Winter 2002
Now it works
-| ev1 env1 puzzle;
val it = VI 3 : value