University of Virginia Computer Science
CS150: Computer Science, Fall 2005

Exam 2 Comments

Grading Note: The exam has 88 "possible" points from the questions. Exam scores include a 12 point bonus for all students who spelled their name correctly, to provide 100 "possible" points. (On some questions, it was possible, of course, to get more than the number of "possible" points if an answer is exceptionally good or clear.) The class average on the exam was 84.

Programming with Mutation

1. (average 7.2 out of 10) The end-auction! procedure from Problem Set 5 (PS5 Comments) did not remove sold items from the item table. To remove an item we need a table-delete! procedure. It takes a table, a field, and a procedure. It mutates the value of the table to remove all entries for which the procedure applied to the value of the field evaluates to true. For example, in end-auction! we would do
   (table-delete! items 'item-name (make-string-selector item-name))
to delete the item named item-name from the items table after it is sold.

Define the table-delete! procedure.

Comments: The simplest way is to use table-select, and to replace the entries of the table using set-cdr!:

(define (table-delete! table field pred)
  (set-cdr! table 
	    (table-entries 
	     (table-select table (lambda (val)
				   (not (pred val)))))))
(note we need the not to negate the predicate procedure since we are keeping the non-matching entries and removing the matching entries).

This is not the most efficient solution, since it involves constructing a new table and new entries list in that table. Alternately, we could go down the list of entries and replace cdr's as necessary to skip deleted entries. This is much trickier: (note: I applied the same no DrScheme rules to myself writing these solutions, so it is likely there are some bugs in this code. If you try it and find some, you can get bonus points on your exam by sending in a working version)

(define (table-delete! table field pred)
  (define (table-delete-elements! elements fieldno proc)
    (if (null? elements) null
	(if (proc (get-nth (car elements) fieldno)) ; skip this one
	    (table-delete-elements! (cdr elements) fieldno proc)
	    ; keep this one, but make its cdr the result of deleting elements
	    (set-cdr! (car elements)
		      (table-delete-elements! (cdr elements) fieldno proc)))))
  (set-cdr! 
   table ; note we still need set-cdr! in case the first entry is deleted
   (table-delete-elements! 
    (table-elements table)
    (find-field-number table field)
    pred)))

2. (9.1 / 10) What is the complexity of your table-delete! procedure? (Use Θ notation, and be sure to define all variables you use carefully, and state all assumptions you make. For full credit, your answer must include a clear and convincing supporting argument.)

Comments: The first definition applies set-cdr!, table-entries, and table-select. The first two are Θ(1) since the time they take does not depend on the table size. The table-select time depends on the number of entries n in the input table and the number of fields f in the table. Our implementation of table-select (from the PS5 comments) is Θ(nf) as explained in the PS5 comments, so table-delete! is Θ(nf).

Note that although the second definition is more efficient, it is also Θ(nf) since it cdrs through the entries in the table, doing a get-nth which it Θ(f) work on each entry. The reason it is more efficient is because the amount of new cons cells it needs to create is much less (in fact, it creates no new cons cells, just replaces cdrs using set-cdr!), so it will run faster and use less memory for the same size input as the first definition. However, as the input size grows, the second definition will also grow as Θ(nf).

Programming with Objects

3. (8.4 / 10) The make-police-officer procedure defined in Problem Set 6 Comments (Question 6) starts like this:
(define (make-police-officer name) 
  (let ((super (make-person name)))
    (ask super 'make-restless 2) ;;; Police officers are quite restless
    (lambda (message)
      ...
Suppose we had used this instead:
(define (make-police-officer name) 
  (let ((super (make-person name))
	(restlessness 2))
    (lambda (message)
      ...
Explain why the new police officer would not be very effective. (You may want to use an environment diagram to make your answer clear.)

Comments: The new police officer would have initial restlessness 0, the value set in make-person. This means she wouldn't move on a clock tick (if she started in the right place, perhaps she could stil be an effective police officer!) The reason for this is the restlessness place defined by the let is in the frame created when the let application is done. This frame also contains the super place which has the result of (make-person name). The person created has its own frame, containing its restlessness place. When the clock-tick method is evaluated on the police-officer, it uses the inherited person clock-tick method which is:

   (lambda (self)
     (if (< (/ (random 100000) 100000) restlessness)
	 (ask self 'act-randomly)
	 #f)))
So, the restlessness name is evaluated in the person's frame, and the 0 value is found. This is why we need to use the ask instead, to change the value of restlessness in the right frame. (Note that in many object oriented languages this is not the case; we can override a variable in a subclass, and when the code in the superclass methods uses that variable, it will find the new value instead.)

Complexity and Computability

4. For each of the following statements, explain what the impact of the described event would be.

  1. (2.6 / 3) Finding a Θ(2n) algorithm that solves the Smiley Puzzle.
    Comments: This would not show anything very useful, other than that we can solve the Smiley Puzzle in 2n. Note that 2n is not a polynomial, so it does not put the Smiley Puzzle in class P. (Some students claimed that it showed that it would prove that all NP-Complete problems have Θ(2n algorithms. This is a good conclusion based on the reasoning that we defined NP-Complete as the "hardest" problems in class NP, and argued that they can all be reduced to each other. The subtlety (that we didn't get into in the class) is that the reduction is a polynomial-time reduction. That means it must be done in polynomial time. Because of this, it can scale the size of the input (n in this example) by up a polynomial factor. So, it would be possible to reduce the Traveling Salesperson Problem to the Smiley Puzzle, but the size of the result Smiley Puzzle might be 7n not size n. Hence, it when we say "hardest" problems in NP, we really mean "hardest" within a polynomial time reduction, and knowing Smiley is O(2n) does not prove that all NP-Complete problems have Θ(2n) solutions. Based on what we covered in class, though, this was an intelligent and reasonable conclusion, so it was worth full credit.)
  2. (2.8 / 3; the average is a bit deceptive here, since answers that correctly determined that this proved P is not equal to NP received 5 points) Finding a proof that the fastest possible algorithm that can solve the 3SAT problem is Θ(3.3n).
    Comments: If you were able to do this you wouldn't need to finish the rest of this exam since you would have proved class NP is not equivalent to class P (thus ensuing an automatic A+ in the class). Since the described proof shows that the fastest possible algorithm for an NP-Complete problem is worse than polynomial time, it means that the NP-Complete problems have no polynomial-time solution, and that class NP is different from class P. This would be a very significant result!
  3. (1.8 / 3) Finding a Θ(n5) algorithm that solves a problem in NP.
    Comments: This would be uninteresting since class NP contains class P. There are lots of problems in NP that have Θ(n5) algorithms such as simulating a 5-dimensional universe at scale n.
  4. (1.8 / 3) Finding a polynomial-time reduction from the Sorting Problem to the Smiley Puzzle
    Comments: A reduction from problem A to problem B means we can use a solution to problem B to solve problem A, thus showing that problem A is no harder than problem B (modulo the reduction). So, this would show that the Sorting Problem is no harder than the Smiley Puzzle. This is uninteresting, since we already know Sorting is Θ(n log n) and Smiley Puzzle is NP-Complete.
  5. (2.0 / 3) Finding a polynomial-time reduction from the Traveling Salesperson Problem (defined in Lecture 16) to the Halting Problem
    Comments: This shows that we could use a solution to the Halting Problem to solve the Traveling Salesperson Problem. Since we know the Halting Problem is undecidable, this is uninteresting. One subtlty here is that we would need to convert the TSP to a decision problem for this to make sense. The output of the Halting Problem is just true or false, but the output of the TSP (as we defined it) was a list of cities or false. So, there would be no way to map the true or false value produced by the halting problem back to a list of cities. The solution to this is to convert TSP to a decision problem, where the output is true or false (for example, the output is whether or not a valid route with less than some distance exists).
  6. (1.8 / 3) Finding a polynomial-time reduction from the Halting Problem to the Smiley Puzzle
    Comments: This would be a shocking and unfathomable reduction, since is would claim that a proven decidable problem (the Smiley Puzzle) can be used to solve a proven undecidable problem. It would mean that Turing and thousands of other computer scientists were all wrong, and that the foundations of logic and proof are broken, or that there is a problem with the reduction you found. (Most likely the latter!)

Computability

5.
a. (3.9 / 5) Is the Identical-Outcomes problem described below decidable?
Input: Two programs P and Q and an input I

Output: If executing program P on input I produces the same output as executing program Q on input I output true. Otherwise, output false. Two executions are considered to produce the same outcome if either (1) both executions do not terminate; or (2) both executions terminate with the same output.

Comments: The Identical-Outcomes problem is undecidable. We can prove this by showing how a solution to Identical-Outcomes could be used to solve a known undecidable problem, the Halting Problem. Here's how:
(define (halts? P I)
   (not (identical-outcomes? P (lambda (x) (infinite-loop)) I)))
We use an infinite loop producing program as the Q input to identical-outcomes?. If P would halt, identical-outcomes? is false since Q does not halt. If P would not halt, identical-outcomes? is true since both p and Q do not halt.

A common mistake on this question was to use halts? to define identical-outcomes? and claim that that proves Identical Outcomes is undecidable. Showing that we can define something using halts? doesn't prove anything, since we know we can't define halts?. You would need to prove that there is no other way of defining identical-outcomes? that does not use halts?.

b. (4.2 / 5) Is the Identical-Termination problem described below decidable?
Input: Two programs P and Q and an input I

Output: If both P and Q executing on on input I halt, output true. If both P and Q do not halt on input I, output true. Otherwise (one of the programs halts and the other one does not halt), output false.

Comments: As in part A, we can show that identical-termination? would allow us to solve halts?:
(define (halts? P I)
   (not (identical-termination? P (lambda (x) (infinite-loop)) I)))
(I think some students are so convinced that an exam wouldn't ask the same question twice, or a question with the same answer twice, that they find ingenious ways to come up with different answers. I like to ask the same question multiple times, since its easier than coming up with new questions, and a good way to see if students really understand things well enough to repeat the same answer confidently. You should't be too surprised if I do something similar on the final.)

6. (9.3 / 10) Ben Bitdittle claims that the streakability problem (as defined in Problem Set 6 is decidable using this argument:

The streakability problem involves one student, one police officer, and a finite number of places. Hence, the state of Charlottansville is described by the locations (what place they are at) of the police officer and the student, and the state of undress of the student (if the student's is-dressed variable is #t or #f).

There are a fininte number of possible states. If the number of places is p, the maximum number of possible states is p * p * 2 (p possible locations for the police officer, p possible locations for the student, and 2 possible undress states for the student).

Since the total number of states is finite, an execution longer than 2p2 steps (clock-ticks) must repeat a previous state.

We can evaluate the streakability problem by setting up the initial state of the world and running clock-ticks until either the streaker is arrested, in which case the output is true, or 2p2 clock ticks have been executed, in which case the output is false since a state repeated without the streaker being arrest and once a state repeats the same sequence of states will be repeated every time.

Ben's answer differs from the answer given in the PS6 Comments. Explain at least two fundamental flaws in Ben's argument, and what assumptions are needed to make his argument hold.

Comments: Sorry, this turned out to be a bad question. There were too many confusing things wrong with Ben's proof, that no one identified the one most important assumption his proof depends on that was needed for the undecidability proof to work. That is that the clock-tick method is guaranteed to terminate. Ben's proof relies on the assumption that each tick completes; the undecitability proof in PS6 comments was based on the possible non-termination of the clock-tick method for the police officer (in this case, through its call to the arrest method).

The less fundamental assumptions Ben's proof relies on are that the state of the world he identifies (locations of the police and streaker and dress state of the streaker) fully capture the state of the process. In fact, this is not the case, since the state of the random number generator also effects what happens next, as well as whether or not the student has successfully traversed the streaking path. For Ben's proof technique to be correct, he must know that when a state S is encountered the next state T will be the state that follows S if the same S state is ever encountered again. If Ben's state notion captures everything about the state of the process this would be true, and it would me that once the number of steps exceeds the number of possible states, that no new states will ever be encountered.

Because of the problems with this question, if your answer revealed any understanding of Ben's proof and the proof in PS6 comments, you received full credit for this question.

Models of Computation

7. (9.0 / 10) In Lecture 32 we defined:
cons ≡ λ xyz . zxy
car ≡ λ p . p T
cdr ≡ λ p . p F
If we instead defined:
cons ≡ λ xyz . zyx
Explain how we should define car and cdr to have the correct meaning and show that car cons M N correctly reduces to M using your definitions.

Comments: Since the definition of cons flipped the variables, we need to flip the definitions of car and cdr also:

car ≡ λ p . p F
cdr ≡ λ p . p T
After this, showing the car cons M N term reduces correctly is just a matter of following the beta-reduction rules similarly to Lecture 32.

8. (8.0 / 10) Cy D. Fect proposes the following Churning Machine model of computation as an alternative to the Turing Machine:

The Churning Machine is an infinite tape with one tape head, two finite state machines (we call them the M and N machines), and a churner which selects between the finite state machines. The churner is in one of two possible states: pointing to the M machine or pointing to the N machine.

At each step the Churning Machine looks at the churner to decide which FSM to use. Then, it reads one symbol from the tape, and follows the transition rule for the current state of the selected FSM. The transition rule has an output symbol, a next state, and a head direction, just like in a Turing Machine. It also has a churn option, which is either True or False. If the churn option value is True the churner switches to point to the other FSM. Note that when the churner switches, the FSM maintains its current state; when the churner switches back, it will resume from that state.

Cy claims his Churning Machine is more powerful than a Turing Machine because it has two FSMs and the churner. Explain how you would prove him wrong. (You do not need to provide a fully details proof, but should provide a convincing argument.)

Comments: To prove Cy wrong, we need to prove that the Churning Machine (CM) is no more powerful than a Turing Machine (TM). If we can show that we can simulate all possible CMs with a TM, that would be a convincing proof.

The simulate a CM with a TM, we need to map the state of the CM onto the TM. We can do this by combining the M and N finite state machines into a single finite state machine. Suppose the states of the M machine are numbered 0, ..., m - 1 and the states of the N machine are numbered 0, ..., n - 1. Then, the FSM for the corresponding TM will need a state that captures the state of both the M and N machine. For this, we need m * n total states for each pair of states. Since we also need to know the current machine, we need two versions of each state, for 2mn states total. The TM states would be labeled <sm, sn, c> where sm is the state of the M machine, sn is the state of the N machine, and c is the state of the churner. The transition rules for the CM machine could be mapped to transition rules for the TM by just using the state labeling mapping.