Solution

Published on June 2016 | Categories: Documents | Downloads: 37 | Comments: 0 | Views: 420
of 11
Download PDF   Embed   Report

Comments

Content

Midterm Exam
CS 320, Spring 2012 Student id: Name:

Instructions: You have 120 minutes to complete this closed-book, closed-note, closed-computer exam. Please write all answers in the provided space. You’re free to write your answers in Korean. 1) (10pts) Given the following expression in the FWAE language:

{with {g {fun {x} {f x}}} {with {f {fun {z} {g z}}} {with {y {with {f {fun {x} {f x}}} {f {- y m}}}} {y n}}}}
a) Draw arrows on the above expression from each bound variable to its binding occurrence. b) List the names of free variables: f, m, n, y

and bound variables: f, g, x, y, z

2) (5pts) Which of the following are examples of shadowing? a) {with {’x 8} {with {’x 7} {+ 1 ’x}}} b) {with {’x {with {’x 42} {- 11 ’x}}} {+ 9 ’x}} c) {with {’x 2} {with {’y 4} {+ 21 ’x}}}

3) (5pts) Rewrite the following FWAE code in FAE, that is, rewrite it without using with: {with {y {fun {x} {+ y x}}} {fun {z} {y {- 10 z}}}} {{fun {y} {fun {z} {y {- 10 z}}}} {fun {x} {+ y x}}}

1

4) (10pts) The following code (Let’s call this A):

(let ([fac (lambda (n) (let ([facX (lambda (facX) (lambda (n) (if (zero? n) 1 (* n ((facX facX) (- n 1))))))]) ((facX facX) n)))]) (fac 10))
can be rewritten as follows (Let’s call this B):

(let ([fac (let ([facX (lambda (facX) (lambda (n) (if (zero? n) 1 (* n ((facX facX) (- n 1))))))]) (facX facX))]) (fac 10))
via η reduction. Note that in A, 10 is passed to n in the outermost lambda expression. Explain that in B, how 10 is passed to n in the innermost lambda expression. First, the value of the outermost factX is a function value which takes a function and produces another function. Then, the value of fac is the value of (facX facX), which evaluates to a function value which takes a number and produces another number. Finally, (fac 10) passes 10 to the function which takes a number n.

5) (10pts) The following code is a partial implementation of the interpreter for RCFAE. Fill in the missing expressions. Note that DefrdSub is extended with a new kind of substitution aRecSub for recursion:

; interp : RCFAE DefrdSub -> RCFAE-Value (define (interp rcfae ds) (type-case RCFAE rcfae ... [rec (f fun-expr body) (local [(define value-holder (box (numV 42))) (define new-ds (aRecSub f value-holder ds))] (begin (set-box! value-holder (interp fun-expr new-ds)) (interp body new-ds)))]))
6) (5pts) Which of the following produce different results in an eager language and a lazy language? Both produce the same result if they both produce the same number, they both produce a procedure (even if the procedure doesn’t behave exactly the same when applied), or they both produce an error. Show the results of each expression in an eager language and a lazy language, and mark it when it produces different results in an eager language and a lazy language.

a) {{fun {y} 12} {1 2}} eager: error lazy: 12

b) {fun {x} {{fun {y} 12} {1 2}}} eager: closure c) {+ 1 {fun {y} 12}} eager: error lazy: error lazy: closure

d) {+ 1 {{fun {x} {+ 1 13}} {+ 1 {fun {z} 12}}}} eager: error lazy: 15

e) {+ 1 {{fun {x} {+ x 13}} {+ 1 {fun {z} 12}}}} eager: error lazy: error

7) (5pts) In our implementation of the interpreter for LFAE, we call the strict function to enforce evaluation. Where did we call the strict function in our implementation? If we instead call the strict function when we look up identifiers, what difference would it make? – When we evaluate addition and subtraction in num-op and when we evaluate the first expression of an app case in interp. – When a function body returns an identifier, our implementation would return exprV but calling the strict function at identifier look ups would not return exprV.

8) (10pts) Note that there is a nested strict call in the following:

; strict : LFAE-Value -> LFAE-Value (define (strict v) (type-case LFAE-Value v [exprV (expr ds) (strict (interp expr ds))] [else v]))
Write an example showing the need for the nested strict call.

{{fun {y} {{fun {x} {+ 3 x}} y}} 5}

