tim sheard oregon graduate institute lecture 5: review of homework 2 cs510 sect fsc winter 2004...

31
Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC CS510 Sect FSC Winter 2004 Winter 2004

Post on 21-Dec-2015

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

Tim SheardOregon Graduate Institute

Lecture 5: Review of homework 2

CS510 Sect FSCCS510 Sect FSC

Winter 2004Winter 2004

Page 2: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

2Cse583 Winterl 2002

Discussion of homework 2We haveadd : int -> int -> int

mult : int -> int -> int

member : ['a=].'a list -> 'a -> bool

dotprod : int -> int list -> int list -> int

We wantadd' : int -> <int> -> <int>

mult' : int -> <int -> int>

member' : 'a list -> <'a> -> <bool>

dotprod' int -> int list -> <int list -> int>

Page 3: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

3Cse583 Winterl 2002

Add

Have: add : int -> int -> int

Want: add' : int -> <int> -> <int>

fun add 0 y = y

| add n y = 1 + (add (n-1) y);

fun add' 0 y = y

| add' n y = < 1 + ~(add' (n-1) y)>;

Example-| add' 3 <2>;

val it = <1 %+ 1 %+ 1 %+ 2> : <int>

Page 4: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

4Cse583 Winterl 2002

mult Have: mult : int -> int -> int Want: mult' : int -> <int -> int>

fun mult 0 y = 0

| mult n y = y + (mult (n-1) y);

fun mult' 0 = <fn y => 0>

| mult' n = <fn y => y + ~(mult' (n-1)) y>;

Note type of result <int ->

int>

Page 5: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

5Cse583 Winterl 2002

Unfold mult’ by hand(mult’ 2) =

<fn y => y + ~(mult’ 1) y> =

<fn y => y + ~(<fn z => z + ~(mult’ 0) z>) y> =

<fn y => y + ~(<fn z => z + ~(<fn x => 0>) z>) y> = Note the alpha renaming of y,z,x

<fn y => y + ~(<fn z => z + (fn x => 0) z>) y> Using the bracket escape cancel law

<fn y => y + (fn z => z + (fn x => 0) z) y>

Why is it then, that when I type mult’ 2 into MetaML I get the following?

-| mult' 2;

val it = <(fn a => a %+ a %+ 0)> : <int -> int>

Page 6: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

6Cse583 Winterl 2002

Safe beta at work!

-| feature 1;

Safe-beta is off.

val it = false : bool

-| mult' 2 ;

val it =

<(fn a => a %+ ((fn b => b %+ ((fn c => 0)) b)) a)>

: <int -> int>

With safe-beta turned off we get the expected answer.Note how much uglier the expected answer isWhat property makes safe-beta applicable?

Page 7: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

7Cse583 Winterl 2002

memberHave: member : 'a list -> 'a -> boolWant: member' : 'a list -> <'a> -> <bool>

fun member [] x = false

| member (y::ys) x =

if x=y then true else member ys x;

fun member' [] x = <false>

| member' (y::ys) x =

<if ~x = y then true

