Similar documents
CS61A Midterm 2 Review (v1.1)


CS61A Summer 2010 George Wang, Jonathan Kotker, Seshadri Mahalingam, Eric Tzeng, Steven Tang

Announcements. The current topic: Scheme. Review: BST functions. Review: Representing trees in Scheme. Reminder: Lab 2 is due on Monday at 10:30 am.

Scheme Basics > (butfirst '(help!)) ()

This exam is worth 70 points, or about 23% of your total course grade. The exam contains 15 questions.

A Brief Introduction to Scheme (II)

Problem 1. Remove consecutive duplicates (6 points, 11 mintues)

Below are example solutions for each of the questions. These are not the only possible answers, but they are the most common ones.

Discussion 4. Data Abstraction and Sequences

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

STREAMS 10. Basics of Streams. Practice with Streams COMPUTER SCIENCE 61AS. 1. What is a stream?

Intro. Scheme Basics. scm> 5 5. scm>

CS61A Notes Disc 11: Streams Streaming Along

Write a procedure powerset which takes as its only argument a set S and returns the powerset of S.

CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal)

Sample midterm 1 #1. Problem 1 (What will Scheme print?).

6.001 Notes: Section 8.1

6.001 Notes: Section 15.1

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

CS 61A, Fall, 2002, Midterm #2, L. Rowe. 1. (10 points, 1 point each part) Consider the following five box-and-arrow diagrams.

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Remember, this question was mis-worded: you could also add quoted words and sentences in the blanks below. This allowed for a solution to [4] below.

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

University of Massachusetts Lowell

CS 61A Midterm #2 - October 5, 1998

CS3: Introduction to Symbolic Programming. Lecture 14: Lists.

CS61A Notes 02b Fake Plastic Trees. 2. (cons ((1 a) (2 o)) (3 g)) 3. (list ((1 a) (2 o)) (3 g)) 4. (append ((1 a) (2 o)) (3 g))

Discussion 11. Streams

YOUR NAME PLEASE: *** SOLUTIONS ***

6.001 Notes: Section 6.1

CS61A, Fall/1999 Midterm #1 Professor Brian Harvey

Scheme: Strings Scheme: I/O

Programming Project #4: A Logo Interpreter Summer 2005

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

cs61amt2_4 CS 61A Midterm #2 ver March 2, 1998 Exam version: A Your name login: cs61a- Discussion section number TA's name

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

CS 61A Discussion 8: Scheme. March 23, 2017

mk-convert Contents 1 Converting to minikanren, quasimatically. 08 July 2014

CS450 - Structure of Higher Level Languages

Structure and Interpretation of Computer Programs

Why do we need an interpreter? SICP Interpretation part 1. Role of each part of the interpreter. 1. Arithmetic calculator.

SCHEME AND CALCULATOR 5b

CS 275 Name Final Exam Solutions December 16, 2016

Project 5 - The Meta-Circular Evaluator

An Explicit-Continuation Metacircular Evaluator

Functional Programming. Pure Functional Programming

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

Scheme: Data. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, Glenn G.

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

Procedural abstraction SICP Data abstractions. The universe of procedures forsqrt. Procedural abstraction example: sqrt

HIERARCHICAL DATA What is a Tree? How is it different from a Deep List? When would you use one over the other?

Building a system for symbolic differentiation

Introduction to Scheme

CS 61A Midterm #2 ver March 2, 1998 Exam version: A. Your name. login: cs61a- Discussion section number. TA's name

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

CSE341 Spring 2017, Final Examination June 8, 2017

CS3: Introduction to Symbolic Programming. Lecture 14: Lists Scheme vs. other programming languages.

CS 314 Principles of Programming Languages. Lecture 16

Fall Semester, The Metacircular Evaluator. Today we shift perspective from that of a user of computer langugaes to that of a designer of

CS3 Midterm 1 Fall 2006

Using Symbols in Expressions (1) evaluate sub-expressions... Number. ( ) machine code to add

