University of Virginia Computer ScienceCS150: Computer Science, Fall 2005 |

(table-delete! items 'item-name (make-string-selector item-name))to delete the item named

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

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 Θ(*n**f*) 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*).

(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

- (2.6 / 3) Finding a Θ(2
^{n}) algorithm that solves the Smiley Puzzle.**Comments:**This would not show anything very useful, other than that we can solve the Smiley Puzzle in 2^{n}. Note that 2^{n}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 Θ(2^{n}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 7*n*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(2^{n}) does not prove that all NP-Complete problems have Θ(2^{n}) solutions. Based on what we covered in class, though, this was an intelligent and reasonable conclusion, so it was worth full credit.) - (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.3
^{n}).**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! - (1.8 / 3) Finding a Θ(
*n*^{5}) 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 Θ(*n*^{5}) algorithms such as simulating a 5-dimensional universe at scale*n*. - (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. - (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). - (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!)

Input:Two programsPandQand an inputI

Output:If executing programPon inputIproduces the same output as executing programQon inputIoutputtrue. Otherwise, outputfalse. 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:TheIdentical-Outcomesproblem is undecidable. We can prove this by showing how a solution toIdentical-Outcomescould 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 theQinput toidentical-outcomes?. IfPwould halt,identical-outcomes?is false sinceQdoes not halt. IfPwould not halt,identical-outcomes?is true since bothpandQdo not halt.A common mistake on this question was to use

halts?to defineidentical-outcomes?and claim that that proves Identical Outcomes is undecidable. Showing that we can define something usinghalts?doesn't prove anything, since we know we can't definehalts?. You would need to prove that there is no other way of definingidentical-outcomes?that does not usehalts?.

Input:Two programsPandQand an inputI

Output:If bothPandQexecuting on on inputIhalt, outputtrue. If bothPandQdo not halt on inputI, outputtrue. Otherwise (one of the programs halts and the other one does not halt), outputfalse.

Comments:As in part A, we can show thatidentical-termination?would allow us to solvehalts?:(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'sBen'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.is-dressedvariable is#tor#f).

There are a fininte number of possible states. If the number of places is

p, the maximum number of possible states isp*p* 2 (ppossible locations for the police officer,ppossible locations for the student, and 2 possible undress states for the student).Since the total number of states is finite, an execution longer than 2

p^{2}steps (clock-ticks) must repeat a previous state.We can evaluate the

streakabilityproblem by setting up the initial state of the world and running clock-ticks until either the streaker is arrested, in which case the output istrue, or 2p^{2}clock ticks have been executed, in which case the output isfalsesince a state repeated without the streaker being arrest and once a state repeats the same sequence of states will be repeated every time.

**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.

If we instead defined:cons≡ λxyz.zxy

car≡ λp.pT

cdr≡ λp.pF

Explain how we should definecons≡ λxyz.zyx

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

After this, showing thecar≡ λp.pF

cdr≡ λp.pT

**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 theCy 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.)MandNmachines), and a churner which selects between the finite state machines. The churner is in one of two possible states: pointing to theMmachine or pointing to theNmachine.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

TrueorFalse. If the churn option value isTruethe 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.

**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 2*m**n* states total. The TM
states would be labeled <*s _{m}*,