9) (10pts) The following strict code results in redundant evaluations:

; strict : LFAE-Value -> LFAE-Value (define (strict v) (type-case LFAE-Value v [exprV (expr ds) (strict (interp expr ds))] [else v]))
Instead, we cache strict results using the following data structure:

(define-type LFAE-Value [numV (n number?)] [closureV (param symbol?) (body LFAE?) (ds DefrdSub?)] [exprV (expr LFAE?) (ds DefrdSub?) (value (box/c (or/c false LFAE-Value?)))])
Rewrite the above strict code using cached strict results.

(define (strict v) (type-case LFAE-Value v [exprV (expr ds v-box) (if (not (unbox v-box)) (local [(define v (strict (interp expr ds)))] (begin (set-box! v-box v) v)) (unbox v-box))] [else v]))

10) (10pts) The following code is an excerpt from the implementation of the interpreter for BFAE:

(define (interp expr ds st) ... [app (f a) (interp-two f a ds st (lambda (fv av st1) (interp (closureV-body fv) (aSub (closureV-param fv) av (closureV-ds fv)) st1)))] ...)
In BMFAE, we introduce variables so that DefrdSub maps names (symbols) to addresses (integers) and Store maps addresses (integers) to values (BMFAE-Value). Rewrite the above app case for BMFAE.

[app (f a) (interp-two f a ds st (lambda (fv av st1) (local [(define a (malloc st1))] (interp (closureV-body fv) (aSub (closureV-param fv) a (closureV-ds fv)) (aSto a av st1)))))]

11) (20pts) Given the following expression: {{fun {x} {seqn {setbox x 2} {openbox x}}} {newbox 11}} write out the arguments to and results of interp each time it is called during the evaluation of a program. Write them out in the order in which the calls to interp occur during evaluation. Write down the arguments and the results using the {} notation, not using the more verbose data constructors. Also, use an arrow notation for both the store and the environment. An example, if the first call to interp were: (interp (parse ‘{+ x y}) (aSub ’x (numV 3) (aSub ’y (numV 4) (mtSub))) (mtSto)) then a model solution would be: exp: env: sto: ans: exp: env: sto: ans: exp: env: sto: ans: {+ x y} {x -> (numV 3), y -> (numV 4)} {} (numV 7) {} x {x -> (numV 3), y -> (numV 4)} {} (numV 3) {} y {x -> (numV 3), y -> (numV 4)} {} (numV 4) {}

Note that the environment and store read in order from left to right. (1) exp: env: sto: ans: (2) exp: env: sto: ans: (3) exp: env: sto: ans: {{fun {x} {seqn {setbox x 2} {openbox x}}} {newbox 11}} {} {} (numV 2) {0 -> (numV 2), 0 -> (numV 11)}

{fun {x} {seqn {setbox x 2} {openbox x}}} {} {} (closureV ’x {seqn {setbox x 2} {openbox x}} {}) {}

{newbox 11} {} {} (boxV 0) {0 -> (numV 11)}

(4) exp: env: sto: ans: (5) exp: env: sto: ans: (6) exp: env: sto: ans: (7) exp: env: sto: ans: (8) exp: env: sto: ans: (9) exp: env: sto: ans: (10) exp: env: sto: ans:

11 {} {} (numV 11) {}

{seqn {x -> {0 -> (numV

{setbox x 2} {openbox x}} (boxV 0)} (numV 11)} 2) {0 -> (numV 2), 0 -> (numV 11)}

{setbox x 2} {x -> (boxV 0)} {0 -> (numV 11)} (numV 2) {0 -> (numV 2), 0 -> (numV 11)}

x {x -> (boxV 0)} {0 -> (numV 11)} (boxV 0) {0 -> (numV 11)}

2 {x -> (boxV 0)} {0 -> (numV 11)} (numV 2) {0 -> (numV 11)}

{openbox x} {x -> (boxV 0)} {0 -> (numV 2), 0 -> (numV 11)} (numV 2) {0 -> (numV 2), 0 -> (numV 11)}

x {x -> (boxV 0)} {0 -> (numV 2), 0 -> (numV 11)} (boxV 0) {0 -> (numV 2), 0 -> (numV 11)}