CIS4/681 { Articial Intelligence 2 > (insert-sort '( )) ( ) 2 More Complicated Recursion So far everything we have dened requires

Interpreters and Tail Calls Fall 2017 Discussion 8: November 1, 2017 Solutions. 1 Calculator. calc> (+ 2 2) 4

PAIRS AND LISTS 6. GEORGE WANG Department of Electrical Engineering and Computer Sciences University of California, Berkeley

User-defined Functions. Conditional Expressions in Scheme

regsim.scm ~/umb/cs450/ch5.base/ 1 11/11/13

Project 5 - The Meta-Circular Evaluator

Sample Final Exam Questions

Discussion 12 The MCE (solutions)

Homework 1. Reading. Problems. Handout 3 CSCI 334: Spring, 2012

;;; Determines if e is a primitive by looking it up in the primitive environment. ;;; Define indentation and output routines for the output for

An Explicit Continuation Evaluator for Scheme

Solutions and grading standards

Structure and Interpretation of Computer Programs

CS 360 Programming Languages Interpreters

CS3L Summer 2011 Final Exam, Part 2 You may leave when finished; or, you must stop promptly at 12:20

CS61A Notes Week 9: Muta4on (solu4ons) Revenge of the Box- and- pointers

CS 314 Principles of Programming Languages

Building a system for symbolic differentiation

Syntactic Sugar: Using the Metacircular Evaluator to Implement the Language You Want

CSC 533: Programming Languages. Spring 2015

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

6.001, Spring Semester, 1998, Final Exam Solutions Your Name: 2 Part c: The procedure eval-until: (define (eval-until exp env) (let ((return (eval-seq

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

6.001: Structure and Interpretation of Computer Programs

CSE341 Spring 2017, Final Examination June 8, 2017

6.945 Adventures in Advanced Symbolic Programming

(scheme-1) has lambda but NOT define

Lisp Basic Example Test Questions

CSE 341 Section Handout #6 Cheat Sheet

STREAMS 10. Basics of Streams. Practice with Streams COMPUTER SCIENCE 61AS. 1. What is a stream? 2. How does memoization work?

CS 342 Lecture 7 Syntax Abstraction By: Hridesh Rajan

Deferred operations. Continuations Structure and Interpretation of Computer Programs. Tail recursion in action.

SCHEME 10 COMPUTER SCIENCE 61A. July 26, Warm Up: Conditional Expressions. 1. What does Scheme print? scm> (if (or #t (/ 1 0)) 1 (/ 1 0))

Project 2: Scheme Interpreter

;; definition of function, fun, that adds 7 to the input (define fun (lambda (x) (+ x 7)))

CS 3L (Clancy) Solutions and grading standards for exam 1

This exam is worth 30 points, or about 28% of your total course grade. The exam contains

Transcription:

1 of 5 5/11/2006 12:10 AM CS 61A Spring 2006 Midterm 2 solutions 1. Box and pointer. Note: Please draw actual boxes, as in the book and the lectures, not XX and X/ as in these ASCII-art solutions. Also, please put in the start arrows! Sometimes it's hard to know where your diagrams are supposed to begin, especially if you use leftward and upward pointing arrows. > (cons (list '(a) '(b)) (append '(c) '(d))) (((a) (b)) c d) --->XX--->**--->X/ V V c d V XX--->X/ V V X/ X/ V V a b The pair marked ** in the diagram above is the value of the subexpression (APPEND '(C) '(D)), namely, the list (C D). The CONS sticks one pair in front of that, the pair at the start arrow. Its car, the first element of the new list, is the value of (LIST '(A) '(B)), which is ((A) (B)). > (car (cons '((portia)) '(black. satin))) ((PORTIA)) --->X/ X/ V portia This should have been really easy, because CAR is an inverse function of CONS; that is, (CAR (CONS X Y)) is always X, whatever X might be. So you could entirely ignore the second argument to CONS. The double parentheses in ((PORTIA)) mean that it's a list of one element, which is itself a list of one element, a word. > (caadr '( ((a b c) (d e f)) ((g h i) (j k l)) ((m n o) (p q r)) )) (g h i) --->XX--->XX--->X/ g h i This was mainly a test of whether you understand the order of operations in the C...R functions. CAADR means the CAR of the CAR of the CDR, not "first do CAR then CAR then CDR"! So we have (cdr '(((a b c) (d e f)) ((g h i) (j k l)) ((m n o) (p q r)))) (car '(((g h i) (j k l)) ((m n o) (p q r)))) (car '((g h i) (j k l))) (g h i) A shortcut to this solution is to remember that CADR returns the second element of a list, so you can get to ((G H I) (J K L)) in one step, then take the CAR (the first element) of that.

2 of 5 5/11/2006 12:10 AM If you did the operations in reverse order, you got the wrong answer (B C). > (filter (lambda (x) (if (list? x) (pair? x) (number? x))) '(1 () (2 3) (so) what)) (1 (2 3) (so)) --->XX--->XX-------->X/ 1 XX--->X/ X/ 2 3 so This was an exercise in understanding FILTER, IF, and predicates. The IF subexpression returns true for a list that's also a pair (i.e., not the empty list) or for a non-list that's a number (not a non-numeric word, for example). So these tests are made: element first test result second test result 1 LIST? #F NUMBER? #T () list? #t pair? #f (2 3) LIST? #T PAIR? #T (SO) LIST? #T PAIR? #T what list? #f number? #f The lines in capital letters show the elements that FILTER keeps. To solve this problem correctly you also had to understand that there is no recursion here, so this is not a deep-list problem: the elements of the elements are not tests (which would have rejected the word SO). Scoring: One point for each printed result; one point for each diagram, except that you lost at most one point for putting quotation marks in the printed results. 2. Data abstraction. This should have been an easy one, but a lot of people had trouble with it. It's important to know the domains of procedures; FIRSTS's domain is Trees, but HELPER's domain is forests, not trees, so (DATUM X) makes no sense. The argument to FIRSTS is a Tree, so its proper selectors are DATUM and CHILDREN, and to construct a new one you use MAKE-TREE (or you could call it MAKE-NODE, equivalently). DATUM of this Tree is a sentence, so its selectors are FIRST and BUTFIRST. CHILDREN of a Tree (the argument to HELPER) is a forest, which is just a sequence (a list), so its selectors are CAR and CDR, and its constructor is CONS. (define (firsts tree) (MAKE-TREE (FIRST (DATUM tree)) (helper (CHILDREN tree)))) (define (helper x) ; We chose this bad parameter to hide the type! (if (NULL? x) ; Don't use X in your own programs. '() (CONS (firsts (CAR x)) (helper (CDR x))))) Scoring: One point off for each error, either failing to change something that should be changed, or changing something that shouldn't. 3. Understanding Scheme-1. EVAL-1 deals with *expressions* -- with the notation in which programs are expressed. APPLY-1 deals with *values*, including procedures as well as their arguments, and knows how to call a procedure.

3 of 5 5/11/2006 12:10 AM So (a), which is about the *notation* for a procedure call, and (c), which is about a special form, are changes to EVAL-1. For (a), we'd add a clause before line 10, something like ((and (pair? exp) ; exp is a list (not (null? (cdr exp))) ; of length > 1 (arithmetic-operator? (cadr exp))) ; 2nd elt. is +-*/ (apply-1 (eval-1 (cadr exp)) ; apply val of oper (list (eval-1 (car exp)) ; to first elt (eval-1 (caddr exp))))) ; and third elt For (c), we'd add a clause somewhere before line 10 saying ((define-exp? exp) (add-to-global-table! (cadr exp) ; name is 2nd elt (eval-1 (caddr exp)))) ; value exp is 3rd and we'd change line 3 to ((symbol? exp) (if (found-in-global-table? exp) (value-in-global-table exp) (eval exp))) ; if we've defined this name ; get value we saved ; else ask STk as before But (b) is about how to call a procedure; we'd change line 17 of APPLY-1 to: (eval-body (substitute (caddr proc)... where EVAL-BODY evaluates the expressions in turn: (define (eval-body exprs) (if (null? (cdr exprs)) ; if only one expression left, (eval-1 (car exprs)) ; return its value (begin (eval-1 (car exprs)) ; otherwise eval the first one (eval-body (cdr exprs))))) ; but keep going The unusual base case reflects the fact that we have to return the value of the last expression; that's why we can't just use FOR-EACH to evaluate all the expressions in the body. Scoring: 2 points each, all or nothing. 4. Function overloading with DDP Changing the syntax of the parameter list in STk's lambda expressions would be possible only using tools beyond the scope of this course. We could build an overloaded DEFINE into Scheme-1, but that's not what the question asked for. Instead we create two new procedures, OVERLOADED and DEFINE-OVERLOADED. But these are really just like SICP's implementation of DDP for functions of possibly more than one argument, using the type signature to find the correct method. So all you had to do for full credit on this question is (define define-overloaded put) (define overloaded apply-generic) ; the one on SICP page 184 Other correct solutions basically involved rewriting one or both of PUT and APPLY-GENERIC. Scoring: We allocated 2 points to DEFINE-OVERLOADED, which was pretty much all or nothing. We allocated 3 points to OVERLOADED, as follows: 3 Correct. 2 Passes typed data to method (doesn't call CONTENTS). 2 Mistakes in dot notation for variable number of arguments. 2 (method args) instead of (apply method args).

4 of 5 5/11/2006 12:10 AM 1 Only works for two arguments. 1 Checks only one type tag. 0 Anything worse. 5. Deep lists. (a) Car/cdr recursion means two recursive calls for each pair, one for the car, and one for the cdr! (cond ((null? lst) '()) ((pair? lst) (cons (deepen (car lst)) (deepen (cdr lst)))) (else (list lst)))) (b) Using MAP means that the recursion is indirect, through a call to MAP. Improper lists (pairs whose cdrs are non-null atoms) aren't in the domain of this procedure; you could have an error check if you wanted, but we don't require error checks on exams: (cond ((null? lst) '()) ;; This test is unnecessary but okay. ((list? lst) (map deepen lst)) ;; ((pair? lst) (error "no improper lists")) ; Optional. (else (list lst)))) A common error on (b) was to try to combine car/cdr recursion with MAP, like this: (cond ((null? lst) nil) ((atom? (car lst)) (cons (list (car lst)) (map deepen (cdr lst)))) (else (map deepen lst)))) This doesn't work, because the elements of (cdr lst) might be atoms, in which case the map will fail. But even if it did work, this problem is about understanding different styles of programming, and you should know how to write a MAP-based tree recursion cleanly. Such solutions got 2 points out of 4 for part (b). Scoring: 4 points for each part, as follows: 4 Correct. 3 Has the idea. 2 Has an idea. 0 Other. Some particular common examples: -2 for LIST or APPEND instead of CONS; -2 for SYMBOL? instead of ATOM?. 6. Tree search. The procedure should return #T in two cases: (1) The two desired data are directly below this node; (2) A recursive call for some child returns #T. (define (siblings? tree datum1 datum2) (define (helper forest) (cond ((null? forest) #f) ((siblings? (car forest) datum1 datum2)) (else (helper (cdr forest))))) (or (and (member datum1 (map datum (children tree))) (member datum2 (map datum (children tree)))) (helper (children tree)))) An alternative to using a helper function would be to replace the last line with (not (null (filter (lambda (child) (siblings? child datum1 datum))

5 of 5 5/11/2006 12:10 AM (children tree)))) This is perfectly acceptable, but less efficient; if the first child satisfies the condition, it checks the other children anyway. (A useful higher order function we should have in our library is FIND-FIRST, like FILTER except that it returns only the first element that satisfies the condition.) You *can't* avoid a helper by calling SIBLINGS? itself with (CHILDREN TREE) as its first argument. That argument has to be a tree, not a forest! You could make this solution slightly more efficient by using (let ((data (map datum (children tree)))) (or...)) to avoid calling MAP twice. Some people, taking advantage of the assumption that an element appears at most once, used my find-place procedure from lecture to find the path from the root to each datum, and then see if the butlasts of the paths are the same. This is a fairly reasonable "use what you have to get what you need" approach for an exam, if you don't know how to solve the problem properly, but in real programming it's really inefficient and ugly to create data structures (the paths) that you don't really need to solve the problem. And this solution isn't quite correct; it's a data abstraction violation to use BUTLAST on a path, which isn't a sentence. [You could instead say (reverse (cdr (reverse path))), making this solution even uglier, but correct.] Also, your program will be more robust if it doesn't rely on the uniqueness of the data, a condition that isn't necessary in our solution above. Scoring: 8 Correct. 7 (NULL? TREE). 6 Tests each node correctly but doesn't accumulate the results correctly. 6 No base case in helper. 5 Forgets the (MAP DATUM...). 5 Data abstraction violation, but does the right thing. 2 (SIBLINGS? (CHILDREN TREE) DATUM1 DATUM2). 0 Even worse (e.g., no tree recursion). ----------------------------------- If you don't like your grade, first check these solutions. If we graded your paper according to the standards shown here, and you think the standards were wrong, too bad -- we're not going to grade you differently from everyone else. If you think your paper was not graded according to these standards, bring it to Brian or your TA. We will regrade the entire exam carefully; we may find errors that we missed the first time around. :-) If you believe our solutions are incorrect, we'll be happy to discuss it, but you're probably wrong!