Assignment 12

Due Apr. 21, on line

Part of the homework for CS:2820, Spring 2021
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Simple multiple choice questions, 1 point each:

  1. In the solutions to the machine problem that have been distributed for MP8 and MP9, it was necessary to schedule and reschedule infection events. None of these solutions have a simulation framework that supports event deletion or rescheduling, so how were previously scheduled events cancelled or rescheduled?
    a) By deleting the Action fields of events to cancel them.
    b) By changing the time fields of events to reschedule them.
    c) By changing the λ expression associated with obsolete events.
    d) By checking a variable to stop cancelled events from doing anything. — correct.
    e) By changing the object on which cancelled events operate to null.

    In the solutions to MP8 and MP9 the act and time fields of events were declared to be final. Therefore, they cannot be changed, so a) and b) must be wrong. Besides, changing the time field of an item in the pending-event set would violate a fundamental requirement of all priority queue and heap implementations.

    The λ expression is used to creat an Action which is stored in the act field of an event, so answer c) is really just a variation on answer a) and it is equally wrong.

    Answer e) is nonsense. Cancelling an event cannot not delete any objects aside from the object representing the event itself. If the "get sick" event for a person is to be cancelled, that does not require that we eliminate the person.

    Answer d) is correct. Look at the code for Person.infect, which begins with this if statement:

    if (   (diseaseState == DiseaseStates.uninfected) // no reinfection
        && (infectMeTime == now)                      // if not rescheduled

    The variable that is changed in order to cancel or reschedule an infection is infectMeTime.

  2. Consider the graph of dependencies between classes, where one class depends on the other if the name of the other is mentioned in the definition of the class. Two classes in a large program are probably part of the same software layer if:
    a) the graph is acyclic.
    b) the graph links the two classes in a cycle. — correct.
    c) the graph is a tree and the two classes are at the same level.
    d) the graph is plotted on cartesian coordinates.
    e) the graph is a tree and one class is the parent of the other.

    If class A depends on class B, then either they are in the same layer or A is in a layer above B.

    It follows that if there is a cycle, the classes in the cycle must all be in the same layer, so b) is correct.

    Answer d) is utter nonsenxe (it refers to a completely different use of the word graph.

    Answers a), c) and e) all refer to kinds of acyclic graphs, from which no hard conclusions may be drawn about layering. If the graph is acyclic, it may be that each class is in a separate layer.

  3. Gnuplot is a data plotting utility that can read and plot data from a CSV file, but to do so, it needs a file of instructions, let's call that file plotfile, and let's assume that plotfile explains how to read plotdata.csv. The following rules could be added to the epidemic simulator makefile to try to make it plot the output:
    plotdata.csv: epidemic.class model
            java epidemic model > plotdata.csv
    	gnuplot plotfile

    There are some missing make dependencies in the above:
    a) plot depends on plotdata.csv
    b) plot depends on epidemic.class
    c) plot depends on model and plotdata.csv
    d) plot depends on epidemic.class and plotfile
    e) plot depends on plotdata.csv and plotfile — correct.

    plot obviously depends on plotfile since that is an argument to the gnuplot shell command. What else does it depend on? The descriptive text explained that plotfile "explains how to read plotdata.csv." Therefore, plot also depends on plotdata.csv. In sum, e) is correct and a) is incorrect because it only partially lists the dependencies.

    plot only depends on epidemic.class and model.class indirectly, through plotdata.csv. In general, makefiles should not list such indirect dependencies. The make utility automatically infers them from the direct dependencies that are given. This rules out b), c) and d).

  4. Consider this bit of code from one of our simulators:
    Simulator.schedule( time + delay, (double t)-> go( time + delay ) );
    In our original simulators, it worked perfectly, but when we modified class Simulation to support rescheduling, and this event was one of those that was rescheduled, things went crazy and sometimes, events were simulated out of order. This is because:

    a) The λ expression cached time+delay, while reschedule() changed t. — correct.
    b) Rescheduling changed time but not delay.
    c) All λ parameters must be final or effectively final.
    d) go() needs to be rewritten to allow rescheduling.
    e) We needed to get rid of the common subexpression by doing td=time+delay first.

    As we have demonstrated a month or more ago, the code given above really compiles to something like this:

    Simulator.schedule( time + delay, new SomeKindOfAction( time, delay ) );

    Where SomeKindOfAction implements Event and the parameter initializes cached copies of the effectively final non-local variables found in the body of the λ expression. The trigger method of SomeKindOfAction will call go(cachedTime+cachedDelay).

    Given this, it should be clear that b) is wrong because nothing done in reschedule() can change the cached copy of Time. Answer e) is wrong for similar reasons, no rewrite of time+delay will eliminate the cached copy.

    Rewriting go() cannot help, since that is outside the control of class Simulation. Rewriting the call to go does help, but that is not what answer d) said – to most programmers, "rewriting go()" suggests a rewrite to the code of the method itself, not a rewrite to the call.

    Answer c) is only tangentially relevant and it is also false. The correct statement would be "all variables referenced in a λ expression other than the λ parameters must be final or effectively final."

    Answer a) is the closest to correct because time and delay are indeed cached, and because reschedule() can change the lambda parametere t but has no effect on the cached values.

  5. Consider these inner class definitions, part of class X:
    Public Static Class A {}
    Private Static Class AA extends A {
        public Thing t;

    Given an instance of AA called aa inside a method of class X how can the code return class aa to a user of X in a form that is encapsulated?
    a) return (A)aa; from code declared to return an AA
    b) return new A(aa); from code declared to return an A
    c) return aa; from code declared to return an A — correct.
    d) return aa; from code declared to return an AA
    e) return new A(); from code declared to return an A

    The method cannot return an AA because class AA is unknown to the world outside X and therefore if the method returned an AA, the method itself would be effectively invisible outside X even if it was public. Therefore a) and d) are wrong.

    Class A does not have a constructor with a parameter, so b) is wrong. Returning a new A cannot be right, because that new A carries no information at all, so e) is wrong.

    Therefore, c) is the only answer we have not eliminated. Is it right? Yes, because aa is a legal value to return in any context where a member of class AA is allowed, and that includes places where all parent classes of AA are expected, including class A.