else ~(member' ys x)>;

Page 8: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

8Cse583 Winterl 2002

Example: member-| member' [2,3] <9>;

val it =

<if 9 %= %y then true

else if 9 %= %y then true

else false>

: <bool>

Why do we have %y in the result?How can we fix this aesthetic problem? (hint use: lift)

Can we make the last nested if if 9 %= %y then true else false

Be replaced by just (9 %= %y) (hint make a special case for lists of length 1)

Page 9: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

9Cse583 Winterl 2002

member’ againfun member' [] x = <false>

| member' [y] x = <~x = ~(lift y)>

| member' (y::ys) x =

<if ~x = ~(lift y)

then true

else ~(member' ys x)>;

-| member' [2,3] <9>;

val it = <if 9 %= 2 then true else 9 %= 3>

: <bool>

Page 10: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

10Cse583 Winterl 2002

dotprodHave: dotprod : int -> int list -> int list -> int Want: dotprod’ : int -> int list -> <int list -> int>

fun dotprod 0 xs ys = 0

| dotprod n (x::xs) (y::ys) =

(x * y) + (dotprod (n-1) xs ys)

The function nth will come in handyfun nth 0 (x::xs) = x

| nth n (x::xs) = nth (n-1) xs;

Page 11: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

11Cse583 Winterl 2002

Dotprod (continued)

fun help 0 next xs = <fn y => 0>

| help n next (x::xs) =

<fn ys => ( ~(lift x) * (nth ~(lift next) ys) )

+ ~(help (n-1) (next+1) xs) ys>;

fun dotprod' n xs = help n 0 xs;

Example:

-| dotprod' 3 [0,1,2];

val it =

<fn a => (0 %* %nth 0 a) %+ (1 %* %nth 1 a)

%+ (2 %* %nth 2 a) %+ 0)> : <int list -> int>

Page 12: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

12Cse583 Winterl 2002

Can we do without nth ?We canfun dotprod' 0 xs = <fn ys => 0> | dotprod' n (x::xs) = <fn (y::ys) => ( ~(lift x) * y ) + ~(dotprod' (n-1) xs) ys>;

But-| dotprod' 3 [0,1,2];val it = <(fn (b::a) => 0 %* b %+ ((fn (d::c) => 1 %* d %+ ((fn (f::e) => 2 %* f %+ 0)) c)) a)> : <int list -> int>

Safe-Beta doesn’t apply!

Page 13: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

13Cse583 Winterl 2002

Applying optimizations-| dotprod' 3 [0,1,2];

val it =

<(fn a => (0 %* %nth 0 a) %+

(1 %* %nth 1 a) %+

(2 %* %nth 2 a) %+ 0)>

Rules 1*x = x 0*x = 0 x+0 = x

<fn a => 0 %+

(%nth 1 a) %+

(2 %* %nth 2 a)>

Page 14: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

14Cse583 Winterl 2002

StrategyThe rules 1*x = x 0*x = 0

Can be applied by writing staged versions of multiply ( * ) mult : int -> <int> -> <int>

The Rule x+0 = x

Can be applied by writing a special case for lists of length 1. (We’ve seen this one before)

Page 15: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

15Cse583 Winterl 2002

Codefun mult 0 x = <0>

| mult 1 x = x

| mult y x = < ~(lift y) * ~x >;

fun help 0 next xs = <fn y => 0>

| help 1 next [x] =

<fn ys => ~(mult x <nth ~(lift next) ys>)>

| help n next (x::xs) =

<fn ys => ~(mult x <nth ~(lift next) ys>) +

~(help (n-1) (next+1) xs) ys>;

fun dotprod' n xs = help n 0 xs;

Page 16: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

16Cse583 Winterl 2002

Example-| dotprod' 3 [0,1,2];

val it =

<fn a => 0 %+ (%nth 1 a) %+ 2 %* (%nth 2 a)>

: <int list -> int>

How do we get rid of the last (0 + …) A analysis version of addition ( + ) add : <int> -> <int> -> <int>

fun add <0> x = x

| add n x = < ~n + ~x >;

Page 17: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

17Cse583 Winterl 2002

Final version of dotprod’

fun help 0 next xs = <fn y => 0>

| help 1 next [x] =

<fn ys => ~(mult x <nth ~(lift next) ys>)>

| help n next (x::xs) =

<fn ys => ~(add (mult x <nth ~(lift next) ys>)

<~ (help (n-1) (next+1) xs) ys> )>;

fun dotprod' n xs = help n 0 xs;

-| dotprod' 3 [0,1,2];

val it = <fn a => (%nth 1 a) %+ (2 %* %nth 2 a)>

: <int list -> int>

Page 18: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

18Cse583 Winterl 2002

3 stage dot-prodfun nth (x::xs) 1 = x | nth (x::xs) n = nth xs (n-1);

(* iprod : int -> Vector -> Vector -> int *)fun iprod n v w = if n '>' 0 then ((nth v n) * (nth w n)) + (iprod (n-1) v w) else 0;

(* iprod2 : int -> <Vector -> <Vector -> int>> *)fun iprod2 n = <fn v => <fn w => ~(~(if n '>' 0 then << (~(lift (nth v n)) * (nth w n)) + (~(~(iprod2 (n-1)) v) w) >> else <<0>>)) >>;

Page 19: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

19Cse583 Winterl 2002

Results of staging-| val f1 = iprod2 3; (* Results from stage 1 *)val f1 = <(fn a => <(fn b => ~(%lift (%nth a %n)) %* (%nth b %n) %+ ~(%lift (%nth a %n)) %* (%nth b %n) %+ ~(%lift (%nth a %n)) %* (%nth b %n) %+ 0)>)> : <int list -> <int list -> int>>

-| val f2 = (run f1) [1,0,4]; (* Results stage 2 *)val f2 = <(fn a => (4 %* (%nth a %n)) %+ (0 %* (%nth a %n)) %+ (1 %* (%nth a %n)) %+ 0)> : <int list -> int>

Page 20: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

20Cse583 Winterl 2002

Generator vs TransformerThe function iprod2 is written in generator form

iprod2 : int -> <Vector -> <Vector -> int>>

fun iprod2 n = <fn v => <fn w =>

~(~(if n '>' 0

then << (~(lift (nth v n)) * (nth w n)) +

(~(~(iprod2 (n-1)) v) w)

>>

else <<0>>)) >>;

Also possible to write as Transformer p3 : int -> <Vector> -> <<Vector>> -> <<int>>

fun p3 n v w =

if n '>' 0

then << (~(lift (nth ~v n)) * (nth ~ ~w n)) +

~ ~(p3 (n-1) v w) >>

else <<0>>;

Page 21: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

21Cse583 Winterl 2002

From 3-level transformer to generator

fun back2 f = <fn x => <fn y => ~ ~(f <x> <<y>>)>>;fun iprod3 n = back2 (p3 n);

val f3 = iprod3 3; (* Results from stage 1 *)<(fn a => <(fn b => ~(%lift (%nth a %n)) %* %nth b %n %+ ~(%lift (%nth a %n)) %* %nth b %n %+ ~(%lift (%nth a %n)) %* %nth b %n %+ 0)>)>

val f4 = (run f3) [1,0,4]; (* Results stage 2 *)<fn a => (4 %* %nth a %n) %+ (0 %* %nth a %n) %+ (1 %* %nth a %n) %+ 0>

Page 22: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

22Cse583 Winterl 2002

Optimizing 3-stages

First write staged arithmetic functions

fun add' <0> y = y

| add' x <0> = x

| add' x y = < ~x + ~y >;

fun mult' 0 y = <0>

| mult' 1 y = y

| mult' x y = <~(lift x) * ~y>;

Page 23: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

23Cse583 Winterl 2002

Next use them in 3 level code

fun p4 n v w =

if n '>' 0

then <add' < ~(mult' (nth ~v n)

<(nth ~ ~w n)>) >

~(p4 (n-1) v w) >

else <<0>>;

fun iprod4 n = back2 (p4 n);

Page 24: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

24Cse583 Winterl 2002

Resultsval f1 = iprod4 3; (* Results from stage 1 *)-| val f1 =

<(fn a =>

<(fn b =>

~(%add' (<~%mult' (%nth a %n) (<%nth b %n>)>)

(%add' (<~%mult' (%nth a %n) (<%nth b %n>)>)

(%add' (<~%mult' (%nth a %n) (<%nth b %n>)>)

(<0>)))))>)>

