tim sheard oregon graduate institute lecture 8: operational semantics of metaml cse 510 section fsc...

Post on 14-Dec-2015

219 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

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

top related