#lang plai (define-type BFAE [num (n number?)] [add (lhs BFAE?) (rhs BFAE?)] [sub (lhs BFAE?) (rhs BFAE?)] [id (name symbol?)] [fun (param symbol?) (body BFAE?)] [app (fun-expr BFAE?) (arg-expr BFAE?)] [newbox (val-expr BFAE?)] [setbox (box-expr BFAE?) (val-expr BFAE?)] [openbox (box-expr BFAE?)] [seqn (first BFAE?) (second BFAE?)]) (define-type BFAE-Value [numV (n number?)] [closureV (param symbol?) (body BFAE?) (ds DefrdSub?)] [boxV (address integer?)]) (define-type DefrdSub [mtSub] [aSub (name symbol?) (value BFAE-Value?) (rest DefrdSub?)]) (define-type Store [mtSto] [aSto (address integer?) (value BFAE-Value?) (rest Store?)]) (define-type Value*Store [v*s (value BFAE-Value?) (store Store?)]) ;; ------------------------------------------------------------;; parse : S-expr -> BFAE (define (parse sexp) (cond [(number? sexp) (num sexp)] [(symbol? sexp) (id sexp)] [(pair? sexp) (case (car sexp) [(+) (add (parse (second sexp)) (parse (third sexp)))] [(-) (sub (parse (second sexp)) (parse (third sexp)))] [(fun) (fun (first (second sexp)) (parse (third sexp)))] [(newbox) (newbox (parse (second sexp)))] [(setbox) (setbox (parse (second sexp)) (parse (third sexp)))] [(openbox) (openbox (parse (second sexp)))] [(seqn) (seqn (parse (second sexp)) (parse (third sexp)))] [else (app (parse (first sexp)) (parse (second sexp)))])]))

;; ------------------------------------------------------------;; interp : BFAE DefrdSub Store -> Value*Store (define (interp bcfae ds st) (type-case BFAE bcfae [num (n) (v*s (numV n) st)] [add (l r) (interp-two l r ds st (lambda (v1 v2 st1) (v*s (num+ v1 v2) st1)))] [sub (l r) (interp-two l r ds st (lambda (v1 v2 st1) (v*s (num- v1 v2) st1)))] [id (name) (v*s (lookup name ds) st)] [fun (param body-expr) (v*s (closureV param body-expr ds) st)] [app (fun-expr arg-expr) (interp-two fun-expr arg-expr ds st (lambda (fun-val arg-val st1) (interp (closureV-body fun-val) (aSub (closureV-param fun-val) arg-val (closureV-ds fun-val)) st1)))] [newbox (expr) (type-case Value*Store (interp expr ds st) [v*s (val st1) (local [(define a (malloc st1))] (v*s (boxV a) (aSto a val st1)))])] [setbox (bx-expr val-expr) (interp-two bx-expr val-expr ds st (lambda (bx-val val st1) (v*s val (aSto (boxV-address bx-val) val st1))))] [openbox (bx-expr) (type-case Value*Store (interp bx-expr ds st) [v*s (bx-val st1) (v*s (store-lookup (boxV-address bx-val) st1) st1)])] [seqn (a b) (interp-two a b ds st (lambda (v1 v2 st1) (v*s v2 st1)))])) ;; interp-two : BFAE BFAE DefrdSub Store (Value Value Store -> Value*Store ;; -> Value*Store (define (interp-two expr1 expr2 ds st handle) (type-case Value*Store (interp expr1 ds st) [v*s (val1 st2) (type-case Value*Store (interp expr2 ds st2) [v*s (val2 st3) (handle val1 val2 st3)])]))

;; num-op : (number number -> number) -> (BFAE-Value BFAE-Value -> BFAE-Value) (define (num-op op x y) (numV (op (numV-n x) (numV-n y)))) (define (num+ x y) (num-op + x y)) (define (num- x y) (num-op - x y)) ;; malloc : Store -> integer (define (malloc store) (type-case Store store [mtSto () 0] [aSto (addr val rest) (+ addr 1)])) ;; lookup : symbol DefrdSub -> BFAE-Value (define (lookup name ds) (type-case DefrdSub ds [mtSub () (error ’lookup "free variable")] [aSub (sub-name val rest-ds) (if (symbol=? sub-name name) val (lookup name rest-ds))])) ;; store-lookup : number Store -> BFAE-Value (define (store-lookup addr st) (type-case Store st [mtSto () (error ’store-lookup "unallocated")] [aSto (sto-addr val rest-st) (if (= addr sto-addr) val (store-lookup addr rest-st))]))

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close