val f2 = (run f1) [1,0,4]; (* Results stage 2 *)

-| val f2 =

<fn a => 4 %* (%nth a %n) %+ (%nth a %n)>

Note the calls to add’ and mult’ are escaped to run when the first

generator generates the second generator.

Page 25: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

25Cse583 Winterl 2002

3 stage dot-prodfun nth (x::xs) 1 = x | nth (x::xs) n = nth xs (n-1);

(* iprod : int -> Vector -> Vector -> int *)fun iprod n v w = if n '>' 0 then ((nth v n) * (nth w n)) + (iprod (n-1) v w) else 0;

(* iprod2 : int -> <Vector -> <Vector -> int>> *)fun iprod2 n = <fn v => <fn w => ~(~(if n '>' 0 then << (~(lift (nth v n)) * (nth w n)) + (~(~(iprod2 (n-1)) v) w) >> else <<0>>)) >>;

Page 26: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

26Cse583 Winterl 2002

Results of staging-| val f1 = iprod2 3; (* Results from stage 1 *)val f1 = <(fn a => <(fn b => ~(%lift (%nth a %n)) %* (%nth b %n) %+ ~(%lift (%nth a %n)) %* (%nth b %n) %+ ~(%lift (%nth a %n)) %* (%nth b %n) %+ 0)>)> : <int list -> <int list -> int>>

