Assignment 9, due Mar 31Solutions
Part of
the homework for CS:2820, Spring 2017
|
On every assignment, write your name and section number. Write your name as it appears on your university ID card! Use the section number as it appears in your current registration! We will not do detective work to figure out who did what. Homework is due on paper at the start of your discussion section. Exceptions will be made only by advance arrangement with your TA (excepting "acts of God"). Never push homework under someone's door!
a) This means that we have public 'setter' and 'getter' methods to operate on outgoing. That suggests that outgoing might as well be public. Give examples of operations on outgoing that are forbidden to the public as a result of forcing the public to use these methods. (0.5 points)
We can only append new items to outgoing, so we cannot do any of the following operations, among many others: addFirst(), clear(), poll(), remove(), and set().
b) But the list outgoing is already declared as final. This would seem to imply that outgoing is read-only. Give an example of an operation on outgoing that is forbidden by declaring it to be final, and give some examples of operations that change outgoing that are still permitted despite its being final. (0.5 points)
Declaring it to be final makes it illegal to assign a new value. That is, we cannot write outgoing=x. We can, however, change the contents of the list, for example, using our setter method addOutgoing() which calls outgoing.add().
public void arrivalEvent( float time, Vehicle v ) { Simulation.schedule( time + travelTime, (float t)->this.departureEvent( t, v ) ); }
A problem: Rewrite the above code so that it does not use a lambda expression. This will require defining an inner class that implements Simulation.Action and then passing an instance of that class. Do it with an explicitly named inner class. (0.5 points)
public void arrivalEvent( float time, Vehicle v ) { class A implements Simulation.Action { void trigger( float t ) { departureEvent( t, v ); } } Simulation.schedule( time + travelTime, new A() ); }
Alternatively, we could use an anonymous inner class:
public void arrivalEvent( float time, Vehicle v ) { Simulation.schedule( time + travelTime, new Simulation.Action { void trigger( float t ) { departureEvent( t, v ); } } ); }
// version a public void departureEvent( float time, Vehicle v ) { Simulation.schedule( time, (float t)->destination.arrivalEvent( t, v ) ); } // version b public void departureEvent( float time, Vehicle v ) { destination.arrivalEvent( time, v ) }
a) Which solution will lead to more efficient code and why? (0.5 points)
Version b simply calls destination.arrivalEvent() instead of scheduling it to happen now, that is, immediately after the return from the departureEvent().
Note that these are equivalent because there is no code in departureEvent() between the time it schedules destination.arrivalEvent() and the time it returns. Had there been code there, it would have been harder to prove the equivalence of these two versions because we would have had to prove that none of that code interacted in any way with the code in destination.arrivalEvent().
b) Consider the following actions during the execution of this code:
Give the order of these actions as they occur with version a and with version b. (0.5 points)
In version a: 3 4 1 2
In version b: 3 1 2 4
An alternative is to add a new field to each gate that indicates that is incremented every time an output change event is scheduled and decremented when that event occurs. Only when the output change event decrements the counter to zero does the event service routine actually change the output.
A Question: What is the minimum time interval between successive output changes, as a function of gate characteristics defined by the input to the logic simulator. (0.5 points)
The interval is the same as the gate delay.