-| val f2 = (run f1) [1,0,4]; (* Results stage 2 *)val f2 = <(fn a => (4 %* (%nth a %n)) %+ (0 %* (%nth a %n)) %+ (1 %* (%nth a %n)) %+ 0)> : <int list -> int>

Page 27: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

27Cse583 Winterl 2002

Generator vs TransformerThe function iprod2 is written in generator form

iprod2 : int -> <Vector -> <Vector -> int>>

fun iprod2 n = <fn v => <fn w =>

~(~(if n '>' 0

then << (~(lift (nth v n)) * (nth w n)) +

(~(~(iprod2 (n-1)) v) w)

>>

else <<0>>)) >>;

Also possible to write as Transformer p3 : int -> <Vector> -> <<Vector>> -> <<int>>

fun p3 n v w =

if n '>' 0

then << (~(lift (nth ~v n)) * (nth ~ ~w n)) +

~ ~(p3 (n-1) v w) >>

else <<0>>;

Page 28: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

28Cse583 Winterl 2002

From 3-level transformer to generator

fun back2 f = <fn x => <fn y => ~ ~(f <x> <<y>>)>>;fun iprod3 n = back2 (p3 n);

val f3 = iprod3 3; (* Results from stage 1 *)<(fn a => <(fn b => ~(%lift (%nth a %n)) %* %nth b %n %+ ~(%lift (%nth a %n)) %* %nth b %n %+ ~(%lift (%nth a %n)) %* %nth b %n %+ 0)>)>

val f4 = (run f3) [1,0,4]; (* Results stage 2 *)<fn a => (4 %* %nth a %n) %+ (0 %* %nth a %n) %+ (1 %* %nth a %n) %+ 0>

Page 29: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

29Cse583 Winterl 2002

Optimizing 3-stages(* add : int -> int -> <Vector> -> <int> *)

fun add i x y e =

if x=0

then e

else if x=1

then <(nth ~y ~(lift i)) + ~e>

else <(~(lift x) * (nth ~y ~(lift i))) + ~e>;

(* p3 : int -> <Vector> -> <<Vector>> -> <<int>> *)

fun p3 n v w =

if n = 1

then << ~(add n (nth ~v n) ~w <0>) >>

else << ~(add n (nth ~v n) ~w

< ~ ~(p3 (n-1) v w) >) >>;

Page 30: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

30Cse583 Winterl 2002

Resultsfun iprod3 n = back2 (p3 n);

val f3 = iprod3 3;

val f4 = (run f3) [1,0,4];

val f4 =

<(fn a => 4 %* %nth a 3 %+ %nth a 1 %+ 0)>

: <int list -> int>

Page 31: Tim Sheard Oregon Graduate Institute Lecture 5: Review of homework 2 CS510 Sect FSC Winter 2004 Winter 2004

31Cse583 Winterl 2002

Review Using lift where appropriateThe use of helper functionsTransformers vs generatorsSpecial case for static lists of length 1Staged versions of binary operators where one of the arguments is static, often allow special “rules” to be appliedWhen will the “safe” object level equations like safe-beta, safe-eta, and let-lifting apply?