XML

kent logo

CO538 Anonymous Questions and Answers Keyword Index

This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.

To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.

Keyword reference for q4

2012

Question 27 (2012):

Submission reference: IN2179

Hello, I have everything working fine but I remember in one of the answers previously that you suggested speed.control to ALT between 3 guards, a timeout guard, a speed control guard and an input guard. I was wondering if there was any difference between that 3 guard ALT and a PRI ALT with just a speed control guard and a timeout guard, which is what I currently have.

Answer 27:

Certainly there will be a difference. For one thing, it means when speed.control is waiting for its normal input, it can't process speed control commands. For this exercise, that probably doesn't matter since input data will mostly be pending and it won't have to wait for long. For other applications of speed.control, where the input data was sometimes stalled, this could be bad – it would hold up whatever process was trying to change the speed (and if that process were also interacting with whatever was supplying the input data, that would cause deadlock).

However, not dealing with such possibilities will only be lightly penalised ... this time! Unnecessarily constraining the way a process can sync with its environment is something always to avoid.

The PRI in your question is not relevant to the above concern.

Keywords: q4


Question 26 (2012):

Submission reference: IN2178

Hello there,

For Q4 all seems well in Gaul, however there is just one issue. Originally, when the BELL character is output (BELL flashes my output window), the ability to change speed stops, all output stops as well. Is this the desired beaviour or should it be that output continues? I have it so that output will continue such that when the limit is reached the value fed into pause is halved if at 256 lines per second (or doubled if at 1 lines per second) before the bell is output. That way the the limit is reached and imediately reset to the previous speed and the error is shown. Which way is better or desired?

Also is the diagram compulsory? My ASCII art isn't exactly da Vinci standard.

Thank you for your help.

Answer 26:

It is not desired behaviour that the system stops working when a command to change speed would push that speed outside its defined limits. As the question says:

"... the attempt should be ignored and an error message generated. To keep things simple and not interfere with the columns of numbers being output, this error message should be a single BELL character ... sent to the error! channel."

You said: "when the limit is reached the value fed into pause is halved if at 256 lines per second (or doubled if at 1 lines per second) before the bell is output." That implies you do not allow your system to reach either of the defined limiting speeds? If so, that is wrong. What should happen is that if the command would push the speed above 256 lines/second (respectively below 1 line/second), the speed should be changed to 256 lines/second (respectively 1 line/second).

The two diagrams (for pairs2 and q4) are compulsory. You do not have to do ASCII art! There are four options:

Keywords: q4 , diagrams


Question 25 (2012):

Submission reference: IN2177

I have tried my best at implementing the approach that was suggested in my seminar where I take the raw BYTE information from print.streams, feed it through my monitor process which implements the freeze functionality and then feed it through a speed.control component before outputting it to the screen!.

Unfortunately, what I thought worked for this approach doesn't seem to and just introduces deadlock when the program first runs. I've written everything out as a diagram and can't get my head round why this is happening - it all looks as if it should work (to me anyway!)

Copied below are the relevant sections of my code. I wondered if you would be able to give me any suggestions of what's happening or why the deadlock is occurring and/or what would be the best way for me to implement the final stages of speed control? Freeze/flip etc. are all working.

Thank you very much in advance for your help.

(Ed: code deleted)

Answer 25:

I've contacted the seminar leaders ... who all deny suggesting the approach you describe. We think you must have misunderstood some of the discussion on this.

See the third and fourth paragraphs of the answer to Question 21 (2012). The approach you describe appears attractive but, for the reasons described in that third paragraph, is unsafe. Deadlock is very likely to happen as soon as a cycle of communications is attempted (whenever monitor communicates to one of the processes it is controlling ... all of which are feeding back communications to monitor). A safe design is outlined in the fourth paragraph just referenced.

You said your implementation of this (wrong) approach "introduces deadlock when the program first runs". The deadlock in that approach only happens when monitor responds to a command to reset one of the three resettable components. If you get deadlock as it starts (i.e. without keying in 'n', 'i' or 'p'), you have another problem – check your wiring, check your speed.control has a loop, ...

Thought: it may be that you misunderstood your seminar leader when the freeze control in Exercise 3 was being discussed? In that system, "the raw BYTE information from" demo "is taken and fed through" a control "process which implements the freeze functionality". Now, there is no feedback loop of message traffic in the network for that exercise – so this is safe. Your seminar leader may have said that exactly this approach also works for Exercise 4 and that is true, but not the way you have taken it. A freeze.control process placed between print.streams and the external screen! channel is good. But that freeze.control process is not the monitor – it is a different process, something extra.

Re. other bits of your code: your speed.control has an ALT with only one guard – see the third paragraph in the answer to Question 14 (2012). I think you mean to poll that channel (i.e. you need to PRI ALT that guard against a SKIP, see "Choice" slide 30).

Keywords: q4


Question 24 (2012):

Submission reference: IN2176

For the diagrams for Assessment 3, do you want us to label the channels or just leave them unlabelled? Thanks.

Answer 24:

See the last paragraph in the answer to Question 23 (2012).

Keywords: q4


Question 23 (2012):

Submission reference: IN2175

For the graphs, the email said we must provide diagrams for pairs2 and:

    - your overall "q4" network.  Along with other processes, this should show
      the modified "numbers2", "integrate2" and "pairs2" just as black boxes
      (no internal details, as in the diagram on page 5 of 'more-exercises.pdf').

Do you want the internal details of monitor, speed, freeze, print.streams? Or just show the channels?

Answer 23:

The only diagram language we have presented ("Overview" slides 28-35) is for networks of processes running in parallel. The modified numbers2, integrate2 and pairs2 processes are implemented by such networks, so diagrams are part of their design spec and should be documented somewhere. We've already given you the diagrams for numbers2 and integrate2, so we have only asked for a diagram for pairs2 (from these three).

For the processes monitor, speed.control and freeze, we are only expecting implementations that are purely sequential (i.e. contain no internal PAR networks). Therefore, there is nothing to diagram: just draw these processes as shaded (or empty) boxes (or whatever shape you like). We do not draw diagrams for sequential code – programming language syntax is good enough, or should be!

Of course, should you happen to implement monitor, speed.control or freeze as a network of internal processes running in parallel, please submit the diagrams showing this. However, sequential logic is simplest for these.

The process print.streams (which we provided) has an internal PAR, but the processes set up are short-lived (just a single channel input) and have no channel connections with each other. Its logic is mainly sequential, going parallel temporarily at the start of each loop. Such changing forms cannot be diagrammed statically. Instead, we need a movie (or, at least, a cartoon strip) showing the changing forms. For print.streams, we would need two diagrams showing its two states (and document somewhere that it continually switches between them):

    (sequential state)

                      ----------------------------------
                      |                                |
           in[0]      |                                |
       ------->-------|                                |
                      |                                |
                      |                                |
           in[1]      |                                |      out
       ------->-------|          print.streams         |------->-------
                      |       (col.width, delay)       |
                      |                                |
           in[2]      |                                |
       ------->-------|                                |
                      |                                |
                      |                                |
                      ----------------------------------



    (parallel state)

                      ----------------------------------
                      |                                |
           in[0]      |      -------------------       |
       ------->-------|------|                 |       |
                      |      -------------------       |
                      |                                |
           in[1]      |      -------------------       |      out
       ------->-------|------|                 |       |------->-------
                      |      -------------------       |
                      |                                |
           in[2]      |      -------------------       |
       ------->-------|------|                 |       |
                      |      -------------------       |
                      |                                |
                      |          print.streams         |
                      |       (col.width, delay)       |
                      ----------------------------------

The sequential state of the above is just blank (as are all sequential states). The parallel state is fairly bland: the internal processes are anonymous and unconnected (each being a single input from an external channel). So, this is not really worth doing and we haven't asked for it. Anyway, we provided this process – the diagrams we want are for new processes you are writing.

Aside: occam-pi supports concurrency that can be very dynamic. Modelling complex systems, such as biological mechanisms, often requires dynamism as living entities (represented by concurrent processes) are "born", move around some world (represented by more concurrent processes), break old connections (channels) and make new ones, combine with each other, split apart and, eventually, "die". Programming such systems is aided by drawing "cartoon strips" showing the possible sequences of network configurations in representative parts of the whole system and representative circumstances – we need these cartoon strips for initial design and subsequent implementation and maintenance. An example is shown in the "Overview" slides 71-82: we still have to talk you through those slides but, hopefully, you can see the idea.

Summary: there are no internal concurrency details for monitor, speed.control or freeze to diagram (unless you have an interesting, but unexpected by us, implementation!). We provided print.streams, so we have not asked you to diagram that (and it's not really worth doing – see above). Your implementations of pairs2 and the whole system q4 each have (or should have) a fixed internal network of sub-processes, so we have asked for one diagram each for them. The q4 process will have instances of monitor, speed.control, freeze and print.streams: these should be shown as empty (or shaded) boxes.

As said in the posting to everyone, external channels must be labelled (with the parameter names used in your code) and the directions of all channels must be indicated (by arrow-heads). Internal channels need not be labelled – but, if they are, either label them with the name of the internal channel used in your code or by the keyboard characters that cause messages to be sent along them (note: the latter is only for the channels leaving the monitor process, as shown in the exercise sheet).

Keywords: q4

Referrers: Question 24 (2012)


Question 22 (2012):

Submission reference: IN2174

For Assessment 3, will be be marked down if there is a delay from when buttons are pressed? At the moment there is a 3 line delay from then 'n' is pressed till when the numbers column resets to 0, will this be a problem?

Answer 22:

No – that's OK. See Question 14 (2010).

Keywords: q4


Question 21 (2012):

Submission reference: IN2172

I have tried to implement the same functionality from my working question 3 for freezing in question 4 by taking the whole of a multiplex? array of channels (which has the information to be printed) on through the monitor process.

I know I must be doing soemthing wrong because it doesn't compile and gives the error "left-hand side must be of type CHAN, PORT, or TIMER" twice relating to two of the lines. I've looked at it for ages and can't work out why it's saying this as the thing in question is of []CHAN INT type and if it wasn't my idea of how to implement freeze that I did in class for Q3 wouldn't work.

Here is my full code for the monitor process and q4 network:

    PROC monitor (CHAN BYTE keyboard?, CHAN INT reset.numbers!,
                  CHAN INT reset.integrate!, pairs.flip!,
		  []CHAN INT multiplex?, out!)
      BYTE keyboardBuffer:
      INITIAL BOOL running IS TRUE:
      INITIAL MOBILE []INT multiplexBuffer IS MOBILE [SIZE multiplex?]INT: 
      -- Not sure if I need to do the above?
      -- Copied it from print.streams so I could declare an array of size
      -- unknown to the compiler.
      WHILE TRUE
        ALT
          keyboard ? keyboardBuffer
	    ...  Ed: response hidden (may change value of 'running')
          running & multiplex ? multiplexBuffer  -- <<< COMPILER ERROR HERE
	    out ! multiplexBuffer                -- <<< COMPILER ERROR HERE
    :

Answer 21:

Sorry – I can't parse/understand the second sentence in the second paragraph of your question.

I'm assuming your multiplex channel array are the three channels the flow from the two delta processes and pairs2. Rather than route this array back through monitor, it would be simpler to route a single channel from print.streams instead – that carries all the information (needed eventually to get to the screen!).

However, routing any of these channels back through monitor is a classical mistake. It sets up a feedback loop over which you have no control of the amount of traffic (because numbers2 is always generating). If the loop gets full with every process trying to output something, deadlock results. If we design a feedback loop in our circuits (and we do this frequently), we must be able to limit the amount of traffic (as in the resettable versions of the parallel implementations of numbers and integrate, used elsewhere in this exercise).

Presumably, you are doing this so that the monitor can freeze and/or control the speed of this traffic flow. But this is dangerous (see last paragraph). Instead, get monitor to send messages to other processes to do the freezing and speed control. This can be done without setting up any feedback loops.

Your lines that don't compile:

          running & multiplex ? multiplexBuffer  -- <<< COMPILER ERROR HERE
	    out ! multiplexBuffer                -- <<< COMPILER ERROR HERE

make some sense. I think you are wanting to use as a guard the arrival of messages on all of the multiplex? channels, the catching of the messages in corresponding elements of the multiplexBuffer data array, and with the response being the forwarding of all those messages to the out! channels.

However, the input and output symbols (? and !) can only be used for receiving or sending messages from or to a single channel, not an array of channels (which is why your lines won't compile). Your second line could be implemented as follows:

	    PAR i = 0 FOR SIZE out!              -- these will
	      out[i] ! multiplexBuffer[i]        -- compile

But occam-pi does not allow the parallel replication of primitive processes as an individual guard, so there's nothing we can do to rescue the first of your two lines. There are ALT replicators in occam-pi (see "Choice" slides 109 onwards), but we've not done them yet in the course. Anyway, they do not do what you were wanting here.

However, what you should not have been wanting to do that. What you were trying to do was too complex (a single channel could have been used) and unsafe (the feedback loop in the resulting design has an uncontrolled volume of traffic and would lead to deadlock).

Keywords: q4

Referrers: Question 25 (2012)


Question 20 (2012):

Submission reference: IN2173

I am on the last stage of the assessment that asks us to implement the speed.control process.

Should we be keeping the array of 3 channels both going into and coming out of the speed.control process (and then going into print.streams), or is there a better way to do this still without altering print.streams?

Also, any general advice on what to think about when implementing speed.control is much appreciated as I am having difficulty getting my head around how to control the number of lines that will be output each second!

Answer 20:

Only one of the channels into print.streams needs controlling. You need to work out why this is true – it's important that you see this.

Once you understand the above, your speed.control process needs only one channel in and one out. Of course, a control? channel is needed as well, on which speed-up or slow-down messages arrive.

For a required speed (lines per second), work out the delay needed between lines and use the given 'pause' process. See either of the model answers ('a1.occ' or 'a2.occ') for code that sets the line speed at the start of execution (but does not let you vary it).

However, that solution has a problem. If we have the pause delay up to one second (i.e. one output line per second) and we want to speed it up, the response to a '+' keystroke will be sluggish. If we key the '+' at the start of a one second pause in the output, nothing can change in the output until that one second pause has completed.

It would be much better for the system to respond to the '+' straight away and for the output to speed up immediately. This can't be done using the given 'pause' process – a timeout guard in the ALT is needed.

Keywords: q4


Question 19 (2012):

Submission reference: IN2171

Hello, for q4 do we leave the comments at the beginning of the file in or shall we delete them?

Answer 19:

It would be nice to delete those comments (that we wrote) from your submission file – lets us get to your code quicker (and saves paper if we print). But we haven't asked for this, so it's perfectly OK to leave them.

Of course, you should include appropriate comments about your own code.

Keywords: q4


Question 18 (2012):

Submission reference: IN2170

I'm having a problem with my monitor method in Q4. If I write:

    BYTE k:
    keyboard ? k
      number ! k

obviously this won't work because of the change in data type. I've been stuck on this for the past few days, wondering if you could work out where I'm going wrong. I can't seem for the stream to continue – it just outputs nothing.

    PROC monitor (CHAN BYTE keyboard?, CHAN INT number!, integrate!)
      WHILE TRUE
        PRI ALT
          BYTE k:
          keyboard ? k
	    ...  (Ed: response hidden, but looks good)
          BYTE k:
          keyboard ? k
            SKIP          -- Ed: was this where you wanted: number ! k
    :

Answer 18:

First, the monitor needed for Q4 is a process and definitely not a method! ;)

But I don't know why you want to send down an INT-carrying channel a character received from a BYTE-carrying channel? If you really wanted to do that, you would have to cast the character into an INT:

    BYTE k:
    keyboard ? k
      number ! INT k        -- send ASCII code (as an integer)

See "Basics" slide 30, the program casting.occ in your examples folder and the Q&As linked from "cast" in the keyword-index of the anon Q&As ... for further information about type casting in occam-pi.

However, I'm sure you don't want to do this (and you certainly don't need to).

The code you posted (outlined in the question above) shows that you also have some misunderstanding about the ALT (or PRI ALT). You have two guards that are the same! This means: wait for the guard to become ready, when one becomes ready both become ready (because they are the same), the second guard will never be chosen (because it is listed after another guard that's ready in a PRI ALT), so execute the first guard and the process it is defending. Again, I'm sure that's not what you intended.

The monitor process does not need an ALT (or PRI ALT). All it has to do is wait for something to arrive on its keyboard? channel and respond (as you are doing in the response I hid in the code in your question).

Hope this helps.

Keywords: q4 , cast


Question 17 (2012):

Submission reference: IN2169

I am currently on the speed.control part of my Q4.

I have initialised delay and have set it so that each button (+ and -) changes it how they should (I don't want to give too much away - if you need to look at my code, I can email it).

What happens is that it's SUPPOSED to start at 32 lines/sec. However, for reasons unknown to me, it starts at 16 lines/sec. Here's what happens if I press +/-:

    Starts at 16 lines/sec
    MINUS - It stays at 16 lines/sec (as if it were at 32 lines/sec)
    MINUS - It goes to 8 lines/sec
    MINUS - It goes to 4 lines/sec
    MINUS - It goes to 2 lines/sec
    MINUS - It goes to 1 line/sec
    PLUS - 2 lines/sec
    PLUS - 4 lines/sec
    PLUS - 8 lines/sec
    PLUS - 16 lines/sec
    PLUS - Stays at 16 lines/sec
    PLUS - Stays at 16 lines/sec

I have not yet implemented the BELL part of it, so I tested PLUS out by constantly spamming it when I was at my 16 lines/sec. Eventually, it gets to something ridiculous like 1000 lines/sec and actually does change to it, so it goes from 16 to 1000 if I hit + the right amount of times. I can not actually MINUSfrom there.

Where could I be going wrong in my code for this to happen? I know that I haven't implemented BELL yet, but I can't imagine not having that would stop my code from coming out at 32, 64, 128 etc lines/sec.

Answer 17:

Thank you for mailing me your code separately. I hope my reply was helpful.

For the others, a common mistake was being made (though this doesn't explain all the bad behaviour described, but is probably one of the causes). This mistake was placing the speed control process between print.streams and the external screen! channel. If you do this and delay (by the computed amount) every BYTE that passes, it is controlling characters (not lines) per second. If the average line length were 60 characters, then the lines per second being managed would be 60 times slower than intended.

A quick fix is only to do the pause when an end-of-line ('*c') goes past! However, there is a more efficient (and simpler) way.

Keywords: q4


Question 16 (2012):

Submission reference: IN2168

What is the exact syntax for outputting BELL along the error channel? I am simply writing:

    error ! BELL

and getting an "I/O list item 1 does not match protocol" compile error.

Answer 16:

That compiler error message is generated if BELL has a type that is different from that carried by the error! channel.

The include directive:

    #INCLUDE "course.module"

in the program file makes available lots of things, including BELL (which is defined as a BYTE constant with VALue 7, the ASCII code for bell). So long as you haven't re-declared BELL with another type in your own code following that directive, it has type BYTE.

How is the error! channel declared, somewhere above your line that doesn't compile? It should be a "CHAN BYTE error!" parameter. If it is, then your line will compile. Honest!

For the code to execute correctly, that "CHAN BYTE error!" parameter must be connected to the second output channel parameter of the main q4 process (also called error! in your starter code file, q4.occ). At least, the ASCII code in BELL will be delivered to the terminal window running your program. So long as that terminal window is configured to react to that code (e.g. by pinging or flashing the screen or both, as does the occPlug window), then all will be well.

Beware that some older releases of the Transterpreter required the error! to be flushed, in the same way as needed by the screen! channel. The current Windows version (20110201.1855) does not have that requirement.

Correct (Unix) behaviour for the standard error channel is that anything sent there is delivered immediately to the terminal window. For the standard screen channel, characters are buffered until either an end-of-line ('*c') or flush (FLUSH) is received, or the buffer becomes full: when any of these things happen, the buffer is flushed to the terminal window.

Keywords: q4 , flush


Question 15 (2012):

Submission reference: IN2167

In the last lecture (Friday, 19 Oct), someone asked about the position of the replace gadget in the integrate process with a reset line ("Choice" slide 52): could it have been placed on either of the other two internal channels instead? Could you go over that again please?

Answer 15:

I don't think I answered that question very well, changing my mind to say: "yes, it doesn't really matter where the replace is placed in the circuit". That's true ... but only if we take a fairly relaxed view of the semantics of the device. If we take a strict view, there are low-level differences in the behaviours possible from the device, depending where that replace is placed – see below. However, for real-time control applications, such as the inertial navigation component described in "Choice" slides 53-56 (and in the "occam Approach to Transputer Engineering" paper), we can take the relaxed view – see the end of this answer.

A simpler system to consider first is the numbers.reset circuit in slide 49. If no resets are sent, this just generates: 0, 1, 2, 3, 4, 5, etc. Suppose we send the number 42 down the reset line just once. The output sequence depends, of course, on when that reset happens. Possible output sequences are:

    42, 43, 44, 45, 46, 47, ...
     0, 42, 43, 44, 45, 46, ...
     0,  1, 42, 43, 44, 45, ...
     0,  1,  2, 42, 43, 44, ...
     0,  1,  2,  3, 42, 43, ...
     0,  1,  2,  3,  4, 42, ...
     etc.

However, if the replace gadget were spliced into the d channel (between succ and prefix), there is no way the 42 could ever get in quick enough to prevent the first 0 from coming out – i.e. the first output sequence line above would not be possible.

If replace were spliced into the c channel (between delta and succ), not only could the first 0 not be replaced but the reset sequence could only start from 43. Possible output sequences are:

     0, 43, 44, 45, 46, 47, ...
     0,  1, 43, 44, 45, 46, ...
     0,  1,  2, 43, 44, 45, ...
     0,  1,  2,  3, 43, 44, ...
     0,  1,  2,  3,  4, 43, ...
     etc.

So, the actual reset number, 42, would not come out.

Compare the above with what the numbers.reset serial implementation (slide 50) can do with the same scenario (a single reset of 42). If the reset happens early enough, the 42 will overwrite the variable n on the first loop and will come out first – the 0 will not be seen. I hope it is clear that the possible output sequences are the same as the first set above – i.e. the same as those produced by the parallel implementation (slide 49), with the replace gadget between prefix and delta. So, for this scenario anyway (and actually for all), the two implementations of numbers.reset (slides 49 and 50) give rise to the same component – at least, if we are only considering the possible output sequences they produce. If the position of replace in slide 49 is changed, we have noted differences in the possible output sequences, which may or may not be significant (depending on the application in which it is used).

The "at least" qualification two sentences back needs explaining. The full semantics of a device is more than just the outputs it makes for given inputs and the timings of those inputs. We need also to know about the patterns of all events (i.e. input and output communications and, later, barrier synchronisations) in which it can engage. For instance, how may the inputs events interleave with output events? In many circumstances, we need this information to avoid deadlock.

When we consider possible interleavings for the numbers.reset implementations of slides 49 and 50, some differences do emerge. In the serial implementation (slide 50), here is the sequence of events when a single reset event occurs:

                    ...
                    out ! x
                    out ! x + 1
                    out ! x + 2
        reset ? y
                    out ! y
                    out ! y + 1
                    out ! y + 2
                    ...

where time is flowing downwards and x and y represent generic values. Note that the output of the reset value is the next event following the reset input. No other interleavings of input and output events are possible.

Now, consider the parallel implementation (slide 49). The above sequence is certainly a possibility but so, also, is the following:

                    ...
                    out ! x
                    out ! x + 1
                    out ! x + 2
        reset ? y
	            out ! x + 3
                    out ! y
                    out ! y + 1
                    out ! y + 2
                    ...

It all depends on where the previously cycling number is in the feedback circuit when the reset is taken by replace. If it is in succ or prefix, we will get the first pattern. If it is in delta, we will get the second.

So the parallel and serial implementations of number.reset are different. The serial form is more constrained in the way it syncrhonises with its environment (i.e. the other processes in the network in which it is embedded). Everything it does can also be done by the parallel version, but the parallel version may choose to do things differently.

Note: when considering the semantics of a process, it is only its impact on its environment that is relevant. That is why, when thinking about the patterns of events in which a process can engage, it is only those that interact with its environment (e.g. external input and output channels) that are important. Hence, in the above sequence (and the ones that follow), we only include events involving the channels from the parameter list – not the internal ones.

Now, let's get back to the integrate process, first comparing the serial and parallel versions of the original process – the one without any reset channel. Consider the serial version (slide 57). Its synchronisation pattern is tightly constrained: a strictly alternating sequence of inputs and outputs:

                    ...
                    out ! r                   -- running total, so far
        in ? x
                    out ! r + x               -- running total, so far
        in ? y
                    out ! r + x + y           -- running total, so far
        in ? z
                    out ! r + x + y + z       -- running total, so far
                    ...

This serial version "buffers" one item of the flow of numbers from its input channel to its output (i.e. in any state, the number of inputs it has taken is either the same as its number of outputs or one more).

As noted in "Basics" slide 94, the parallel version "buffers" two items of the flow of numbers from its input to output (i.e. in any state, the number of inputs it has taken is either the same as its number of outputs or one more or two more). This allows it greater flexibility in the way it synchronises. The above pattern can certainly happen, but so can:

                    ...
                    out ! r                   -- #in? = #out!
        in ? x                                -- #in? = #out! + 1
        in ? y                                -- #in? = #out! + 2
                    out ! r + x               -- #in? = #out! + 1
        in ? z                                -- #in? = #out! + 2
                    out ! r + x + y           -- #in? = #out! + 1
                    out ! r + x + y + z       -- #in? = #out!
                    ...

where "#in?" means the number of inputs so far and "#out!" means the number of outputs so far. Other patterns may occur, so long as:

    0 <= (#in? - #out!) <= 2

Note that, viewed separately, the output sequence for any given input sequence is the same for both the serial and parallel versions. However, the difference in buffering capacities may be significant for deadlock analysis. The more constrained pattern of synchronisation forced by the serial version increases the potential for deadlock in a poorly designed application that uses it.

Now consider the serial and parallel versions of integrate.reset ("Choice" slides 51 and 52). The serial version still buffers only one running total (either the most recently computed value or one that's just been reset). Its synchronisation pattern is also tightly constrained: a strictly alternating sequence of either an input or reset event, followed by an output event. For example:

                    ...
                    out ! r                   -- running total, so far
        in ? x
                    out ! r + x               -- running total, so far
        in ? y
                    out ! r + x + y           -- running total, so far
        reset ? a
                    out ! a                   -- the reset running total
        in ? z
                    out ! a + z               -- running total, so far
                    ...

The parallel version (slide 52) can buffer up to three running totals: one in plus (the most recent), one in replace (either the second most recent or a reset value) and one in delta (the oldest). This gives much greater flexibility to the patterns of synchronisation possible. Again, the above pattern is possible. But also:

                    ...
                    out ! r                   -- running total, so far
        in ? x                                -- 'r+x' moves through 'replace' to 'delta'
        in ? y                                -- 'y' only gets into 'plus' (which needs its other input)
        reset ? a                             -- 'a' gets into 'replace'
                    out ! r + x               -- running total, so far
		                              -- 'r+x' fed back through 'prefix' to 'plus'
					      -- 'r+x+y' computed, moves to 'replace' and is discarded
					      -- 'a' moves into 'delta'
                    out ! a                   -- the reset running total
        in ? z
                    out ! a + z               -- running total, so far
                    ...

and many others. Notice that in the above sequence, one of the running sums of input values (r+x+y) never emerged. Whether missing this value is significant depends on the application.

Now, consider what happens if the replace gadget in the parallel implementation (slide 52) were positioned elsewhere. For one thing, the buffering capacity between the in and out channels drops back to two. If replace were spliced into the channel between prefix and plus, the reset value would never emerge as itself – it would always first have been added to the next input value. For example:

                    ...
                    out ! r                   -- running total, so far
        in ? x                                -- 'r+x' moves to 'delta'
        in ? y                                -- 'y' only gets into 'plus' (which needs its other input)
        reset ? a                             -- 'a' gets into 'replace' and moves on to 'plus'
	                                      -- 'a+y' computed in 'plus', cannot move on yet
                    out ! r + x               -- running total, so far
		                              -- 'r+x' fed back through 'prefix' to 'replace', which discards it.
					      -- 'a+y' moves to 'delta'
                    out ! a + y               -- the reset running total (with added 'y')
        in ? z
                    out ! a + y + z           -- running total, so far
                    ...

In the previous example, the contribution of 'y' was never seen in the running sum outputs. This time it is, but added to the reset value (which is not seen directly).

If replace were spliced into the channel between delta and prefix, the reset value would never emerge as itself – it would always first have been added to the next input value (as for the previous version). The difference is at start-up – there is no way a reset could happen fast enough to prevent the first output from always being the first input added to the initial 0 from prefix (i.e. the first output is always the first input).

  Brief Note on Formal Semantics

A sequence of events (channel communications and, later, barrier synchronisations) in which a process can engage is called a trace.

The last 7 sequences above show extracts from traces of the processes being considered. For clarity, we've listed them in two columns: one for input and one for output. For traces, consider them listed in one column, keeping the ordering.

CSP (Communicating Sequential Processes), the formal algebra that underlies occam-pi, defines three semantic models with increasing capabilities: traces, failures and divergences. The simplest is the traces model, which enables verification of safety properties (e.g. that a process will not do something bad). The other two concern liveness properties (e.g. that a process will actually do something): failures enable deadlock analysis and divergences address livelock.

In the traces model, the semantics of a process is just defined by: the set of all its possible traces. Two processes are equivalent if their traces are the same set. A process, P, is a refinement of a process, Q, if the traces of P are a subset of the traces of Q. This is where safety analysis comes in: if a process Q is known to have safe behaviour and we implement a process P and prove that it refines Q, then we know that P also must be safe (because every trace that P can do, Q can do and Q only does safe things). In such a scenario, Q is usually described as a specification for P.

  Summary

The position of the replace component in the parallel circuits of numbers.reset (slide 49) and integrate.reset (slide 52) does impact on their formal semantics.

The serial numbers.reset (slide 50) is a traces refinement of the parallel implementation in slide 49. The serial integrate.reset (slide 51) is a traces refinement of the parallel implementation in slide 52.

If, however, the replace component is repositioned somewhere else in the circuits, there is no formal relationship between the serial and those parallel versions. Whether the differences (see earlier) matter depends on the applications to which they are put.

For the inertial navigation component (slides 53-56), they don't matter. All the versions of integrate.reset (serial or any of the three parallel implementations considered above) deliver running sums and allow resets at any time. The precise interleaving of inputs, resets and outputs doesn't matter – the important matter is the accuracy of the input sample values and the accuracy of their sampling times (which must be evenly spaced). If some running sum is discarded when a reset happens, it doesn't matter: that value was suspect anyway, which is why integrate.reset was being reset. If the reset value does not get output itself, it doesn't matter: the value that comes out is the reset value plus the latest input, which is more up-to-date than the reset value alone. Finally, if we can't reset before the first number appears after integrate.reset is switched on, who cares?

Keywords: q4 , csp , formal-semantics , reset


Question 14 (2012):

Submission reference: IN2166

I have had a little bit of trouble implementing the flip behavior to pairs expressed in Q4. I understand what it is meant to do but struggling at finding a way of implementing it that isn't long and overly complicated. I wanted to avoid a modified plus process inside pairs2 and wanted to introduce the new component to do the job as this makes the most logical sense in terms of the rest of the program. It also suggests that a suitable process has been described and from looking through those available I felt that the closest match would be the (Ed: rest of sentence deleted as it gives too much away).

I simplified my (Ed: name deleted) process slightly and with my code currently looking like this I get no output. Confused at what's going on! I've tried running through process diagrams on paper and still stuck ...

    PROC pairs2 (CHAN INT in?, flip?, out!)
      CHAN INT a, b, c, d, flip.decision:
      INT any:
      ...  (Ed: variable declaration hidden, used in flip response below)
      WHILE TRUE
        SEQ
          PRI ALT
            flip ? any
              ...  (Ed: response to flip guard hidden)
          PAR
            delta(in?, a!, c!)
            tail(a?, b!)
            ...  (Ed: process instance hidden)
            plus(b?, d?, out!)
    :

Answer 14:

Your pairs2 has two errors.

The biggest one is that you start a PAR network of processes – all of which run forever – in the body of a WHILE loop. The first time that loop is entered, once it reaches that PAR all the components of that PAR start up and never finish. So the loop never loops, only executing the PRI ALT (at the start of its body) just the once. That's probably not what you meant to happen.

The second error is that your PRI ALT only has one guard. That means just wait until that guard is ready. The code may as well have been written:

    PROC pairs2 (CHAN INT in?, flip?, out!)
      CHAN INT a, b, c, d, flip.decision:
      INT any:
      ...  (Ed: variable declaration hidden, used in flip response below)
      WHILE TRUE
        SEQ
	  flip ? any
	  ...  (Ed: response to flip guard hidden)
          PAR
	    delta(in?, a!, c!)
	    tail(a?, b!)
	    ...  (Ed: process instance hidden)
	    plus(b?, d?, out!)
    :

Again, that may not be what you wanted.

These two misunderstandings need correcting. Hopefully, what needs to be done then becomes much clearer. Your modified (Ed: name deleted) process looks good.

Keywords: q4

Referrers: Question 25 (2012)


Question 13 (2012):

Submission reference: IN2165

In question 4, we have to deal with an array of channels. I was wondering what the syntax is for doing so in regards to the parameter that goes in the call to print.streams?

Answer 13:

See "Basics" slide 101. That instance of print.streams takes the input-ends of an array of 4 channels. In Q4, print.streams needs the input-ends of an array of 3 channels. The syntax for this is the same – the number of channels in the array doesn't matter.

Keywords: q4


Question 12 (2012):

Submission reference: IN2164

I'm currently working on Q4 and while my freeze/error-inducing process in Q3 works exactly as specified/intended, I can't seem to get the control working in Q4 for reasons I don't understand.

Here is the code for my monitor process, which is only trying to enable my numbers2 process to be reset:

    PROC monitor (CHAN BYTE in?, CHAN INT numbers!)
      ...  (editor) code omitted
    :

It should do, as far as I can see, run round the loop doing nothing until an 'n' is pressed – when it should output a 0 to the numbers! channel. The problem is that when I try and insert it in to the network it causes all output to stop from the numbers2 process, defined as such:

    PROC numbers2 (CHAN INT out!, reset?)
      ...  (editor) code omitted
    :

The process will also not respond to any keyboard input.

If I remove my monitor process from the network, the numbers2 process functions fine ... so it certainly feels like it should be my monitor process that's causing the issues. Am I missing something very obvious?

Answer 12:

Your monitor is not running "round the loop doing nothing until an 'n' is pressed". It is busy polling the keyboard channel! It uses a PRI ALT governing that channel against a SKIP guard. If no key press has been made, the keyboard input guard is not ready and the PRI ALT takes the SKIP guard. The latter was defending only a SKIP (i.e. do nothing) process, so execution loops around back to the PRI ALT.

Your monitor process is continually active, racing round this polling loop over 100,000 times per second on the Transterpreter (or more than 100,000,000 times per second with the KRoC runtime), consuming every processor cycle available. The other processes can make little headway against this torrent of (useless) activity – the system is effectively livelocked. Take a look at the processor loading (e.g. on the Windows Task Manager) when this is running – one of the cores will be almost at 100%, with the others mostly idle (the Transterpreter does not multicore schedule). If you're using KRoC (which does multicore schedule), the system will work ... but one of the cores will be at 100% loading and getting rather hot. All that work is quite unnecessary and unacceptable for a real-time system (with hard deadlines to meet) or an embedded system (with limited battery life).

This is a classic mistake – see the warning at the bottom of "Choice" slide 30.

Solution: save the planet and don't poll for keyboard input! Just wait for one to arrive (i.e. all you need is the input line). Waiting for a channel input costs nothing in processor loading and the waiting process jumps to life when something arrives.

Keywords: q4


Question 10 (2012):

Submission reference: IN2162

Question 4 for the assessment states: "New processes, numbers2 and integrate2, must be made that accept the new reset signals and respond appropriately. Maintain the same style of implementation as before. Don't modify any internal processes – but insert an extra one somewhere to do the job."

It also states earlier that numbers, integrate and delta are accessible from the course.module included. If we have to redefine numbers2 and integrate2 based on the ones included, is there anywhere on raptor etc. where we can look them up and copy the code from course.module into our q4.occ file and then make changes to them?

Answer 10:

Sorry, I thought the source files for course.module were in the Transterpreter release, which most have downloaded. They certainly are in the Kroc release, which is worth getting if you have Linux or a Mac (look for modules/course/libsrc).

Of course, you must have these source files and I have copied them to raptor (and swallow) at:

    \courses\co538\course-module\             (read the README.txt)

You don't really need these files to copy numbers, integrate etc. to your q4.occ starter file and then edit into the extended versions needed for the exercise. They are only 7 lines of code each and, anyway, can be copy-pasted from "Choice" slide 88.

You need these files for curiosity browsing and studying. Many of the processes have implementations that are really complex and scary (e.g. course.REAL32TOSTRING in float_io.occ, which converts a 32-bit floating-point real into ASCII text – a task that just is complex and scary). Ignore those! But there are a lot that will reward reading. Be curious. We are always here to answer your questions.

Keywords: q4

2011

Question 29 (2011):

Submission reference: IN2060

its cutting it a bit fine i know, but how do i ipmlement the speed control section for the last part of the assigemtn, ive been sticuk on thisfor ages, ive fiigured out that i need to use a timer, im just not sure how best to utilize it.

Answer 29:

I'm afraid you have to ask questions a little more specific than: "how do I do this part of the assignment?".

However, we will say this ...

The model answer has two versions for speed.control. Version 0 uses only the pause(delay) procedure to control output line speed: it has to respond to speed control signals and, of course, the data flow it's controlling. It is very simple but has some not good properties (such as not being able to respond promptly to speed-up signals when executing a long pause). Nevertheless, it would get good marks, :).

The other version uses TIMERs directly and responds quickly to speed-control signals at all times – but it's a bit more complex.

Keywords: q4


Question 28 (2011):

Submission reference: IN2059

Hi, I'm really struggling with the speed.control section. I have a process that takes 1s and 0s given to it by my monitor, and then sends then either halves them, or doubles them depending on what is received. This is then sent to another process which takes a value from the speed.control process, and outputs a line of digits. After doing this, it checks with a timer to see if the time figure is greater than speed. If it is, it waits until the timer has again passed the speed value. The problem is, when I key plus or minus, nothing seems to happen? Any thoughts on where I've gone wrong?

Answer 28:

I don't understand what you means by "either halves them, or doubles them depending on what is received"? You say your process is receiving 0s and 1s, presumably these are INTs? But if so, halving a 0 or a 1 gets 0, doubling a 0 gets 0 and doubling a 1 gets 2. I don't understand how that helps ...

You also talk about comparing a "time figure" with a "speed" ... which is like comparing chalk with cheese. You should only compare time values against time values (which may have been calculated from a previous time value and a gap interval). For example, the gap interval (in microseconds) for a speed of 256 lines per second would be 1000000/256.

Hope this helps ...

Keywords: q4


Question 26 (2011):

Submission reference: IN2056

I am having trouble implementing the "pairs2" process for the 3rd assessment. Below is what I have so far, but it doesn't work:

    PROC pairs2 (CHAN INT in?, out!, inject?)
      INITIAL BOOL flip IS FALSE:
      WHILE TRUE
        PRI ALT
          INT injected:
          inject ? injected
	    flip := NOT flip
          SKIP
	    CASE flip
	      FALSE
	        pairs (in?, out!)
	      TRUE
	        differentiate (in?, out!)
:

Answer 26:

Please never show someone your code and ask why it doesn't work! Instead, explain why you think it does work – i.e. talk through the code, saying what you are expecting it to do and saying why. Nine times out of ten, either yourself or the person to whom you are explaining will then see why what you are saying is wrong: some unfounded assumption you have made or something wrong with the mental model you have about the ideas/constructs you are using.

The problem here is that once either "pairs" or "differentiate" is instantiated in the above code, it never terminates (because its components all have infinite loops). This is the mistake in your mental model of what is happening here. As a result, the loop in your "pairs2" above will never loop! As such, any attempt to communicate on the "inject" channel after either "pairs" or "differentiate" has been started (and that will be within nanoseconds of the start of your system) will not be accepted and your "keyboard.monitor" will be forever blocked. Your system should still be running ... but you have lost control.

The correct way to go about this is to change something inside the existing "pairs" process, rather than trying to replace the whole thing. However, if you can't figure out that particular solution, you can have both "pairs" and "differentiate", but running in parallel, with a switch process at the front (which sends data to one or the other) and a simple multiplexer component at the other side which collects output from both. However, that's a rather heavyweight solution, but at least it works!

Keywords: q4


Question 25 (2011):

Submission reference: IN2054

To partially answer my own question (invalid reference to another question!); the deadlock seems occur arbitrarily whenever the output lines per second is > 32. I was running the program directly from vim (!./q4), which I presume buffers and can't output quick enough?

There is no deadlock if I run the program directly from the terminal (urxvt).

Answer 25:

That is slightly odd — even if vim doesn't take the output quickly, it should just stall the program, not deadlock it completely. KRoC does behave slightly differently if the standard I/O isn't a terminal, but without investigating I'm not sure how vim implements this (i.e. whether it just uses pipes or whether it opens a VT pair for communication).

PHW adds: I just tried running the model answer in the way described (from vim) ... and it works just the same (i.e. correctly) as when run directly.

Keywords: q4


Question 23 (2011):

Submission reference: IN2053

I am at the point where I have an implementation of speed.control. However, pressing any of the monitored keys in rapid succession causes a deadlock. Is this to be expected?

Answer 23:

Probably not — it hints at problem in the design of your solution. Without seeing the code, my immediate thought is to wonder if you have some components polling their control channels, e.g.:

    WHILE TRUE
      PRI ALT
        BOOL any:
        control ? any
          ...  do something useful
        SKIP
          SEQ
            in ? any
            ...  other stuff

Although it takes more than just this, you could end up in a situation where the code above is stuck waiting for data from "in" or a subsequent output, but some other component in the network is stuck trying to send data down the "control" channel, and as a result, is stopping the input (or output) in the above code from happening.

Check for cycles of connected processes in your solution and look for deadlock possibilities in there.

Keywords: q4


Question 21 (2011):

Submission reference: IN2051

Same problem as in Question 18 (2011):

    pause(1000000)

results in waiting about 30 seconds. I am using the Transterpreter on Windows 7 64-bits.

Same waiting time with:

    TIMER tim:
    INT timeout:
    SEQ
      tim ? timeout
      timeout := timeout PLUS 1000000
      WHILE TRUE
        SEQ
	  tim ? AFTER timeout

In order to have about a delay of 1 second, I need pause(33333). But ... pause(1000000) in print.streams does give 1 second.

Answer 21:

I suspect your code ... please send to Fred <frmb@kent.ac.uk>. We won't tell you what's wrong ... but will point to any areas of obvious concern!

Keywords: q4


Question 20 (2011):

Submission reference: IN2049

When I output BELL to error! in q4 it does not BELL error message the console. However, it just exits the program with error code 1.

Is this meant to happen or is there something wrong with my code?

Answer 20:

That should not happen! Please send Fred <frmb@kent.ac.uk> your code.

Keywords: q4


Question 19 (2011):

Submission reference: IN2050

Hi, I am very confused with how to go about implementing the freeze part of q4. Unfortunately, I was not able to do this in q3 either! Help!

Answer 19:

Sorry – can't just tell you the answer ... it's too simple ...

Think this way: a data stream through a channel only flows if the processes through which it is routed are programmed to execute appropriate input and output instructions. If those instructions are not being executed (e.g. the code is doing something else ... like waiting for some signal to resume the flow), the stream cannot flow. The default action is no action. Data flows only if it is programmed to flow. What you see (in your code) is what you get.

Hope this helps!

Keywords: q3 , q4


Question 18 (2011):

Submission reference: IN2047

When I 1 000 000 of delay for the pause method (which should be 1 second when I run it it seems to be delaying for about 70 seconds is this purely down to the TVM or is it something else if so what am I missing?

Answer 18:

The grammar in your question does not parse. So, it's a little difficult to understand.

However, the code:

    pause (1000000)

will pause the executing process one second (= 1,000,000 microseconds) on either the KRoC compiled system (for Linux and Macs) or the Transterpreter (so long as you have not switched it to the runtime for the Lego Mindstorms ... in which case, the pause would be 1,000 seconds (= 1,000,000 milliseconds)). Of course, you must not have changed the implementation of the pause process in your starter file.

There is no way it will result in a delay of around 70 seconds. If still a problem, please mail Fred, <frmb@kent.ac.uk>, your code and ask nicely, :).

Keywords: q4

Referrers: Question 21 (2011)


Question 17 (2011):

Submission reference: IN2048

Hi, I'm just doing the speed control part, and it has come to my attention that there are two different versions of more-exercises.pdf floating around. I personally used the one on raptor, but I have found out from a friend the moodle one says the upper limit should be 256 lines/second, where as the raptor one says it is 1024 lines/second.

Which is it, and can the old versions of files be removed to avoid confusion please?

Answer 17:

I've just checked. There are two ways to find more-exercises.pdf from the Co538 Moodle page: from the Assessment 3 box and from the "Exercise sheets ..." link in the Teaching Resources box. These link to different, but identical, files. The same-named file on raptor (in courses\co538\exercises\) is also identical (and says limit the rate of output to 256 lines/second). Your q4.occ starter file (unless we have made a mistake there) also says 256. The q4.occ on raptor (in courses\co538\exercises\) says 256.

There used to be a version where the limit was 1024. We lowered it because your terminal emulator probably can't go that fast and, if it could, you wouldn't be able to read it! We must have an old version somewhere you can access ... please mail Peter, <phw@kent.ac.uk>, where - thanks!

PS: nobody would lose any marks for setting a limit of 1024 instead of 256.

Keywords: q4


Question 16 (2011):

Submission reference: IN2046

In q4, I'm building the first network diagram where you have to connect all the deltas into the printstream, but it says there are too many actual parameters. Is there any way to resolve this please?

Answer 16:

There is no printstream process. There is a print.stream, but that takes only one input stream and is only used for the first part of this exercise. For the first modification (with the deltas), there are three streams that need printing and the data-flow diagram shows print.streams (plural) to be used.

Note also that print.streams (in your q4.occ starter code) takes four parameters – the third being an array of channels (the three streams, in this case, for printing). See Basics slide 100 for an outline of its use: outline because the example in that slide prints from four channels and, to avoid distraction, does not have the first two parameters (column width and delay) that are defined for the print.streams given in the starter code.

Keywords: q4


Question 15 (2011):

Submission reference: IN2045

This is a follow-up to Question 12 (2011) ...

    PROC freeze.control (...)

Editor: rest of question omitted.

Answer 15:

Thank you for giving more information on the area of your problem. However, without seeing your code, I can't help. The description you give is still not enough to diagnose your error.

If you send me (<phw@kent.ac.uk>) your code, I will point out any misunderstanding of system behaviour that's apparent (but, of course, I cannot correct your code).

Keywords: q4


Question 13 (2011):

Submission reference: IN2044

For assessment 3 (q4), it is required for pairs to be flipped to differentiate on the push of a button and reverse if pushed again. How would I implement this e.g: what is the best structure to use: IF or CASE?

Answer 13:

If there is a 2-valued decision to make, then a boolean expression managed by an IF is appropriate. If there is an n-way decision and (n > 2) and the decision is to choose between a known set of options (represented by constant integer or character values), then a CASE is appropriate.

We have not yet presented the CASE structure in the lectures, but there is a forward reference to it at the end of the the question (Exercise 4) on the more-exercises sheet. The note there recommends its use for processing character input from the keyboard channel (i.e. in your monitor process).

Keywords: q4


Question 12 (2011):

Submission reference: IN2043

In exercise 4, I have a freeze.control proc that takes the output of print.streams. The behaviour is controlled by monitor.

If I do not forward the input to screen AND do not read the input, the program seems to lock (no deadlock error).

However, if I just read the input without fowarding it, I can freeze than restart to output to screen without problems.

I can't figure out why.

Answer 12:

Sorry – cannot understand your question. In paragraphs 2 and 3, to which process does the "I" refer and to which channel does "input" refer? In para 3, to what channel is the input being "forwarded"? Thanks.

Keywords: q4

Referrers: Question 15 (2011)


Question 11 (2011):

Submission reference: IN2042

This question relates to the pairs2 implementation of assessment 3 (q4.occ).

In order to implement this process, I must have a component that will 'flip' the addition to a subtraction. Quoting from the text: "A neater way is to leave the existing sub-components alone, but introduce an extra component into the circuit to achieve the required effect. [A process suitable for this new component has been described in the course.]"

What process is this? I have not seen such a process?

Answer 11:

Answering your questions in reverse order: yes you have ... and you have to find (or re-invent) it yourself! ;)

Keywords: q4

2010

Question 21 (2010):

Submission reference: IN1916

Will we lose marks by not including ASCII data-flow diagrams after adding freeze and speed.control components?

Answer 21:

Nope! We should have asked you to include network diagrams in some form (ASCII art, hand drawn on paper, electronic media) ... but we didn't, :(.

I'm sure you did draw some diagrams anyway – it's very difficult to know what you are doing if you don't!

Keywords: q4


Question 20 (2010):

Submission reference: IN1915

I have a couple of questions regarding the speed.control modification in Assessment 3.

  1. If you halve the initial speed of the system right down to 1 line/second, the system won't let you go any slower than 1 line/second, as specified. But if the speed is doubled at any point by pressing '+' before slowing it right down like this, the slowest the system can output becomes 1 line every 2 seconds. Could you possibly give me any indication why this might be?

  2. Early on in the assessment pdf, when it talks about generalising input to the reset processes, it mentions that monitor should only output zeros. But I use different integer values on a single channel to discriminate between plus and minus signals in my speed.control implementation. Is this acceptable or should I use a plus channel and separate minus channel?

Thanks! :)

Answer 20:

  1. This is not entirely unexpected behaviour in some cases. Not having seen your code, I'm guessing that at some point you cap the integer at the top/bottom to impose the limit. However, the maximum value is probably not a power-of-2 multiple of the initial value, which is why you get this slightly odd behaviour — one sequence of integers as you speed up, which is capped when it reaches the maximum speed, and a different sequence of integers as you slow down (and vice-versa). Hence you get this behaviour. It would be better if you could fix it though — the fact you get the behaviour you describe suggests something is slightly wrong somewhere. Try building a test-rig for your speed.control process to see what it's doing.

  2. What you have is fine — the zeros are only for resetting the number-processing components. The point is that you should be able to reset numbers or integrate to any value, i.e. the reset component used in them is general.

Keywords: q4


Question 18 (2010):

Submission reference: IN1913

Hey, When I add my speed.control before the print.streams method, all of the lines get outputted at once for some reason.

Say I am at 2 lines per second, rather than 1 line being outputted at 0.5 seconds and then the next being outputted 0.5 seconds later, 2 lines are outputted each second.. :( Is this what's supposed to happen? :<

Also, not sure if outputted is a word, but if it isn't it should be >.> Thnx!

Answer 18:

Sorry – that's not supposed to happen! I'm afraid there's something wrong in your speed.control logic (probably).

Sorry – outputted is not a word. The word you are looking for is: output!

Keywords: q4


Question 17 (2010):

Submission reference: IN1911

Hi, I'm currently working on step 3 of Assignment 4 – changing pairs to subtract rather than add. Without wanting to go into too much detail I've got both a modified pairs process and another new process which uses a boolean flag to toggle. The last time I used a flag in such a way it was pointed out to me that it was unnecessary and I'd missed an alternate way of doing things.

Am I going down the wrong road again with regards to this? Thanks.

Answer 17:

Your solution sounds good.

For many cases, remembering state in global variables leads to more complex code than just letting process logic flow through the states (where the state of the process is represented by where the logic has reached, rather than data in a variable).

However, for the toggle process you describe, using a boolean flag (declared global to the loop) is probably simplest.

There are no complete rules for things like this that cover all circumstances we encounter – only guidelines. The guideline two paragraphs above often works simply and elegantly (and is often missed by too much thinking along OO lines) – just not here. Always look for the simplest solution.

Keywords: q4


Question 16 (2010):

Submission reference: IN1912

Hello, my bell isn't working ...

If ALL my code does is output a BELL on the error channel, it works fine! But when I add my processes in, to run AFTER outputting the BELL (SEQ), nothing happens :/

I don't understand! :((

Answer 16:

Sorry – see the answer to Question 15 (2010). You probably have the same trouble and the same fix should work.

Keywords: q4 , bell , beep


Question 15 (2010):

Submission reference: IN1910

In the speed.control process when it comes to outputting BELL nothing seems to happen. I have also changed my code so that whenever I press the '-' key it outputs BELL without doing anything else but this still has no effect (no inverting of colours/screen flash etc). I'm using a Windows machine so in reference to the Question 11 answer this may be different to a Macbook.

Answer 15:

Sorry – this seems to be a bug in the Windows version of the Transterpreter. I finally found a Windows machine and tried the model answer. As you and others have observed, no reaction to BELL, :(. The problem is that characters sent to the error channel are not automatically flushed as per spec (and as we have told you, for example at the end of our answer to Question 11 (2010))!

This is only a problem with the Transterpreter on Windows. On the Mac – and, probably, Linux (I've not tried that yet) – the error channel correctly flushes every character. The kroc run-time also manages the error channel correctly.

We will get this fixed. Meanwhile, wherever you send BELL to the error channel in your solution to q4, follow this with a FLUSH – e.g.

  error ! FLUSH

Apologies.

Keywords: bell , beep , q4

Referrers: Question 16 (2010)


Question 14 (2010):

Submission reference: IN1908

In Q4, while testing I noticed that when pressing 'n' there is a delay between my reset in the increment:

  0  0  1
  1  1  4      <-- 'n' key pressed
  2  3  9
  3  6  16
  4  10 20
  0  10 21     <-- finally!
  1  11 24

This isn't allowed, is it?

Answer 14:

Yes, it is! See Question 7 (2010).

How quick the reaction to your reset is depends on how much is already in the pipeline to the screen ahead of where the reset is processed. The 'n' keypress is processed inside inside numbers2, whose numbers generated in future start again from 0. Ahead of that are numbers already generated in a delta, integrate2, another delta, pairs2 and print.streams. Your reset clearly can have no effect on those numbers and you have to watch them come out of the system before you see the reset 0 (in the first column of screen output).

If your screen output is set very slow (e.g. one line per second), there will be numbers backed up in all stages of the pipeline and the response from the system to the reset will be delayed (as you observed). If your screen output is very fast (and it would need to take around a million lines per second - unfortunately, your terminal window cannot manage that), the pipeline will be empty and the response from the system to the reset will be immediate.  occam-pi is good for real-time control.

Keywords: q4

Referrers: Question 22 (2012)


Question 13 (2010):

Submission reference: IN1907

Hi, For the freeze control in Q4, can I change the whole network diagram from the previous modification or should I stick to the old diagram, but with new processes included??

Answer 13:

Well, you may design a different network diagram if you have a better way of arranging things. However, the question asks for features to be added incrementally – e.g. when adding freeze control, the previous reset controls must be retained.

Process orientation enables safe incremental design and implementation. Because the internal logic and data structure of each process is isolated (strictly private to the process), processes only impact on each other when they communicate (or, we will see later, barrier synchronise) and that can only happen with the explicit agreement of the processes involved. So, nothing can happen to a process behind its back! This means that as we add processes to a network, only those parts of the network to which they are explicitly connected (by channels or, later, barriers) are affected – the rest of the network behaves as before.

There is one caveat to the above. Whilst plugging in new processes cannot alter the behaviour of existing ones (and the sub-networks they form), we do have to ensure that the network overall remains alive. Any modification to a network may introduce a possibility for deadlock and we must take care not to do this! We will be teaching design rules that guarantee freedom from deadlock ... but these are not complete (i.e. they don't cover all the designs we need to make). For the others (e.g. the dining philosophers' college), we need to make individual analyses to remain safe. It is a challenge to make such formal analysis routine ... and, if time, we shall have a go in this course! :)

So in answer to your question here, we recommend incrementally modifying the old diagram (as has been done in the exercise sheet in the four developments of the q4 process network) by connecting in new processes with the necessary behaviour. It's the simplest way to go – for both the freeze and the speed controls.

Keywords: q4


Question 12 (2010):

Submission reference: IN1906

To implement the freeze control, are we allowed to add a new process in Q4? This process would communicate with the monitor process.

Answer 12:

Yes. In general, it's a good idea to implement new functionality with a new process!

The new process for freeze control can be identical to the control process from Q3 (just implementing the freeze part – not the other stuff provoking deadlock etc.).

Keywords: q4


Question 11 (2010):

Submission reference: IN1905

Using the Transterpreter, if you send a BELL down the error channel, is it meant to actually do something, because for me it does nothing or is that just the Transterpreter?

Answer 11:

The BELL character is ASCII code 7 (known as "bell"). On old teletypes, when this was received it actually rang a real bell. On later video terminals, it caused a beep sound. In terminal windows (on modern desktop screens), what happens depends on how your terminal emulator is programmed (sometimes this is user configurable). Many effects are possible:

The terminal window in the Transterpreter JEdit occPlug does the third action above (screen flash) – at least, that's what it does on my Macbook.

Here's a short program (test-bell.occ) that you can cut-and-paste and compile-and-run:

--------------------------------------------------------------------------------

--** Test BELL on screen and error channels.

#INCLUDE "course.module"

--* the main process
--
-- @param keyboard The standard input channel (stdin, in Unix-speak)
-- @param screen The standard output channel (stdout, in Unix-speak)
-- @param error The standard error channel (stderr, in Unix-speak)
--
PROC test.bell (CHAN BYTE keyboard?, screen!, error!)

  BYTE ch:
  SEQ
    
    -- test BELL on screen channel ...
    
    out.string ("screen: this line will end with a BELL (press a key) ...", 0, screen!)
    screen ! FLUSH
    keyboard ? ch
    screen ! BELL
    screen ! FLUSH     -- the effect of the BELL, if any, happens now!
    out.string ("*c*n", 0, screen!)

    keyboard ? ch      -- wait for keypress.  This is to let the terminal
                       -- emulator complete its reaction to the BELL on
                       -- the screen channel.  Otherwise the terminal
                       -- emulator mixes that up with the following text
                       -- sent to the error channel.  By default, screen
                       -- and error channels are crudely multiplexed to
                       -- the same output device.  From Unix, they can
                       -- be separated.

    -- test BELL on error channel ...
    
    out.string ("error: this line will end with a BELL (press a key) ...", 0, error!)
    keyboard ? ch
    error ! BELL       -- the effect of the BELL, if any, happens now!
    out.string ("*c*n", 0, error!)

:

--------------------------------------------------------------------------------

Note: the screen channel needs a FLUSH in order to force out text that doesn't form a completer line (no line-feed character). The error channel, however, flushes every character sent automatically.

Keywords: q4 , bell , beep

Referrers: Question 15 (2010)


Question 10 (2010):

Submission reference: IN1904

Will the model answer for Q3 be available to look at before the Q4 submission deadline?

Answer 10:

Sorry, no! Q3 is a warm up exercise for Q4. The freeze control it asks for can be reused intact in Q4.

Keywords: q3 , q4


Question 9 (2010):

Submission reference: IN1903

In relation to Question 8 (2010): I get that output if I remove speed.control. The only other instance I've got it to work correctly is putting speed.control before/after my freeze process. The problem is that delay() acts strangely (very slow compared to invoking it from print.streams).

I'll have another good crack at it tonight and if I fail I'll email you :)

Answer 9:

If you put the speed.control process after the output from print.streams, it'll be controlling the delay between each character sent to the terminal. As terminals are line-buffered (unless you explicitly FLUSH each character), you will have to wait some time before each line appears (the delay per character multiplied by the number of characters in the line).

If the delay is called from within print.streams, then you'll be getting the delay for each line of output, rather than each individual character, so it will generate screen output faster.

Rather than clutter up print.streams with additional speed control logic to adjust delay times, keep that logic separate in your new speed.control process but get it to control the speed of (any) one of the channels going into print.streams.

Note: using the delay process to force delays in the speed control logic has the following problem. Whilst the delay is on-going, the logic cannot respond to further instructions – such as to speed up. For instance, if the speed has been wound down to one line per second and we key in a '+' to make it go faster, the keystroke cannot be responded to until the end of the current delay period and – with one second intervals – that will feel very unresponsive. Consider how to solve this!

[Hint: your speed,control must already be ALTing between the input channel (whose speed it is controlling) and a control line (for adjusting speed). Rather than use a delay somewhere, get it to ALT between the input channel, control channel and a timeout guard. With suitable logic, it can now be programmed to respond immediately to any control signal, regardless of how long it is till the next timeout.]

Keywords: q4


Question 8 (2010):

Submission reference: IN1902

For Q4, why does flipping to minus within pairs2 result in a number being generated that is 1-bit from the correct answer? Now that I've implemented speed.control the number being generated by pairs2 is 1 from the correct answer if it's doing addition and 2 from the correct answer if it's doing minus. I've tried putting speed.control in different places but either delay() functions strangely or I deadlock (trying not to give too much away). I'd like to learn more about this strange behaviour so I can fix it with my current set-up. Any hints? :)

Answer 8:

Check the model solution output given in the answer to Question 7 (2010).

It sounds like you are doing something wrong. Does the above allow the "1 from the correct answer" you mention? Which bit in the number is "1-bit from the correct answer"? "2 from the correct answer" sounds definitely wrong.

But it also looks like you are doing something right! Try mailing your code to one of us. We won't correct it but will give you a pointer if we can.

Keywords: q4

Referrers: Question 9 (2010)


Question 7 (2010):

Submission reference: IN1901

For Q4, the pairs2 process is it okay to write a new toggle process that upon a 0, say, being put down its reset channel, it outputs the opposite of values that arrive (instead of the same). For example, if 2 was input, the opposite (i.e. -2) would be output?

Also is there somewhere we can find an example of the output we should get upon the flip being activated?

Answer 7:

That toggle process sounds a really good idea!

Here's output from the model answer:

             77           3003           6084
             78           3081           6241
             79           3160           6400
             80           3240           6561
             81           3321           6724         <-- 'p' keyed in round about here
             82           3403           6889
             83           3486             84
             84           3570             85
             85           3655             86
             86           3741             87
             87           3828             88

Keywords: q4

Referrers: Question 8 (2010) , Question 14 (2010)


Question 5 (2010):

Submission reference: IN1898

When it comes to flipping the adder within the pairs process to a subtractor, it states in the q4.occ starter file that after we do this: "...we see the natural numbers sequence".

In Exercise 4 in the "more-exercises" sheet, it states: "in its flipped mode, the modified pairs2 process becomes a differentiator so that the stream of numbers produced are the same (bar a bit of slosh) as those coming from numbers2".

This means positive numbers must be produced. However, back in the q4.occ file it also states: "The first 'p' zaps the adder process within pairs so that it becomes a subtractor, taking the numbers arriving from the tail process from those arriving directly from the delta".

This means that negative numbers are produced.

Unless I am doing something wrong, which is entirely likely, do these two statements not mean different numbers will be produced? Which is the right one if this is so? Does the aforementioned "slosh" mean the minus sign?

Answer 5:

You are not doing anything wrong!

This is our mistake, for which we apologise. The quote you gave from the q4.occ starter file tells you to do the subtraction the wrong way around. Stupidly, this was a known error – see Question 18 (2006). It was corrected in the starter file but, sadly, an old version has crept back in!

The q4.occ starter file has been corrected again – hopefully, we have better version control in place now! The corrected file can be found on raptor at:

  \courses\co538\exercises\q4.occ

Note: when marking this assessment, no marks will be lost for programming these subtractions the wrong way round (i.e. for doing what the q4.occ starter file specified) – even though that leads to (a decreasing sequence of) negative numbers. Apologies.

Keywords: q4


Question 4 (2010):

Submission reference: IN1899

I'm currently working on Q3 and have managed to get the output to the screen to freeze when 'f' is received. When the next key is pressed, numbers are again put to the screen but the process has kept on running and therefore some numbers are not printed. Is this correct or do I have to stop the numbers from incrementing (any pointers on how to do this would be appreciated)?

Answer 4:

It's not correct!

The question (Exercise 4) in the "more-exercises" sheet does say: "from wherever it left off". Keying 'f' should freeze screen output, which should resume from where it froze when the next character is entered.

It's actually simpler to program the above behaviour than to leave the demo process running without printing its output. Remember that a channel cannot lose any messages: if the receiver does not input, the sender just blocks (until such time as the receiver does input from the channel ... at which time, the message comes across). So to lose message from demo, we would need to program control explicitly to continue to take in messages but not forward them! To block messages from demo, just don't listen to it – simple!!

Keywords: q3 , q4

2009

Question 27 (2009):

Submission reference: IN1825

I'm working on the speed control on q4 and I'm getting some very strange behaviour, whenever I use the pause process, regardless of what value I pass it to delay by, it always seems to delay by approx 1 second, whether I set the delay value to 1, 10, 100, 1000, 10000 or any other number in between. And when my speed control changes the delay value, I can't see the result since it just insists on printing at that constant rate of about one line per second.

If I remove the pause completely, it outputs several thousand a second (since print.streams is initialised to -1).

Any idea why this might be happening? I'm in panic mode right now!

Answer 27:

Sorry – you submitted this with just over an hour to the deadline ... which was a bit late for us to respond! In any case, without seeing your code, there's not enough info to suggest what's wrong ... and we wouldn't let you post full implementations of things like speed control and ask why it doesn't work (see paragraphs at the top of each anon Q&A page).

Make sure you get good feedback from whoever marks your submission! Complain if you don't ...

Keywords: q4


Question 20 (2009):

Submission reference: IN1819

"A neater way is to leave the existing subcomponents alone, but introduce an extra component into the circuit to achieve the required effect. [A process suitable for this new component has been described in the course.]"

Is there any chance of a hint on where to find this?

Answer 20:

Well, you'll need a component that's PRI ALTing to react to the reset message to your pairs2. So, look in the choice slides for examples ...

Keywords: q4


Question 19 (2009):

Submission reference: IN1818

Hi, I have got a problem with the freeze functionality in q4. I have managed to implement it and it freezes an output when requested and resumes it after receiving next character, but the print streams then prints one extra column of ones. (I assume this is because I had connected the freeze.control with monitor and print.streams processes in order to avoid deadlock) Is there any way to get rid of this extra column being printed?

Answer 19:

Sorry, I've no idea how you can get an extra column of numbers (ones) after freezing and un-freezing!

I don't understand what you mean by connecting: "the freeze.control with monitor and print.streams processes"? Do you mean connecting the freeze.control between and print.streams? That sounds like you are introducing an extra channel into print.streams, which would account for the extra column – but that extra column would always have been there?!!

No. You should be introducing a freeze.control process into an already existing channel, between an already existing somewhere and print.streams (to which it was previously directly connected).

Keywords: q4


Question 17 (2009):

Submission reference: IN1816

Hello,

I am currently attempting q4. My question is this. Can the implementation of pairs2 be made in sequence? I find the idea of switching the circuit in PAR components perplexing. Should I be able to do this? Will a sequential implementation be looked upon with disregard by the mark scheme?

Many thanks.

Answer 17:

A sequential implementation for pairs2 will only gain a few marks I'm afraid. The exercise is to develop your skills at designing and modifying parallel networks.

Read this part of the question carefully again – especially the paragraph starting: "One way is to bring the new reset channel into ...". The solution does not require dynamically changing the circuit (which we can do in occam-pi, but is not part of this taught module). One solution involves modifying the behaviour of the adder process (so that it flips betwwen an adder and a subtractor when reset). A neater solution, hinted in the paragraph just referenced, just needs another process in the network somewhere and no modifications to the behaviours of any of them – it's just a circuit design problem, using existing components.

Keywords: q4


Question 13 (2009):

Submission reference: IN1811

Any ideas on how can you send an INT (e.g. 1) to a process that accepts CHAN INT only?

Answer 13:

The short answer is communicate with it in parallel. Presumably you have a PROC definition which takes a CHAN INT parameter, in which case you need to wire in a channel and output on the other end. A simple example (and not useful for any assessment probably!) would be:

  CHAN INT c:
  PAR
    my.proc (in?, out!, c?)
    c ! 42

This runs "my.proc" in parallel with a simple process that just outputs on "c". It would be expected that "my.proc" accepts this value, and the continues doing whatever it previously did with the "in" and "out" channels.

If you're still not clear on this, please discuss with your seminar leader :-).

Keywords: q4


Question 12 (2009):

Submission reference: IN1812

I am having a difficulty to understand how to activate a resettable process. The replace process would always use the reset channel. How does it actually get activated? I have tried to send the zero value in the reset channel but it still won't work. Am I missing something here?

Answer 12:

It sounds like your implementation is on the right lines. Such a process would normally have the implementation:

  PROC replace (CHAN INT in?, out!, reset?)
    WHILE TRUE
      PRI ALT
        INT v:
        reset ? v
          PAR
            INT tmp:
            in ? tmp
            out ! v
        INT x:
        in ? x
          out ! x
  :

Thus, if something comes in on the "reset" channel, this component will respond by swallowing up the next value received on "in", and outputting the reset value on "out". Ordinarily, in the absence of any communications on "reset", this process will just copy data from "in" to "out" (the second guard in the PRI ALT).

Regarding 'activation', the process once instantiated is always active — though it may spend most of its time waiting at the PRI ALT for one of the input channels to become ready. Of course, this means you'd have to wire it up inside the relevant process network, which involves modifying that original network (in the case of "numbers", "integrate", etc.). The code for these can be found in the lecture slides, or on raptor in "/courses/co538/libsrc/demo_nets.occ".

Keywords: q3 , q4 , reset

2008

Question 19 (2008):

Submission reference: IN1552

Hi, I was wondering if you could tell me whether for modifying the pairs process in q4, do you expect us to being using one of either the substitute or the greater processes from the Legoland catalogue? Cheers.

Answer 19:

Sorry – that's for you to work out! Using one (not necessarilly either of the ones you mention) of the processes already given in the slides is only one (possibly the best) approach. The question suggests another: plug the reset line into a modified plus process (that would then be better called something like plus.minus).

Keywords: q4


Question 17 (2008):

Submission reference: IN1549

I've moved onto Q4 finally, but I am completely confused by this:

  -- The squares pipeline from the `legoland demonstration' (see "demo_nets.occ"
  -- in the "libsrc" directory, which contains the "course.module" sources) is:
  -- ...
  -- Unpack and rebuild this squares pipeline and pipeline it into print.stream
  -- to make a system that outputs perfect squares - one per line:
  -- ...

It sounds like we have to change squares in the course files, which I can't even find. Surely I'm misreading this.

Answer 17:

The last portion of text in the comment you quote (and also the first line of Exercise 4) gives the answer – the key word is "rebuild":

  -- Note: we don't need to redefine any of the processes defined in these files.
  -- They have already been defined and pre-compiled.  The #INCLUDE directive,
  -- at the start of this file, gives access to them.

So, no, you are not expected to change these. However, you will need to write new versions of some of these (simple) processes to incorporate the reset channels as required.

But you are not expected to modify the course files to do that :-). The simplest way is to re-type the code from the Legoland catalog (slides 88 and 95 from the basics slides) and rename appropriately (e.g. "numbers.reset" for your modified "numbers") when you add in and deal with the reset channels.

For the first part of Exercise 4, the text explicitly points you to that slide 95 as a model for the required code – you just have to add one more process to the pipeline.

Alternatively (and only if you are a very slow typer!), you could copy the relevant sources from the "course.module" library. For those working with the kroc system, these sources are in your downloaded release: modules/course/libsrc/demo_nets.occ. Otherwise, they are on raptor: /courses/co631/libsrc/demo_nets.occ (from Windows, this looks like: S:\courses\co631\libsrc\demo_nets.occ, assuming your S: drive is mapped to '\\raptor\files').

Keywords: q4


Question 16 (2008):

Submission reference: IN1546

Hi, I'm struggling to avoid deadlock in Q4, specifically the "freeze control" bit.

I understand the problem I'm seeing (I think): if you hook up "print.streams" to feed data into monitor, then it creates a "circle of wires" and it is feasible that monitor could be trying to send a reset signal to numbers, but numbers would be trying to send to print.streams which is trying to send to monitor.

The problem is to think of a way around this. Is it acceptable to simply modify print.streams to accept a "freeze" signal the same way numbers2 and its friends do? That seems the most logical and consistent thing to do, but it also seems bad to fiddle with existing processes.

If that idea is "bad", can you offer any sort of hint as to the "proper" answer? Thanks. :)

Answer 16:

Your analysis of the deadlock sounds quite plausible, but keeping the existing "print.streams" process as it is would be sensible, unless there is no other sensible solution. If the deadlock is in that loop of processes, then all you need to do is (somehow) break that cycle. It sounds like you have your "print.streams" feeding data back into the "monitor", which is then doing two jobs: handling keyboard input, and handling output from the program. Which is where things start to get a bit complicated.

So ... don't do that! Just keep the "monitor" process handling keyboard input (and sending other signals appropriately). Separately, add some sort of "freeze.control" process, similar to the one in Exercise 3, whose single job it is to freeze the output of "print.streams" going to the screen. That way, you add one extra process to the top-level network, which doesn't increase the complexity of any individual component :-).

There may still be opportunities for deadlock (e.g. if trying to reset numbers (and others) when the output is frozen), about which there is a note about in the q4.occ file. However, that will be impossible if your follow the specification (of the required reaction to an 'f') in the question (bottom of page 5 in more-exercises).

Keywords: q4


Question 15 (2008):

Submission reference: IN1545

Duplicate of my question originally posed on the forum (I later realised that the forum was not being used).

In assessment 3, the last task:

‘+’ : double the rate of output of lines of text (up to a maximum of 1024 lines/second)

‘-’ : halve the rate of output of lines of text (down to a minimum of 1 line/second)

Do we determine max and min speed just by observation, or do we have to actually count the number of lines per second?

Answer 15:

Ah!! I see your problem now – sorry, an earlier answer did not.

To double or halve the speed, we need to know the current speed! The question does not say what initial speed to use – this is about to be fixed, :). Please set the initial speed to some value of your choice, within the min and max ranges given in the question (e.g. 32).

Your process should compute the delays necessary to control the speed. You may assume that the system can produce lines faster than the maximum (1024 per second) specified and your task is to constrain it. Actually, the transterpreter will have difficulty delivering more than 256 lines per second ... no matter. Your delays should still be computed so that, if you run your program on a faster platform, the controlled speed will increase to either 1024 lines per second or whatever the maximum happens to be.

Note: with the transterpreter, a delay of 0 microseconds will actually give a delay averaging 5 milliseconds. With the kroc compiled native code, the delay will average 0.5 microseconds. For both, a delay set to -1 yields no delay at all. Sorry, this is a subtlety of the runtime support. So, when the question says: "instance it with a delay of zero", change that to: "instance it with a delay of -1". I'll fix that as well.

By the way, if you wind the speed right down to one line per second, when you reset the numbers generator (or the integrator or pairs), the system outputs around 3 or 4 more lines (i.e. takes 3 or 4 seconds) before the changes resulting from the reset happens. This effect is less marked for the integrator and pairs resets. This is not an error on your part, nor is it due to an inefficiency in the occam platform – it is a property of the (exercise 4) system itself. Can you see why?

Keywords: q4


Question 12 (2008):

Submission reference: IN1535

In q4, with pairs set to differentiate, if integrate is reset then pairs will give a negative number.

This is of course accurate, however the question states: the modified pairs becomes a `differentiator', undoing the `integration' effect of the process immediately upstream so that we see the natural numbers sequence. Should we employ some method to enable this to return the natural numbers sequence immediately, or is the negative number acceptable?

Answer 12:

Regarding the pairs process, Exercise 4 says: "Note: in its flipped mode, the modified pairs2 process becomes a differentiator so that the stream of numbers produced are the same (bar a bit of slosh) as those coming from numbers2." So yes, the odd negative number just after the reset you describe is acceptable, :).

Keywords: q4

2007

Question 24 (2007):

Submission reference: IN1329

print.streams waits 1 second until it outputs the next line. While it waits, do the other processes (number, pairs and integrate) wait also? In occam-pi, can we force the channels to input to a process, while that process waits for some time to pass, in order to accept at a later stage?

Answer 24:

Yes to your first question. They are all blocked while print.streams is sleeping since that has to take the output streams they are trying to generate.

No to your second question. Nobody can force input into a process! If a process is not inputting anything, then no input can occur – what-you-see-is-what-you-get. Any process trying to output something down a channel to a process owning the other end, but not currently inputting from it, simply has to wait. No data is lost. When-and-only-when the target process gets around to do some input, the message will flow from the source to target &ndash nothing is missed.

[Note the contrast with Object Orientation. Any object can be forced to take input (delivered by method invocation) at any time, whether it's ready for it or not. There's nothing an object can do to prevent this. Sorting out the resulting mess when that happens is one of the reasons why OOeven single-threaded OO – can be a real headache ... ]

Keywords: q4


Question 23 (2007):

Submission reference: IN1331

I am a bit confused. I am on the speed section of q4. I understand that time increments every microsecond. I have declared a TIMER and got the time and I have a variable which I PLUSto the time to set up my speed delay. I have set the initial value to be 1,000,000 (1 second) but the output comes out a lot slower than 1 line per second.

Any ideas why this might be? Thanks.

Answer 23:

Check that you are not making the same mistake as that suggested in the answer to Question 22 (2007).

Keywords: q4

Referrers: Question 25 (2007)


Question 22 (2007):

Submission reference: IN1328

With relation to Question 15 (2007). I have exactly the same problem and I don't really understand the explanation.

The pause function in print.streams goes much faster than the one in my speed process (I do comment the one in print.streams out before trying the one in my speed process). I have noticed that some of the output done in print.streams is PAR but even if I copy and paste the in/out in my speed process a few times (to delay the delay process from happening) it will not reach anywhere near the same speed is if it were done in print.streams.

Why will the pause in speed not go as fast as the one in print.streams? Thanks.

Answer 22:

Without seeing your program, I've no idea ... but can hazard a guess. The delay process imposes the same delay on any process invoking it – it will be just the same in print.streams as in your speed control process.

In print.streams, the pause is executed once per cycle – i.e. once for each line of output.

Now, where is your speed process and what stream is it controlling? If it is in the stream of BYTEs coming out from print.streams, you had better not be invoking pause in every cycle – otherwise, you will be getting that pause for every character generated, not for every line! Your will be controlling characters per second, not lines per second. If this is you problem, a simple fix is to invoke pause only if the BYTE flowing through is '*n' (newline).

There is, though, a better and more efficient solution ...

By the way, there is no PAR output in print.streams – only PAR input.

Keywords: q4

Referrers: Question 23 (2007) , Question 25 (2007) , Question 25 (2007) , Question 25 (2007) , Question 28 (2007)


Question 21 (2007):

Submission reference: IN1330

The diagrams that we need to submit for q4 ... do we need to submit a diagram for all the new processes we have made (numbers2, integrate2, pairs2) or is it just a layout of our processes for q4? Thanks.

Answer 21:

Please submit a diagram for any process network you have changed (from any diagram given in the question sheet or starter file). Diagrams could be ASCII text art (as in the starter file) or any standard electronic document (also deposited in your submission directory) or a neat hand drawing (handed in to the CAS office with a cover sheet for this assessment number and module ... or scanned in and copied into your submission directory).

So yes ... we do want diagrams for your modified numbers2, integrate2, pairs2 and q4 process networks. Only process networks need diagrams – not serial logic.

Keywords: q4


Question 20 (2007):

Submission reference: IN1325

For the '+' and '-',of the q4.occ: each time the user types '-' on the keyboard, I divide by 2 the 1000*milliseconds of the delay that is passed to the print.stream. But this works only until (1000*milliseconds)/64 and then the (1000*milliseconds)/128 is the same as the (1000*milliseconds)/64. Do I do miss anything important here?

Answer 20:

You should not be doing anything to the delay value passed to print.streams! As the q4.occ starter file suggests, set that delay to -1 so that print.streams imposes no delays at all. Leave print.streams alone. Implement speed control in a brand new process – as the question (and starter file) suggest.

I guess you're modifying print.streams to take a speed control channel and starting at minimum speed (1 line/sec => a period of 1000*milliseconds per cycle). When a '-' is keyed in, the line rate should slow down – i.e. the period should be doubled, not halved. When a '+' is keyed in, the line rate should speed up – i.e. the period should be halved. Assuming that's what you meant ... why is (1000*milliseconds)/128 is the same as (1000*milliseconds)/64? I'm assuming that milliseconds has the value 1000, since time is measured in microsecond units. Then, (1000*milliseconds)/128 is 7812, which is rather different from (1000*milliseconds)/64 which is 15625.

[Note: the question (in the PDF file) says set the print.streams delay to zero, but the starter file says minus one. Setting a delay of zero asks for a delay of one time unit (microsecond on most current platforms) – see the answer to Question 15 (2007). This is because the AFTER operator really means after! Setting a delay of minus one asks for no delay at all – because time is always AFTER one time unit in the past.]

Keywords: q4


Question 19 (2007):

Submission reference: IN1326

In the assessment it says: "BYTEs output on the error channel do not need flushing - they are delivered to the user's terminal (window) without delay." Is this true with the transterpreter also? As I found that the error channel needed flushing after a bell signal.

Answer 19:

On Unix systems, the standard error channel does not need flushing and that's how occam-pi's error! channel behaves there (and is supposed to behave). Under the Transterpreter, it should behave the same ... but, as you found, it does not. This will be fixed in the next revision – thanks. Meanwhile, please send a FLUSH to the error! channel if you want previous output to be forced out!

Keywords: q4


Question 18 (2007):

Submission reference: IN1324

A question on freezing:

When we freeze obviously the timer keeps on going (for the speed control). Now, when we resume, the timer might have gone through many cycles therefore letting a whole load of result pour out all at once before resuming the normal speed.

Do we want that to happen or not? Thanks.

Answer 18:

It's time, rather than the timer, that keeps on going. The timer ain't doing nothing!

But yes, depending how you do it, your scenario will happen. It is quite easy to avoid (e.g. if you implement speed control with a pause procedure – though this has its own problem, see the first paragraph of the asnwer to Question 15 (2007)). There will only be a small loss of marks for suffering this effect when a freeze is unfrozen.

Keywords: q4


Question 17 (2007):

Submission reference: IN1323

For the '+', '-', which are the maximum number and minimum rates? Because in the q4.occ doc you are saying 1-128, but in the pdf file you are saying 1-1024 lines/second.

Answer 17:

Sorry – either maximum rate is OK. For most terminal emulators though, 128 lines per second is about as fast as they can go!

Keywords: q4

Referrers: Question 28 (2007)


Question 16 (2007):

Submission reference: IN1322

Hello,

I have some issues with deadlocking when I type with some fury at 'n' and 'i' when I implement them. My relevant code looks like:

  ...  code deleted

Everything that I think could be done in parallel is done in parallel and I don't understand why if I start pressing the two buttons rapidly I would get in a dead lock situation. Thanks.

Answer 16:

Sorry – see the third paragraph of the preamble at the top of this page. We can't answer such questions here.

Keying in 'n' and 'i' fast should absolutely not provoke in deadlock, so something is wrong. Your resettable integrate is not the parallel version required – you're supposed to be working from the parallel integrate process ... but this isn't why your system is deadlocking.

[From a quick scan of your code, I can't see any obvious reason - sorry. You'll have to keep thinking about it ...]

Keywords: q4


Question 15 (2007):

Submission reference: IN1321

I'm working on q4, and was wondering about the last part (the speed control).

I assume I should use the pause given to us in q4 for this, but when the timeout given to pause is '0' it returns extremely fast (as expected), however when the timeout given is 1 or more, it seems to be a lot slower. (I am expecting to wait 1ms where it seems to be more like 1 second.

Answer 15:

Well – you can use pause somewhere within whatever process you write for the speed control. It's OK ... but when the delay is long, like a second, it will wait that whole second before processing anything else ... which could be a signal to speed up! There is a way to do this so that speed response to '+' and '-' is always fast, no matter what the current delay period.

When you set zero as a delay period - e.g.

  TIMER tim:
  INT t:
  SEQ
    tim ? t
    tim ? AFTER t PLUS 0

we are saying wait until the time on the timer is AFTER what was just read – i.e. that the timer has advanced at least one microsecond. With the Transterpreter, that will probably be true, so there will be no delay imposed ... and the output is fast. But if we set:

  TIMER tim:
  INT t:
  SEQ
    tim ? t
    tim ? AFTER t PLUS 1

we mean wait until at least two microseconds have passed. The Transterpreter is fast enough that that probably won't have happened, so a delay is imposed. Because no other processes can progress (they are blocked by the above delaying speed control process), the occam run-time goes to sleep ... first asking the operating system to wake it up in a microsecond or two. Unfortunately, most operating system have a granularity at around 10 milliseconds in operating its timers ... so your system has to wait that long to get reinstated. [Note: that won't be the case when the operating system is written in occam-pi – check out RMoX.]

Consequently, there won't be much difference between a delay(1) and delay(10000) (10 milliseconds) ... but you will notice delay(100000) (100 millseconds, or 1/10 second) is a lot slower!

So, that should explain the effects of giving small delay values to the pause period. If we pass 1, we hope for 1 (2 actually) microseconds, but get around 10000 – same for all delays up to 10000. [You should not have been expecting 1ms and should be getting 1 second delay!]

Keywords: q4

Referrers: Question 18 (2007) , Question 20 (2007) , Question 22 (2007) , Question 28 (2007)


Question 14 (2007):

Submission reference: IN1320

Are we required to submit q3.occ as part of the latest assessment, or do we just submit q4.occ as this covers the stuff in q3?

Answer 14:

Just submit your q4.occ source file. Thanks.

Keywords: q4


Question 13 (2007):

Submission reference: IN1318

I'm trying to do the increment/decrement of the print.stream's delay part of question 4 and can't seem to see why the following is happening, it seems fairly basic:

    PRI ALT
      rate ? r
	print.streams (10, r!, chans?, screen!)
      SKIP
	print.streams (10, r!, chans?, screen!)

I can't ever get passed the first guard even though I know that I have read input from rate. Removing the skip guard and adding a stop below the first guard shows me that I can actually trigger this guard. Shown in the following:

    PRI ALT
      rate ? r
	STOP

However it seems that when the skip guard is added the first guard is never correctly evaluated and the second one evaluates to true. Whats going wrong?

Answer 13:

Guards are either ready or not ready – they don't evaluate to anything.

There are two problems with your first code fragment. The first is that you input something from rate into a variable r possibly an integer? But then you pass r! to print.streams where r! is the writing end of some channel! Now, while occam-pi does enable channel-ends to be sent through channels, I don't think that's what you are trying to do here – sending channels through channels is how occam-pi can set up networks at run-time (and is part of next year's Advanced Concurreny and Practice module). So, what is your r – it can't be both an integer and a channel?

Your main problem, though, is not understanding the nature of the print.streams process. This process runs forever – its main loop is WHILE TRUE. So, when your code fragment runs, the rate guard probably won't be ready ... but the SKIP guard will and so your second print.streams (which is the same as the first!) starts executing ... and never terminates. So your code fragment never terminates! If it is embedded inside a loop, that loop will never loop and your code fragment will never be executed again.

Hope that helps!

Keywords: q4

2006

Question 34 (2006):

Submission reference: IN987

In the older answers, you mention model answers. Are these still available to look at?

Answer 34:

OK - I've put model answers to completing q1.occ, q2.occ, q3.occ and q4.occ in the raptor folder:

    \courses\co631\answers\

Keywords: q1 , q2 , q3 , q4


Question 27 (2006):

Submission reference: IN861

Hi I need some help! I spent ages trying to get this to work, but it doesnt seem to want to. I'm still stuck on the reset numbers to zero, so I have some questions!! [Stuff omitted.]

[Editor: the above question was posted at 14:00:02 on the day of the submission deadline ... the following was at 14:25:44.]

Hi, I know this is cutting it a bit fine but I've been stuck for days with question 3. When I run the program, the 'i' and 'n' keys work as expected however, when I press 'p', the program output doesnt change and the keyboard is unresponsive. [Stuff omitted.]

Answer 27:

Sorry - that was cutting it too fine! We were attending a Board of Studies meeting from 2:00-4:30pm that afternoon ... and 4:30 was after the deadline. We try to turn around answers as quickly as possible - but cannot promise to do so within the day.

The story has a happy ending for at least one of the questioners ... who followed up an hour later with:

"Forget the last question, i figured it out!! Finally!"

:)

Keywords: q4


Question 24 (2006):

Submission reference: IN854

Why does my code just print:

  0
  1
  2
  3

then deadlocks? If I change the printstream call to connect to the f channel (rather than c), then it just prints:

  0

then deadlocks? If I change it to connect g, then it just deadlocks before printing! Here's my code:

  PROC starty (CHAN BYTE keyboard?, screen!, error!)

    CHAN INT a, b, c, d, e, f, g:
    CHAN INT x:
    INT xx:
    [3]CHAN INT q:

    WHILE TRUE

      PAR

        numbers (a!)
        delta (a?, b!, c!)
        integrate (b?, d!)
        delta (d?, e!, f!)
        pairs (e?, g!)

        print.stream (100000, c?, screen!)
  :

Answer 24:

You never use your channel array q, nor your channel x nor your variable xx.

The WHILE TRUE betrays a bad misunderstanding! Its loop body is a parallel network of processes - none of which ever finish. So, that network never finishes ... so the loop body never finishes ... and your loop never loops!! Just get rid of it.

In your code, numbers outputs its first zero ... delta forwards it to integrate and print.stream ... print.stream prints it (first output line) ... integrate adds it to zero and sends zero to the second delta ... which forwards it to pairs and channel f. Channel f has no receiving process, so that's the end of the second delta which can't continue until it completes the output on f.

Meanwhile, pairs takes in the zero and waits for its second input. This is on its way ... as numbers can now output its second number (1) ... the first delta forwards that to integrate and print.stream (which prints it - the second output line). Meanwhile, integrate adds it to its running sum and outputs that to the second delta ... which, sadly, is blocked still trying to output ... which means that integrate is now blocked.

Meanwhile, numbers can now output its third number (3) ... etc.

Eventually, the first delta gets jammed trying to output to integrate ... so numbers gets jammed trying to output to the first delta. Because, integrate and pairs have internal concurrency, they can actually take in at least one more input than outlined above (because they have parallel input and output processes). This is why you get a couple more lines of output before complete deadlock is establised, :(.

If you connect print.stream to the g channel, the earlier delta processes jam straight away as there is no process taking their second output channels. Everything jams very quickly ... though the first zero should get through to be printed? Probably, the Transterpreter bails out with its deadlock message before Windows gets around to showing the zero in the terminal window.

Your mistake is using print.stream, which has only a single input channel. You should be using print.streams, whose code is given in your starter file and which takes an array of input channels (one from each delta and one from the final pairs).

Keywords: q4


Question 23 (2006):

Submission reference: IN852

Is there anyway to use the numbers, integrate and pairs processes in a SEQ? For SEQ, I can't figure out how to make them work, but they are fine for a PAR.

But I can't figure out how to stop them in a PAR, I would use an IF statement if it was a SEQ; but I'm really stuck and I spent all day trying to make it work ...

Answer 23:

No, there is now way to use the numbers, integrate and pairs processes in a SEQ. The code:

  SEQ
    numbers (a!)
    integrate (a?, b!)
    pairs (b?, c!)
    ...  etc.

first runs the numbers process and waits for that to finish ... which it never does ... so the integrate never runs ... which means there is no process taking the output from numbers ... which means that numbers never even manages to output its first number!

So, trying to run these processes in sequence ... that is a pretty fundamental error.

By "stopping them", I assume you mean blocking them so that the output stream is frozen. To do this, no change at all to those processes is required! You just have to put something in their output stream - an obstacle ("pause") process that you can switch between allowing traffic through or blocking it. To block traffic, simply don't input anything and, therefore, don't forward anything.

If by "stopping" you mean the last modification (response to a 'q' keypress), just terminate the obstacle process. Now, there's an "air-gap" in the wiring and no data can flow and pressing further keys cannot repair that! To see deadlock immediately, you should also terminate the keyboard monitor process - otherwise, that's still alive waiting for keyboard input.

Keywords: q4


Question 22 (2006):

Submission reference: IN842

Is is ok if my 's' keypress doesn't use blackholes? It doesn't seem to cause any problems not using it, but I just wanted to make sure it was ok as you mentioned it during the class

Answer 22:

Yes. If I mentioned it in class, it wasn't to do with this assignment. Sorry - I can't remember doing that. There is no need for "black holes" in this assessment.

Keywords: q4


Question 21 (2006):

Submission reference: IN839

My suspend process works but is giving some very strange output. The code is as follows:

  ...  code deleted

It stops the program just fine but will not allow me to resume. To try and test it a little bit i changed the last line from "SKIP" to "out ! x", just to see what was pending on the output channel. This allows the program to resume on the next keypress. However: in every case (despite how long I wait before resuming), the next number output is 43 and the other output from the program is not what I'm expeciting. For example:

  1	 1	  4
  2	 3	  49   <-- pause here
  43	 46	  135
  43	 89	  181  <-- resume key
  3	 92	  188

Do you have any idea why this may be happening? Or more to the point, is my suspend process along the right lines?

Answer 21:

Sorry - your code fragment is deleted for the same reason as in the previous question.

However, your suspend process polls its control channel and, once it suspends operations, that's all it does. It spins forever, never releasing the processor and, so, your keyboard monitor process never gets back in to allow you to stop it! [Actually, that looks like a bug in the Transterpreter, which should re-schedule after a failed poll attempt. We will look into that.]

But that doesn't let you off the hook. That poll here is not needed ... and, if you have to poll, you shouldn't just spin ... without engaging (communicating) with some other process ... or having a (small) timeout ... in the polling loop. Then, everything gets scheduled again!

Putting a communication in your polling loop is what you do in the "test it a little bit" you describe. However, you output an unitialised variable and that accounts for the mysterious "43" you see. Uninitialised variables have no default value - the compiler warns you if it sees you using them. [I suspect our Transterpreter people decided it would be amusing to set them to 42, :), which they are absoultely entitled to do ...]

Keywords: q4


Question 20 (2006):

Submission reference: IN833

Hi, I'm having some trouble with my zap adder control. I created a new PROC called operation that takes an additional parameter to decide what function is to be carried out. Does this seem like a sensible way to solve the problem?

  ...  code deleted

Also, to suspend output would a reasonable way be to simple halt numbers from outputting anything thus causing everything else to wait for input? Cheers.

Answer 20:

Sorry, we can't answer specific questions about a piece of code large enough to give too much of a solution away. A general guideline is given in the third paragraph of the general text at the top of this page.

Having said that, the deleted code does look sensible (albeit with some redundant SEQs). Your second question has "yes" as its answer, provided by "halt numbers" you really mean "suspend numbers".

Keywords: q4


Question 19 (2006):

Submission reference: IN843

Do I get extra marks for spotting the specification problem in Question 17 (2006) and Question 18 (2006)? :)

Answer 19:

We don't know who you are ... these are anonymous questions! :)

Keywords: q4


Question 18 (2006):

Submission reference: IN841

In question 17 I meant which number do I take off which? Its strikes me as important and I don't want to get it wrong :)

Answer 18:

Ah - I understand what you mean now! :)

The specification says it in words:

  'p' ==> ..............................................................
          .................... taking the numbers arriving from the tail
          process from those arriving directly from the delta.

Natural language, sadly, is a difficult medium with which to be precise - but we try. In your notation from question 17, this means:

  delta - tail

However, that looks wrong! And will lead to a decreasing sequence of negative numbers ... instead of an increasing sequence of positives!! Humm ... that specification has been running for many years and nobody spotted anything wrong. It should be:

  'p' ==> ..............................................................
          .................... taking the numbers arriving directly from
          the delta process from those arriving from the tail.

So, in your notation from question 17, this means:

  tail - delta

Even now, I find it hard to interpret that natural language correctly. Specifications should be written in mathematics - only then can we have precision. Meanwhile, we will accept as a correct solution to this part of the assignment one that does the subtraction either way around. Apologies.

Keywords: q4

Referrers: Question 5 (2010) , Question 19 (2006)


Question 17 (2006):

Submission reference: IN840

You said in the class that pressing 'p' should mean the third column is natural numbers, but when I do what you say I have delta - tail in pairs I get this but the numbers are decreasing. So which one is correct, delta - tail or tail - delta? Thanks.

Answer 17:

Sorry, I've no idea what you mean by: "delta - tail in pairs"? Same for "delta - tail or tail - delta"?

The pairs process, slide 98 of basics.ppt, has three sub-processes: delta, tail and plus, arranged in the network topology shown. Your task is to make that plus process behave like a minus when a 'p' keystroke is made (and vice-versa for the next 'p') ... etc.

Please see the answer to Q16 for further help.

Keywords: q4

Referrers: Question 19 (2006)


Question 16 (2006):

Submission reference: IN837

Hi, I totally get stuck on the fourth modification, how can I change the pairs process to undo the integration? Thanks

Answer 16:

I think you mean the third modification: dealing with a 'p' keystroke ... which has to change the behaviour of pairs. Read the specification of this change:

  'p' ==> the first 'p' zaps the adder process within pairs so that it
          becomes a subtractor, taking the numbers arriving from the tail
          process from those arriving directly from the delta.  In this
          state, the modified pairs becomes a `differentiator', undoing
          the `integration' effect of the process immediately upstream so
          that we see the natural numbers sequence.  A second 'p' toggles
          the process back to its original state.  Subsequent 'p's toggle
          between the two states.

This assumes you are modifying the pairs process whose implementation is given by the network shown in slide 98 of basics.ppt. Just do what it says in the first sentence! The second sentence will then just be true (as your experience in doing the second assessment exercise should inform you). Don't forget to deal with the third and fourth sentences in the specification above.

Keywords: q4


Question 13 (2006):

Submission reference: IN827

In the current assessment, does pressing 'q' basically kill it? I.e. are we trying to make the whole thing crash and die? Thanks

Answer 13:

The question says: "Just cause the system to freeze (i.e. deadlock) in response to this 'q'". By this , we mean something stronger than the freeze in response to an 's', from which we could recover the system with a further keypress. By "freeze (i.e. deadlock)", we do mean force the system into deadlock - something we would not normally require! But this is trivial to do: terminate the keyboard monitoring process and one of the processes in the data stream(s) to the screen channel.

A (much) better solution would be to arrange for all processes to terminate "gracefully" - but that's a *lot* of work and definitely not required.

Keywords: q4


Question 12 (2006):

Submission reference: IN826

With assessment 3, question 4 has this:

  's' ==> suspends output to the screen.  Output is resumed by the next
	     keypress (which is NOT processed according to the above rules
	     -- it is merely the signal to resume output).

How should it be processed differently? I assume that we press 's' once, and nothing is output but everything is still running. Then, I assume if 's' is pressed again then output it resumed, but at the state the machine reached even when it wasn't outputting. Am I wrong here though? Is there something special we need to do? Thanks.

Answer 12:

If you type an 's', the output must be frozen. The next key pressed (i.e. any key, not just an 's') lets output resume from the point at which it was frozen. That's still what must happen if, for example, that next character was an 'i' - i.e. that 'i' is not processed according to the rules (which would mean resetting the integrator).

Keywords: q4


Question 11 (2006):

Submission reference: IN825

I have to following for Q4:

  [snip code]

And i keep getting the errors:

Error-occ21-q4.occ(325)- incompatible channel direction specifier on `d'
Error-occ21-q4.occ(336)- incompatible channel direction specifier on `b'

I've tried changing around the channels and rewriting the PROC's but the same erros keep popping up. From what i can tell the channel directions are correct. For numbers replace outputs on d and delta takes an input on that channel.

Answer 11:

Double-check that you're wiring things up correctly. Because you don't specify which lines the errors are being reported for it's pretty hard to give any more advice! The compiler will generate this error when you try and specify an incompatible channel-direction. Your code had a mixture of some parameters with direction-specifiers and some without -- put them all in as you think they should be and try compiling again. If things still go wonky, email me your code (frmb@kent.ac.uk) and I'll see if there's something else going wrong (like a compiler bug!).

From phw@kent.ac.uk: yes, double-check! You have simply used the codes given in slides 46 and 49 (from choice.ppt), which are correct for the replace process defined on slide 34. Now, look at the replace process defined in your q4.occ starter file ... it's different! The difference is trivial - one parameter name and the order of its parameters. To fix things, either change the replace in your file *or* invoke it correctly.

Keywords: q4

2004

Question 73 (2004):

This may sound silly but there are no questions about using "CASE", could you please tell me a bit more about it and when it's used please. Thanks.

Answer 73:

The "CASE" construct is much like C and Java's "switch". In occam, "CASE" can be used in three places: as a "switch" on some variable/expression; in tagged protocol definitions; and in tagged protocol input. There are plenty of examples of "CASE" usage -- see the past questions, course notes, the model answer to Q4 (its "keys" process) and this occam tutorial. It would also be neater to use a "CASE" for examining the result of a "compare.string" function, rather than an "IF", in Q6.

Keywords: tagged-protocol , case , q4 , q6


Question 61 (2004):

When will the q4 model answer become available?

Answer 61:

Done! Also for q5. See:

    answers/a4_slow.occ
    answers/a4.occ
    answers/a5.occ

in the usual place.

Keywords: q4


Question 53 (2004):

Are differentiate and minus predefined or do we have to define them?

Answer 53:

You have to define them -- they are not in the course library.

You will have been told this in your seminar groups. You could also find out for yourself by browsing through the course library:

  /usr/local/courses/co516/libsrc/README.txt

Note: you don't have to write a differentiate process for Q4! Nor do you have to write a minus process ... read the fifth modification (in your starter file) carefully. Resetting the pairs process causes its adder sub-process to change behaviour so that it subtracts the numbers arriving on its two input streams from each other (careful to do this the right way around) rather than adding them. This has the effect of turning this reset pairs into a differentiator (which is merely a comment, describing the result of this change). One way to do this might be to wire a minus process into the circuit, but that is some way from the simplest solution.

Keywords: q4


Question 52 (2004):

Where do we use numbers.reset? After the second modification you ask us to declare numbers.reset and integrate.reset, but the diagram has numbers as its component?

Answer 52:

There wasn't space in the ASCII-art diagrams to write a revised name for the resettable processes. Clearly, the processes labelled numbers, integrate and pairs -- that have reset lines coming into them -- are the resettable processes you have to produce. What you call them (e.g. numbers.reset etc.) is up to you! Just don't continue to call them by their original names, since those names are already in the course library and the linker will complain.

Keywords: q4


Question 48 (2004):

Talking about the resettable running-sum integrator, you said in the lecture that there was an argument for putting replace between plus and delta or between delta and prefix. Does this mean that the former of the two actually resets to 0 or output 0 instead of the latter that will output 0 plus the last number that came on plus?

Answer 48:

Slide 6-21 in your printed notes (currently slide 22 of chapter 6 in the Powerpoint set) places replace between the delta and prefix. This means that, when a reset (e.g. a zero) comes in, it goes through the plus (and gets something added to it) before going through the delta and being output. Therefore, resetting with a zero does not cause zero to be output -- you will get zero plus the next input. However, the running total was zapped to zero, which is all we were wanting to do.

If we placed replace instead between the plus and the delta, a reset of zero also zaps the running sum to zero and we will see that zero emerge -- which lets us see more directly that the reset has happened.

Placing replace between the prefix and the plus has the same behaviour as the first option above.

So, the replace can be added anywhere in the original circuit and it will have the required behaviour (of zapping the current running sum).

Note that with any of these positions for replace, the next number output by the device -- following a reset -- may be the old running sum (before it is removed when it next passes through the replace). This just depends on where that old value is in the circuit when the reset happens. If that were a real concern, we could not use a replace. Instead, we would have to modify the delta process to take the reset channel itself (and PRI ALT between that reset and its normal input). That's easy -- it's a folding together of the logics for replace and delta into a single process:

  PROC delta.replace (CHAN OF INT in, reset, out.0, out.1)
    WHILE TRUE
      PRI ALT
	INT x:
	reset ? x
	  PAR
	    INT any:        -- remove old value
	    in ? any
	    out.0 ! x       -- copy through new value
	    out.1 ! x       -- copy through new value
	INT x:
	in ? x
	  PAR
	    out.0 ! x       -- copy through value
	    out.1 ! x       -- copy through value
    :
But I prefer not to disturb existing components unless I really have to!

Keywords: q4


Question 47 (2004):

This question regards the `pairs.reset', which we are supposed to program for Q4. Is it okay to say we can program two methods, `pairs.plus' and `pairs.minus', and the `monitor' method choses which one of these to implement depending on the key-press; would this work?

And also, with the `monitor' PROC, is it alright to say that if I type `n' into the keyboard it sends the number 0 to the `numbers' method as an imput? If this is the case am I to asume that if monitor dosen't send a number (i.e. 0) to it, it would carry on as the normal `numbers' and not reset the numbers PROC ?

Also the timer, which we had to implement in q3:

    TIMER tim:
    INT t:
    SEQ
      tim ? t
      tim ? AFTER t PLUS delay

where can we put this ? In the `monitor' method, or is it more sensible to implement it somewhere in `layout.max.chans', because it's connected to the screen ? A student told me somewhere in `numbers', `integrate' or `pairs' would be suitable.

Answer 47:

Programming two separate `pairs' methods is possible, but quite a long way round. You can't `switch' between them, however -- you have do run both (in parallel) and then work out how to feed them inputs and collect outputs. It's easier (and arguably better) to just modify the internals of `pairs'.

As for the resetting of `numbers', yes, that's the way it'd generally be done -- in fact, there isn't any other way in occam. You can't interact with a process unless you have explicit wiring for it (e.g. one process cannot directly change the value of a variable in another process -- the processes have to communicate over a channel to achieve this). And yes, the `numbers' process should carry on generating numbers as normal, until it is reset. What happens inside another process (e.g. `monitor') can have no effect on `numbers' (or, indeed, any other process) unless communication takes place between them! This is what makes occam systems so robust as new components are added or existing ones changed -- unlike systems currently running the Social Services disability section, the Child Support Agency, ...

The timer code can be put anywhere where it will limit the speed of program output. The program is basically a pipeline of processes, so slowing down any one component in that pipeline will slow down the whole pipeline (the pipeline in this case is: "numbers -> integrate -> pairs -> layout.max.chans". `monitor' would not normally be part of this pipeline (although it could be). However, there's no need to complicate the code in `monitor' with timeouts (and making it part of the pipeline) -- the timeout code can go somewhere else. For clarity and simplicity, it's often better to engineer these sorts of things into stand-alone components, then wire them into the process network. Pencil and paper come in handy for this.

Keywords: q4


Question 46 (2004):

Hello, I'm having trouble with the `monitor' procedure, my code is below:

    PROC monitor (CHAN OF BYTE k, CHAN OF INT num, int, prs)
    PAR
      IF
        k = 'n'
        num ! k
        IF
          k = 'i'
          int ! k
          IF
            k = 'p'
            prs ! k
    :

I get indentation errors, and I'm not sure how to fix this, I was told by a colleague that we are supposed to implement an infinite loop in the `monitor' process -- why is this ? and what use could this be ?

Also, in the specification for the assignment, when we press `s' to suspend the output to the screen I'm assuming that this supposed to be implemented by the `monitor' method -- am I right?

Answer 46:

Yes, this code has incorrect indentation. The "occam-2 checklist" in the course notes (and linked from the course web-page) provide a good deal of information on the layout of occam code. The correct layout for an occam `IF' (conditional process) is:

    IF
      condition.0
        process.0
      condition.1
        process.1
      ...

The operation is: the various conditions are checked in the order written; the first one that evaluates to `TRUE' is selected and the process under it run. The rest of the conditions are then ignored. If you look at this occam tutorial, you'll see that the equivalent Java is something like:

    if (condition.0) {
        process.0
    } else if (condition.1) {
        process.1
    } else if ...
        ...

In occam, however, one of the processes must be selected -- if the `IF' "falls-off" the end, it behaves as `STOP', generating a run-time error.

What you have in your code is some way to being a nested `IF'. The correct layout for that would be:

    IF
      condition.0
        process.0
      IF
        condition.1
          process.1
        IF
          ...
            ...

But this is exactly equivalent to the version above, with all the conditions aligned.

The process needs to be an infinite loop otherwise it will run once then terminate, deadlocking anything else that tries to communicate with it (since it isn't there anymore). Parallelism does not imply repetition -- if you want the network to run forever, make each component run forever. And visa-versa -- if you want the network (or a sub-network) to run once (or n-times), make each component run once/n-times. Infinite loops are just `WHILE' loops that never terminate (because their condition never becomes `FALSE'). For example:

    WHILE TRUE
      out ! 42

Will just output 42 on the channel `out' forever (or until it deadlocks).

The suspend signal needs to be handled in `monitor' in the sense that's where the key-presses arrive and are processed. Again, it's a design decision (up to you) as to whether the `monitor' process actually does the suspending of screen output, or whether it simply signals another component in the network, that suspends there. Suspend processes (e.g. for Q3) have been covered in the seminars, so it might make sense to re-use that.

Keywords: q4 , incorrect-indentation


Question 45 (2004):

Concerning q4: `PROC pairs' uses `delta', `tail' and `plus' components linked together. For the assignment we need a toggle on `pairs' in order to add numbers or take them away from each other. If we created another procedure which changed between `plus' and `minus' depending on key presses, and used that procedure in place of `plus'. Is this along the right lines or should there be something internal to `pairs' which decides if there should be a toggle ?

Answer 45:

That is largely up to you! Both ways are essentially acceptable, assuming a nicely coded solution. The difference is usually the breakdown between parallel and sequential code. A single component will generally be sequential code only, whereas a network of processes requires parallelism (but the individual sequential processes are simpler).

One way to find out, of course, is attempt to program this both ways, and see which gets you to the finish-line first..

Keywords: q4


Question 42 (2004):

Is there any way the output can be slowed down its very hard to see if my code is working. If not is there any way we can output our results to a text file and look at them in there ?

Answer 42:

The easiest way to slow down the output is using some suitable `delay' component, either inside the network somewhere, or just before the network connects to the `screen' channel (but this latter delay process is slightly more complicated, as you only want to delay when a newline character goes through). As has been mentioned in the seminars, look at the following files on raptor for an idea of how to do this:

    /usr/local/courses/co516/answers/a1_slow.occ
    /usr/local/courses/co516/answers/a2_slow.occ
    /usr/local/courses/co516/answers/a3_slow.occ

The last of these implements a fixed slow rate (10 lines/second) and has the simplest code ...

Keywords: q4


Question 41 (2004):

In the code given in q4 there is a replace procedure. I don't understand what it does. Could you explain how it works please.

Answer 41:

This question was discussed in the seminars, attendance at which is compulsary. If you miss one, it is your responsibility to find out what you missed!

Having said that, look at slides 6-21/22/23 ... and ...

This procedure is probably best explained in terms of its occam code -- occam is actually very structured, although getting used to the syntax/indentation can take a little time. The code for `replace' (with the channels dressed up with direction specifiers) is:

    PROC replace (CHAN INT in?, control?, out!)
      WHILE TRUE
        PRI ALT
          INT x:
          control ? x
            PAR
              INT any:
              in ? any
              out ! x
          INT x:
          in ? x
            out ! x
    :

The main body of this process is a `WHILE TRUE' loop, so it's going to do something forever. The process inside the `while' is a `PRI ALT' with two guards. The first guard will accept an input from the `control' channel, that has priority over the second guard, an input from `in?'.

As with most ALTs, if neither channel is ready the process will stop running and wait until one of them is. If the `in' channel is ready, and selected, a value will be read and simply output on `out' -- so values can just "flow" through the component unhindered.

However, if the `control' channel is ready (and this will be selected if both channels are ready) a value is read from it and placed in `x'. The code then, and in parallel, performs an input from `in' (throwing the value away) and output the value sent down the `control' channel to `out'. The effect of this is that a communication on the `control' channel causes the next value on `in' to be replaced. In this version, the communications are done in parallel -- so the replaced output may appear before the value that it was replacing. This is not a problem however, and those communications could be done sequentially if desired.

The `replace' component should have been covered in the seminars already, however..

Keywords: replace , q4


Question 39 (2004):

I'm struggling with the `monitor' method: checking previous anonymous Q+A's I found a student starting the method this way:

    PROC monitor ([]CHAN OF INT out, CHAN OF BYTE keyboard, intr)
      --{{{  forever
      WHILE TRUE
        ...  wait for `intr' and process accordingly
      --}}}
    :

while I have done it this way:

    PROC monitor (CHAN OF INT keybrd, num , int , prs)
      PAR
        id(keybrd, num)
        id(keybrd, int)
        id(keybrd, prs)
    :

I'm totally sure my own version is wrong, what I don't understand is what I'm meant to do exactly for this method; and also I would have thought the input for keyboard would have been a string for "s" "n" etc.. so you can compare which one to reset. I have done the methods for `numbers.reset', `integrate' and `pairs' and they're working. I'm not sure where to proceed from here though.

PLEASE HELP!!!! :'(

Answer 39:

Going from your last paragraph, keyboard input is characters -- that are represented by BYTEs in occam. occam doesn't have a native `string' type like Java, so that rules that out. Strings in occam are done using arrays of BYTEs.

What you suggest is largely sensible (and correct): wait for some input from the keyboard, then compare to decide which component to reset. The first code fragment above is on the way to doing this. The second code fragment isn't; this will fail to compile due to the parallel inputs on "keybrd" -- also it's unclear what such code should do: relay the values on "keybrd" to each of the three reset-able processes ? Better to do the input first, then decide what to do with it.

Just as a point to convention: occam PROCs should be called "processes" or "procedures", not "methods" (a term from OO programming, which occam isn't). occam also has FUNCTIONs (that return values) and these are very different from PROCs (non-value parameters can be used to "return" data from PROCs, however).

Keywords: q4


Question 38 (2004):

I am trying to set up a reset for pairs. Where do you best suggest I have replace? Before the input or after? Or can I have more than one replace in a process?

Answer 38:

Yes, you can have as many replace processes as you like in any process network (such as the one needed for pairs.reset). Actually, you should add no replace processes there -- they offer no help in implementing the required change in behaviour of pairs.reset when a reset signal arrives.

Keywords: q4


Question 36 (2004):

I've completed q4 - but just testing it I've found that my implementation for pairs resetting is a bit odd.

If left on its own the program runs fine and loops round every 20 secs or so. If i press `p' I start to see the list of natural numbers - but the program then crashes at 65535. Is this ok?

Answer 36:

Yes, that's not too serious -- but the crashing is a pain and easily fixed.

The `pairs' process, when subtracting, behaves like `differentiate' (except that it loses the first value communicated -- because of the `tail'). Thus you'd expect to see natural numbers -- or at least the input to the (`integrate' -> `differentiate') part of the pipeline.

Your program crashes when your resttable `pairs' process is reset, because your code uses (I strongly suspect) either a `+' symbol (instead of a `PLUS', which wraps round on overflow without crashing) or a `-' symbol (instead of a `MINUS', which also wraps round on overflow without crashing). The course library `plus' process uses a `PLUS', precisely so that it can be used on number streams that get too large or too small.

Your program `crashing' is expected behaviour, if you have used the algebraic operator symbols. The sum of 1..65535 is just less than 231 -- when 65536 is added, it'll overflow. "Crash" is perhaps a slightly strong term in this case -- the (overflow) error was correctly detected and appropriate action taken. But use the `PLUS' (or `MINUS') operators and the overflow will be ignored -- that's what Java does anyway!

Keywords: q4


Question 34 (2004):

When the system is paused, do we need to guard against the user typing in other valid command letters such as `n', `p' etc. ? In my system, when it is paused through a `s' pressing any other valid commands creates a deadlock!

Answer 34:

From the `q4.occ' file:

-->  's' ==> suspends output to the screen.  Output is resumed by the next
-->          keypress (which is NOT processed according to the above rules
-->          -- it is merely the signal to resume output).

So pressing any key whilst paused (including valid command keys) should just resume the output.

Keywords: q4


Question 33 (2004):

I was reading the bit about graceful termination in the course notes and understand about sending poison down the line to shut each process down properly. My question is does this mean that we have to change every single component that we use, i.e. `delta', `succ', etc. ?

Answer 33:

Yes, to get processes like `delta' to shut down nicely, modification will be required. However, you're not expected to implement graceful termination for Q4 -- you can do if you like, but it's quite a lot of hard work. Essentially anything that has a `WHILE TRUE' loop needs adjusting in some way -- such loops cannot terminate..

Keywords: q4 , graceful-termination


Question 32 (2004):

I'm now somewhat through Q4 and have noticed that I'm using polling `PRI ALT's. It says in the coures notes that they should be used only as a last result -- I'm wondering if this is acceptable in Q4?

I'm not sure of another way of interupting a process based on a signal that may or may not arrive. I've created PRI ALTs in the new control PROCs that have been added to `numbers', `integrate' & `pairs'. I'm now planning on using it to react to the byte `s'

Answer 32:

As the course notes say, polling should only be used as a last resort. I wonder, however, if you're actually polling.. Polling code is specifically this:

    PRI ALT
      c ? x
        ...  do something with `x'
      TRUE & SKIP                -- skip guard
        SKIP                         -- do nothing

When executed, if data is available on the `c' channel (i.e. the corresponding outputting process is blocked in the output), then that data will be accepted immediately (placed in `x') and the guarded process runs. If data is not available on the `c' channel, the `SKIP' guard is selected and does nothing -- so the `PRI ALT' finishes immediately.

That code is polling, and it can create problems.. For example:

    WHILE TRUE
      PRI ALT
        c ? x
          ...  do something with `x'
        TRUE & SKIP
          SKIP

This code will consume as much CPU as it can until some data arrives on the channel `c'. Of course, the correct code in this case (since the process does not interact with anything else in the loop) would be:

    WHILE TRUE
      SEQ
        c ? x
        ...  do something with `x'

This code, on the other hand, will wait for something to arrive on `c' then do something with the data received. And waiting (either blocked on channel communication or waiting for a timeout with `AFTER') does not consume the CPU. (although busy-wait versions of these could be created easily, it would be daft..).

It's the `SKIP' guard in the `PRI ALT' (and subsequent do-nothing process or do-very-little process) that constitutes polling.

The following code, for example, is not strictly polling (but it is not nice code):

    WHILE TRUE
      PRI ALT
        c ? x
          ...  do something with `x'
        TRUE & SKIP
          SEQ
            d ? y
            ...  do something with `y'

If you've written stuff like that, you probably wanted instead to write:

    WHILE TRUE
      PRI ALT
        c ? x
          ...  do something with `x'
        d ? y
          ...  do something with `y'

These two code fragments do not behave in the same way, however. The first will commit to input on `d' if `c' is not ready -- refusing then to service `c' until something has arrived on `d'. The second will happily wait for both, and service the first channel that becomes ready (or `c' in preferance to `d' if both are ready).

You can read some more on ALTs and polling in this occam tutorial.

Keywords: q4 , polling

Referrers: Question 23 (2010)


Question 30 (2004):

In the diagrams that you have put into Q4, you have connected the `monitor' only to `numbers' `integrate' and `pairs'. Surely this also needs to be connected to the `layout.max.chans' as to allow output to the screen or not? That is the way I managed to do it in Q3 and it seemed to work ok.

Answer 30:

The keyboard characters input by the `monitor' process do not have to be echoed to the screen channel.

I assume you are talking about the suspend mechanism, in reaction to an `s' keyboard input -- the fourth modification. From `q3.occ':

  --{{{  data-flow diagram
  --
  --Sorry ... you're on your own here.
  --
  --}}}

So yes, some extra connectivity is required beyond that shown on the diagram for the third set of modifications.

However, altering `layout.max.chans' (to take that extra connectivity) is not the simplest approach -- the re-programming is untidy; since it takes its original inputs in PARallel, you will need to poll the extra one separately.

A simpler approach, as discussed in the seminars for Q3, is to create a separate `suspend' component that can be added to the existing process network (with some minor extra wiring) -- and leave `layout.max.chans' unchanged.

It's usually better engineering to add new functionality by adding a new (parallel) process specifically to implement it, rather than by modifying an existing component to add to its responsibilities. For performance reasons, we may sometimes need to fold parallel processes together into one single (but more complex) serial process -- but that can be done later (and fairly mechanically). In this exercise, there is no such performance constraint. In fact, the model answer adds code to slow the system down to produce output at only 10 lines/second, so that it's easier to see the effect of the controlling keystrokes. You might like to do the same -- though this is voluntary!

Keywords: q4

2003

Question 45 (2003):

I have done the rest of the assignment but Im have trouble with pairs.mod, I have defined new PROC's:

    [snip code]

Below is my code for `pairs.mod':

    [snip code]

    PAR
      replace.bool (l.2,control,l.1)

      [snip code]

      SEQ
        prefix.bool(TRUE, l.2, l.1)
        delta.bool(l.1, l.2, l.3)

The trouble I have is that it says I have parallel inputs on channel `l.1', but this is similar to the way I implemented the other mods and they all work...

Answer 45:

This can't be right -- both these processes run for ever, so it doesn't make sense to execute them sequentially. Once `prefix.bool' starts, control can never return, so `delta.bool' never runs.

There appear to be two parallel OUTputs on channel `l.1', in replace.bool and prefix.bool

Keywords: q4


Question 44 (2003):

Additional to Q40, I havn't actually started using `layout.max.chans' yet, because none of my deltas will work. Currently I've got numbers outputting into the delta I gave which outputs one channel into an output module which just outputs whatever ints it gets onto the screen straight away and the other output going to nowhere. If I remove the delta i get the output i expected, but with the delta in between I get no output. The only thing that can possibly be wrong is the delta. Any more ideas?

Answer 44:

If you leave the second output of the delta unconnected, the delta will get blocked when it tries to output. If you want to discard the data, connect it to an INT style black-hole:

    PROC int.black.hole (CHAN OF INT in)
      WHILE TRUE
        INT v:
        in ? v
    :

Keywords: q4 , deadlock


Question 43 (2003):

Will I be penalised if I use STOP to create a deadlock for Question 4?

Answer 43:

No, but it's not a very nice way of inducing deadlock, and it's not always correct. In the default `error-mode', processes that STOP cause a run-time error and the whole program finishes. In `stop' error-mode (which isn't the default), processes that STOP just die quietly, leaving the rest of the program running. Thus, if you use STOP, you should do it in such a way that the program would deadlock `nicely'.

A quick way of causing local deadlock is to communicate on an unconnected channel, simply:

    CHAN OF INT dummy:
    dummy ! 42                   -- deadlocks here, because there's nothing connected to the other side

Keywords: q4 , stop


Question 42 (2003):

Which diagrams do I need to submit with this assignment? (Q4)

Answer 42:

You should submit diagrams for all processes you create or modify. I.e., the modified process networks for `numbers', `integrate' and `pairs', and the overall top-level `q4' network. Also include `icons' for processes you create, if these aren't immediately obvious in the other network diagrams.

Keywords: q4 , diagrams


Question 41 (2003):

Referring to Assignment on Q4:

  1. Are we allowed to implement a minus process? - I did
  2. Should I use an array of output channels in my monitor? - I'm defining 3 seperate outputs
  3. Should I use protocols for the channel types? - I figured that since my channel types are mostly very simple (i.e CHAN OF INT, BYTE) that I could leave it as it is. Will I be penalised for that?

Answer 41:

Yes, you may well need to implement a `minus' process, but it depends on how you go about solving that bit. For monitor outputs, a channel-array or separate channels are equally valid. On your third point, technically `INT' is a protocol. The structured PROTOCOL types should only be used if you need them -- you don't need them for this assignment.

Keywords: q4


Question 40 (2003):

    delta (g, h, c[0])

this is in my main q4 proc. `g' is the input coming from numbers, `c[0]' is an output which will go to layout.max.chans and `h' is an output which will go into integrate. I know numbers gives an output as I've tested it with an output module, but as soon as I attatch the output from number to the input of this delta neither `h' or `c[0]' give any outputs when tested with the same output module.

I can't for the life of me see what I've done wrong! I've checked that all channels are connected correctly over and over so its not that either. Any ideas?

Answer 40:

Two numbers must be output by the `numbers' process before any proper output appears. Since all the output is done via `layout.max.chans', that must input from each of its channels before anything will be displayed on the screen. Thus, if any of those input channels are unconnected, nothing will happen -- the `layout.max.chans' process will wait for input forever -- the `max.chans' constant defines how many channels should be `layed-out'. Similarly, if your pairs process doesn't output after two inputs, things will deadlock -- `layout.max.chans' will be waiting for that final input and the remainer of the network will probably be blocked on output.

Keywords: q4


Question 39 (2003):

I've done the third mod and it works fine. However, someone has just mentioned that you didn't want us to modify the `plus' process. Is this true ?

Answer 39:

The question says:

  'p' ==> the first 'p' zaps the adder process within pairs so that it
          becomes a subtractor, taking the numbers arriving directly from
          the delta process away from those arriving from the tail.  In this
          state, the modified pairs becomes a `differentiator', undoing
          the `integration' effect of the process immediately upstream so
          that we see the natural numbers sequence.  A second 'p' toggles
          the process back to its original state.  Subsequent 'p's toggle
          between the two states.

There is not a single `right' way to do this. The first line seems to imply that you should modify the adder process, though there is a neat solution that doesn't.

Keywords: q4


Question 38 (2003):

Do we have to use the replace function provided for q4 ?

I have a working q4 but it does not use the replace function. That ok?

Answer 38:

In theory, yes. However, if your solution would have been more efficient using `replace' you may lose marks based on that. However, if your solution is succinct and correct, no marks will be lost.

Keywords: q4


Question 36 (2003):

To suspend screen output, would directing the `out.int' and `out.string' to a `black.hole' be appropriate ? I have tried this but it doesn't seem to work, am I going in the right direction or completely off.

Answer 36:

Re-directing the output to a `black.hole' won't suspend it -- it'll gobble it up, like a black-hole. To suspend the output you need to stop the flow of data, which is often simpler than re-directing it. See the model answer for question 3 (on raptor) for an idea of how to do this.

Keywords: q4 , suspend


Question 34 (2003):

    [snip code]

I'm probably missing something really obvious, but why is this not giving any output? There is nothing coming in through the input channel, but yet when I attatch it to a tested output module nothing comes out.

Answer 34:

Look carefully at the PROC heading for `replace':

    PROC replace (CHAN OF INT in, control, out)

and note the ordering of the `in' and `control' channel parameters.

Keywords: q4


Question 31 (2003):

I'm a bit confused about the `out.int' and `out.string' PROCs in `layout.max.chans' in Q4. Are they already defined somewhere, because I can't seem to find them. Or are we meant to define these two PROCs ?

Answer 31:

They are defined elsewhere -- in `course.lib' to be precise, so you must not define them yourself -- doing so will result in linker errors when it finds two copies of each (one from the course library and one from your code).

These two PROCs just write INTs or BYTE-arrays to a BYTE channel, aligning in the given `field' (2nd parameter). Writing `out.string' is easy, `out.int' less so. You can find the code for these on raptor in:

    /usr/local/courses/co516/libsrc/utils.occ

Keywords: out.int , out.string , q4


Question 29 (2003):

I'm having trouble with getting the `pairs' process to toggle adding and subtracting. The following code compiles but doesn't do much, the only effect being that an input on the control line stops any other keypresses getting through. Ive tried declaring `subtract' in various places to no avail. Thanks.

    [snip code]

Answer 29:

See the answer to Question 27 (2003) for a brief description of the problem. Your code contains the process networks for both versions of pairs, but once running, these will never terminate -- they contain `WHILE TRUE' loops. You need to modify the process network itself -- not `wrap' the networks up in other code, as that won't work.

Keywords: q4


Question 27 (2003):

I'm having some problems with the new pairs process. This is what I've done:

    [snip code]

It doesn't seem to be doing anything. Any suggestion ?

Answer 27:

This appears to be a common mistake -- you're instancing the `plus' and `minus' PROCs from inside another component, that results in your component behaving like either `plus' or `minus' respectively. However, once called, these PROCs never return, as they have WHILE TRUE loops.

If you want a single component to take care of the addition/subtraction, you have to engineer (program) it that way -- i.e. a single self-contained PROC, not one that instances other PROCs. If you do want to re-use the existing `plus' and `minus' PROCs, they have to be engineered into a suitable parallel network -- i.e. instanced directly under a PAR, not from sequential code.

Keywords: q4 , process-networks

Referrers: Question 29 (2003)


Question 25 (2003):

I have now got a completed version of q4. However, in this monitor process...

    [snip code]

.... it will only reset `I' or `P' if I press the key twice and it pauses it inbetween each key press. How come it is doing this as it is only the `S' case that asks for a second input? Also, typing in N twice causes the program to deadlock, yet I can't think of why. Any suggestions?

Answer 25:

You have an ALT guard of the form:

    in ? y
      BYTE x:
      SEQ
        in ? x
        ...  do something based on `x'

Before getting to the `do something based on `x'' bit, two inputs will happen on "in". Remember that in an ALT, input guards do perform the input before the guarded process runs. The correct guard/process would be something like:

    in ? y
      ...  do something based on `y'

Keywords: q4 , alternation


Question 23 (2003):

Are we allowed to create a process called `my.prefix', and replace the standard `PROC prefix (...)' within `my.numbers' / `my.integrate' with the new `PROC my.prefix (...)' ?

Answer 23:

Yes, in theory there's no problem with doing that. However, for this assessment, there shouldn't be a need to do this, but that depends on how you go about modifying the various process networks.

Keywords: q4


Question 21 (2003):

I am having trouble with step 3 of the assessment. I am trying to have a variable that is set to either 1 or -1, and then the one of the numbers within pairs is multiplied by this number before the addition takes place (having the effect of subtraction).

My trouble comes in where to create and initialise the variable (call it `b'). At the moment I have it in my monitor process...

    [snip code]

but when I compile, it whinges on the line marked that `b' is not declared. Doesn't the declaration at the top of the PROC last throughout the process ?? If not, how can I introduce the `b' variable without it being reset to one each time the process is run??

Answer 21:

The rule with variable declarations in occam is that they are visible in the process following the declaration, and only that process.

For a good description of this, which relates directly to the error in your code, see Question 3 (2000). You should have gotten an error about incorrect indentation in that code too..

Keywords: q4


Question 20 (2003):

My part 2 of the assessment will not work. I have tried everything and, despite being able to get it to compile, nothing I can do can get the keyboard input to have the desired effect. I have proved that the keyboard input is being read, but I don't know why it's not running the rest of the program as it should

    [snip code]

... am I right in thinking that once it has outputted 0 down either the `n' or `i' channel, it should then come out of the process and go back to my `q4' process (where it was called from), and thus go on to execute the whole number sequence thing but with the values of 0 waiting to be inputted on either the `numbers.reset' or `integrate.reset' processes.

I ask because no matter how I seem to plug these processes together (each one making its own sense), they don't seem to work!!

Answer 20:

Removing some of your code, and assuming you fed it `i' on the keyboard, you are left with a process that behaves something like:

    CHAN OF INT i:
    SEQ
      i ! 0

This immediately deadlocks. The reason is that the channel you are trying to output on is unconnected -- there is no parallel process performing the corresponding input (remember that channel communication in occam is a synchronous action, as well as a communication -- i.e., both the inputting and outputting processes must wait for each other before the communication can take place).

The `q4.occ' file shows (in ASCII art), the process network that ought to be constructed:

                               |
                               v keyboard
   ____________________________|___________________________________
  |                            |                                   |
  |                       _____|_____                              |
  |            __________|           |                             |
  |           /      'n' |  monitor  |                             |
  |          /           |___________|                             |
  |         v                  | 'i'                               |
  |        /                   v                                   |
  |   ____/____     /|    _____|_____     /|    _______            |
  |  |         |   / |   |           |   / |   |       |           |
  |  | numbers |->-  |->-| integrate |->-  |->-| pairs |\          |
  |  |_________|   \ |   |___________|   \ |   |_______| \         |
  |                 \|\                   \|\             \        | error
  |                    \________             \             \     ------>--
  |                             v             v             v      |
  |                            __\_____________\_____________\__   |
  |                           |                                 |  | screen
  |                           |         layout.max.chans        |------>--
  | q4                        |_________________________________|  |
  |________________________________________________________________|

Thus, taking code straight from the diagram, the PROC header for this particular `monitor' process should be of the form:

    PROC monitor (CHAN OF BYTE keyboard, CHAN OF INT to.numbers, to.integrate)

... and the monitor process resets the numbers and integrate processes by communicating on the channels given to it as parameters. The actual channels used are part of the `q4' process (i.e. should be declared there) -- as can be seen in the diagram.

Keywords: q4 , parallelism


Question 19 (2003):

Is there something special that we need to do to get what we press on our keyboards to register in occam as my program isn't picking up any keyboard inputs, yet by my reckoning it should be. It works for the `a3.occ' file tho ?

Help!

Answer 19:

If you have a correctly programmed monitor process, there should be no problem with the keyboard. When you type keys into occam programs, they are not echo'd back to the screen unless you explicitly program this -- so it appears you are typing blind. Might this be the problem ?

If things ought to be happening, but aren't, double-check the `monitor' programming. Also check that it is wired up correctly -- i.e. with the keyboard channel.

Keywords: keyboard-input , q4


Question 18 (2003):

    [snip code]

I have plugged the `i' and `n' channels into `integrate.reset' and `numbers.reset' respectively and yet, though the program compiles, it only seems to be running the `step1' process and not taking any keyboard input or taking it but not acting on it. Any clues as to what is wrong ??

Answer 18:

Yes, although I can only give a fairly restricted answer here. If you want a more detailed response, mail your seminar leader -- they'll be happy to help. If you're in Peter's group, he's not around just at the moment, so you may mail me (frmb) instead.

The main problem with your solution, so far, is that it is not parallel. Your main process either runs the `monitor' code, or the `step1' code. For the network to work correctly, you need to have these as two distinct and separate parallel processes, with channels connecting them.

Keywords: q4


Question 17 (2003):

In order to change the behaviour of the pairs process each time `p' is pressed, can we re-implement pairs without including the plus and minus processes, and carry out the calculations using the PLUS and MINUS operators directly ? Or is it best to keep the plus and minus processes involved ?

Answer 17:

In many ways, that's entirely up to you -- for example, try both, see how they turn out. What you must not do is trash the default `pairs' process and replace it with a purely sequential `pairs' process. After any/all modifications, the `pairs' process must still be a network of sub-processes. Depending on how you decide to approach this part, you might need to write new processes of your own (as opposed to simply modifying old ones).

Note, however, that the `plus' process and `PLUS' operator are utterly unrelated -- one is a process, the other is used for building expressions. One cannot be substituted for the other, without a significant amount of work. The choice (between operators) of whether to use `+' or `PLUS' is up to you. The former is often better, since the program will Stop before generating incorrect data. The latter simply ignores integer overflow -- which will usually result in incorrect answers being generated.

Keywords: q4


Question 13 (2003):

For Q4 what is the command to make the terminal bleep when any other character is entered apart from those specified?

Answer 13:

Output an ASCII "bell" character:

    out ! BELL

The `BELL' constant is defined in `consts.inc', that is included by q4.occ.

The constant definition is simply:

    VAL BYTE BELL IS 7:

It may not work on some terminals -- i.e., those that cannot beep, or those that are configured not to beep.

Keywords: q4 , bell , beep

Referrers: Question 32 (2003)


Question 12 (2003):

do we hand in Q4 through reception or online?

Answer 12:

At Reception -- cover sheet, printout of code, and process diagrams. The deadline for Q4 is now Thursday 20th November.

Keywords: q4 , submission


Question 10 (2003):

Hi, i'm trying to implement the second part of q4, where the inputs `n' and `i' have an effect on the operation of the program.

I have defined a `monitor' process which outputs 1 to a chan, depending on what the keystroke is:

PROC monitor ([]CHAN OF INT out, CHAN OF BYTE keyboard, intr)
  --{{{  forever
  WHILE TRUE
    ...  wait for `intr' and process accordingly
  --}}}
:

When trying to implement my version of `numbers', I wanted to continue using the numbers as normal, but if the INT 1 came in through a `control' chan, to set the value of the input to the prefix as 0 (hence starting it from the beginning again)

PROC my.numbers (CHAN OF INT out, control)
  CHAN OF INT a, b, c:
  WHILE TRUE
    PRI ALT
      INT x:
      control ? x
        IF
          x = 1
            c := 0
          TRUE
            PAR
              delta(a, out, b)
              succ(b, c)
              prefix(0, c, a)
:

However, it doesn't work. Any help ? :)

Answer 10:

As regards numbers, you can't do what you're trying to do with the above code. The compiler will reject it at the ``c := 0'' line, since you can't assign to a channel. We'll assume you meant to output instead, `c ! 0'.

The compiler won't reject that code (if fixed), but it won't work either. Initially `my.numbers' will wait for a signal on the `control' channel -- and won't output anything.

You'll notice this immediately, and maybe press the `n' key to prod `my.numbers'. Given this, the ALT will wake up and run the IF process. Given that `x' will be 1, `my.numbers' will attempt to output on the `c' channel, and deadlock -- there isn't anything connected to the other side of that channel. If, for some reason, `x' was not 1, the original `numbers' process network is run (by the PAR). That'll happily output numbers forever and ignore the `control' channel, such that an attempt by `monitor' to communicate will cause deadlock (in `monitor' as it attempts to output).

You actually need to modify the original process network for this one, as will be explained in the seminars this week (if it hasn't already). To do this, you need to understand what happens when the `numbers' network is switched-on; essentially a number `flows' round in the loop, being incremented by `succ' each time, with `delta' producing the copy that is output. Thus, to reset the numbers back to zero, you need to interfere with that `flow'.

In occam, you can't interfere with a process externally -- the compiler just won't let you (unless you forcefully turn the checking off, but this is rarely a good thing). Attempts to communicate `externally' on the `c' channel (and in parallel), will be banned by the compiler. The modification needs to be `deeper'.

Note: Eerke has mentioned that the deadline for Q4 has been moved back one week, into project week. From the ukc.cs.cs2 newsgroup:

This also reduces the deadline bunching in week 8: the minor pieces of coursework are still there, the major one for CO516 is now the single deadline in week 9.

.. so you've got a bit more time on this.

Keywords: q4 , process-networks

2002

Question 23 (2002):

I'm trying to edit question 4 for the assignment but when I open it using 'gvim q4.occ' it opens but is just black and white text and it beeps at me!

Answer 23:

Check the answer to Question 16 (2002). Note: starting work for an assignment the morning that assignment is due is probably not a good strategy ...

Keywords: q4 , gvim


Question 19 (2002):

For the second modification task, I have created my own processors numbers.reset and integrate.reset which respond to the inputs 'n' and 'i' respectively, however when I assign the replace processor to be used within each of these processors, it displays an invalid process error:-

     :    reset ? ch
     :    IF
     :      (ch = 'n')
     :        PAR
  318:          replace (a, 0, b)
     :          delta (b, out, c)
     :          succ (c, d)
     :          prefix (0, d, a)
     :      TRUE
  Error-oc-q4.occ(304)- Invalid process
  type tree not caught by case (switch) is CHAN

Why does this occur?

Answer 19:

Well ... replace takes 3 channel parameters and you supply an INT (0) as one of them! The Solaris kroc compiler does give a poor error message, but nobody at INMOS ever thought someone would write code like that! The Linux kroc handles this better.

Your code is very wrong though. You are misunderstanding something fundamental. See your seminar leader. [If you get an 'n' in the above, you start up a PAR construct that never ends ...?]

Keywords: q4 , channels


Question 18 (2002):

For part two of q4, where it states "clearly numbers and integrate will have to be reimplemented", do we declare a new process (such as numbersOne) within q4 and modify this or can we edit the version in demo.nets?

Answer 18:

You need to declare a new process (such as numbersOne) before q4 in your file q4.occ. Cut and paste the numbers code from demo.nets and modify that. You can't, of course, edit the file demo.nets - you don't have write permission ...

Keywords: q4


Question 17 (2002):

Is it me or for the second modification do you have to change not only numbers to accommodate a reset command but prefix as well? The same goes for changes that have to be made to integrate and its internal code. Is there an easier way to do this or not?

Answer 17:

I'm afraid it's you. You have to change the numbers process because it's functionality has changed - it's got a reset line! To make this change, however, you don't have to change any of its old sub-components - i.e. prefix, delta and successor - but you do have to insert one extra sub-component into its circuit. The same observations apply for the needed change to integrate.

Keywords: q4


Question 15 (2002):

I have just completed the 'p' operation. It un-does the last operation but the numbers are one out each time:

          43902      963714753          43903
          43903      963758656          43904
          43904      963802560          43905
          43905      963846465          43906

Is this still correct or should I be getting the same in the last colunm as in the first colunm?

Answer 15:

No - that's fine! The model answer (answers/a4) does the same thing.

Keywords: q4


Question 14 (2002):

In q4 you say 'q' should be dealt with by putting the system into deadlock. Can't we use the command STOP instead?

Answer 14:

Well ... you can, but it's not very nice. Any process executing a STOP - in the current versions of KRoC - causes the whole system to stop in a rather ungraceful way. On the Solaris version, it even causes a core dump! Later versions of KRoC will offer an option so that only the process executing a STOP will stop (i.e. freeze, which is subtly different from terminate) - leaving the rest of the system running. This is what is supposed to heppen.

So, getting your process to respond to 'q' with a STOP is allowed - you will not lose marks for this solution. For a better solution see Question 12 (2002).

Keywords: q4 , deadlock


Question 13 (2002):

This is the error i keep getting and I don't understand why, max.chans is still set at 3, can you help, I can't seem to get passed this to get on with the rest!?

  raptor$ kroc q4.occ

      :    delta(a,b,e)
      :    integrate(b,c)
      :    delta(c,d,f)
      :    pairs(d,g)
   315:    layout.max.chans(e,f,g,screen)
      :
      ::
      :
      :
  Error-oc-q4.occ(315)- Too many actual parameters in call of layout.max.chans

Answer 13:

You have too many parameters! layout.max.chans takes just two parameters - an array of input channels and an output channel. You are supplying four parameters, :-(.

Your channels e, f and g should be elements of an array - e.g. c[0], c[1] and c[2]. Then, your instantiation would be:

           layout.max.chans (c, screen)

An alternative solution is to keep your channels, e, f and g, as they were and construct the array required by layout.max.chans on-the-fly:

           layout.max.chans ([e, f, g], screen)

Keywords: q4 , compiling


Question 12 (2002):

For the final modification to q4, when my program is running, I press q and the screen outut stops, and then if I press any key a deadlock message comes up and the terminal shows the raptor prompt again.

Answer 12:

Presumably, you react to the q by sending a suitable signal to the same process implementing the suspend mechanism? What we were suggesting was for that process to terminate (i.e. exit its loop and finish) when it gets that quit signal. That leaves no route for the streams of numbers to get to the screen and most of your q4 system is deadlocked.

However, your keyboard monitoring process is still alive, waiting for more keystrokes. If you type anything but the ones it wants (e.g. anything bar 'n', 'i', 'p', 's', 'q'), it swallows it and loops around and stays alive. If you type an 'n' (for example), it tries to output a reset signal to a deadlocked component. That doesn't succeed and the keyboard process is stuck trying to output. There are now no processes left to run - and, now, the run-time system can announce deadlock and terminate. This solution is fine, but the model answer does something slightly different ...

Keywords: q4 , output

Referrers: Question 14 (2002)

2001

Question 15 (2001):

Can you give me a hint on how to implement the `PAUSE' method for part 4? I know how to do the quit function but need to be able to put this deadlock within the pause function.

Answer 15:

Implement a `PAUSE' in the same way as you did for question 3 (as discussed in your seminar groups). To cause deadlock as the response to a QUIT, the simplest way is to arrange for the process that manages the PAUSE effect to terminate - that leaves its upstream processes blocked all trying to output. Your keyboard monitor is still active - so your system is not yet deadlocked. But as soon as you type one of the characters to which it responds by outputting to the rest of your (now blocked) system, that output won't be taken and your keyboard monitor will block. Everything is now stuck and the run-time system will detect deadlock and quit.

Keywords: pause-process , q4


Question 14 (2001):

I have created the `pause' process to respond to `s' as step 4 of Q4 asks. But where does it go? Does it take input direct from the keyboard and then outputs to the monitor or does the monitor output to the pause process??

Answer 14:

It can't take input direct from the keyboard (as happened for question 3), since the keyboard is already connected to the monitor process. Channels may only connect to one process (at each end). So, I guess that monitor must output to the pause process!

Oh - I see what you were wondering: connect keyboard to the pause process along with the input/output channels whose traffic it's going to freeze ... and pass on keyboard input other than `s' to the monitor. Well, you could try that but I would advise against. There is a nasty deadlock lurking if you do this ... can you see it?

Keywords: pause-process , q4


Question 13 (2001):

From Question 31 (2000), it says:

Getting the monitor to trigger a deadlock (in response to a `q') is easy and will earn full marks (for this part).

Would we get full marks if we implement a livelock ... or do we have to trigger a deadlock?

Answer 13:

Forcing a livelock is a bad idea - your program keeps on running! Forcing a deadlock will terminate your program.

Keywords: deadlock , q4


Question 11 (2001):

In Question 4, for the monitor process we are asked to implement the following: `any other character is an error and is processed by bleeping the screen'. I've looked at last years Q+A's on the web but I can't find help on this. Could you give some kind of clue as to how we can produce a bleep from the PC squeaker in occam?

Answer 11:

You missed it! See the answer to Question 18 (2000).

Keywords: q4 , bell , beep

2000

Question 49 (2000):

I get an error message when trying to compile the folowing:-

PROC plus.modified (CHAN OF INT in1, in2, control, out)
  WHILE TRUE
    PRI ALT
      control signal
        ...  actions when control signal is received
      plus (in1, in2, out)             -- <<< ERROR MESSAGE HERE
:

I get an error message saying expected end-of-line found when a ? was needed. What's the problem?

Answer 49:

You are creating an instance of the plus process in a position where the compiler expects another guard for your PRI ALT. There is nowhere legal you can put that line without adding an extra SEQ (or, possibly, PAR). Bear in mind that once plus starts, it never terminates - so don't ever expect to go around the loop again if you invoke it somewhere in the loop body ...

The first guard of your PRI ALT is syntactically illegal. There should be a ? in the middle of it - and where is your signal variable defined?

Finally, if your PRI ALT is really meant to have a single guard, it's a bit pointless - better simply to use a SEQ.

Keywords: q4


Question 47 (2000):

I am having some trouble with part 3 of the assessment. Here's my code:

  ...  censored

What I'm trying to do is pass through a channel of INTs, multiplying them by a factor, whilst in parallel checking another channel to see if the monitor has passed a zero and, if so, changing the factor.

The problem is that KRoC won't complile the code because it won't let me read and write to a variable in parallel - which is fair enough 'cause I could see some problem arising if they both want access to it at the same time.

Is there a way to get round this, or do I need to rethink my ideas?

Answer 47:

I haven't shown the code because it's wrong in too many ways, I'm afraid, and posting it would not help anyone.

It's not KRoC that won't compile it so much as the language doesn't allow it (and, therefore, KRoC rejects it). We are simply not allowed to look at a variable in parallel with another process that's changing it. So, you do need to rethink your ideas. Check out Question 44 (2000) and its answer.

Keywords: q4 , process-networks


Question 44 (2000):

I am currently doing the pairs toggling bit of Q4. I am trying to say

  IF there is a toggle input
  THEN switched := NOT switched
  ELSE carry on excuting the rest of the code.

where toggle is an input channel and switched is a boolean variable.

Answer 44:

You are describing a poll on the toggle channel. See slide 5-37 in the notes. You may consider the use of polling absolutely essential (see the comment on slide 5-37) for your solution to this part of the question - even though it's not!

Keywords: q4 , inverting , if

Referrers: Question 47 (2000)


Question 41 (2000):

Should we be using PLUS/MINUS or +/- for Q4?

My class supervisor told me that we should be using +/-. But when I do that, my q4 process crashes very quickly due to not being able to wrap round into negative numbers. Is this OK or should I use PLUS/MINUS and allow the program to wrap round?

Answer 41:

Please use PLUS/MINUS rather than +/-. That's what the plus process (from the course library) uses and that was chosen specifically to allow these demo programs to run forever. The Fibonacci sequence gets big very quickly - so the demo example program would crash very quickly otherwise. Of course, the numbers in the supposed-Fibonacci column are no longer from the Fibonacci sequence ... but never mind.

However, whether you use PLUS/MINUS or +/-, you will not lose marks. I've squared things with your supervisor!

Keywords: q4 , overflow


Question 39 (2000):

In the specification for the p bit in q4.occ, it says: "take the output arriving from the tail from that arriving directly from the delta". I'm certain, well confident, well satisfied, ... ERM.. at least I think I've implemented it as specified, but my output gives:

  -1
  -2
  -3
  -4
  ...

I am very tempted just to switch the channels going into plus so that it gives:

  1
  2
  3
  4
  ...

when its in subtractor mode. Or are the negative numbers actually what's required ... i.e. the assignment means do as I say not do what you think I mean ... ?

Answer 39:

You've got me here! In question 4 on the exercise sheet, it doesn't attempt to specify which way around the minusing should operate (in response to a p from the keyboard). So, doing it either way round would be OK.

In the q4.occ file, I tried to make this precise but - given the complexities of natural language - managed to say it the wrong way around :-( ... Apologies for this. So, doing it either way round - what I said or what I meant - is OK.

Keywords: q4 , negative-numbers


Question 38 (2000):

In question 4, when you press the i key to reset the integrate thingy, should it output 0, or the next value that comes in?

Answer 38:

The question did not specify - so either version will be accepted.

Keywords: q4


Question 37 (2000):

I'm in the process of doing q4 and I've implemented everything except pairs. It all compiles but, when I run it, it immediately gives me an error:

  Range error / STOP executed (signal 4)
  Fatal error code 1, core dumped
  Abort (core dumped)

First thoughts were that I had used STOP wrong. However, I took it out and still got the same error. I can't work out where I could be going out of range, so I just wondered if you could explain the error message to me so I could work out what part of my code it is refering to.

Answer 37:

The run-time error messages are a bit terse, I'm afraid. The above error message can be caused by at least 4 things:

It's probably the last one that's your problem ...

Keywords: q4 , range-error , stop


Question 36 (2000):

Do you just want the code for q4.occ or do you want any new diagrams we have done drawn out as well?

Answer 36:

You should submit hard-copy of your program listing attached to a cover sheet to the CAS office (by close of business on Thursday, 30th. November, 2000). You should also include network diagrams of any networks you have designed. In this case, that will be for your modified versions of numbers, integrate and pairs, together with the overall network for the q4 process. On these diagrams, channel names should be labelled with the names used in your code and the direction of data-flow should be arrowed. Neat hand-drawn diagrams on you program listings are fine.

Keywords: q4 , diagrams


Question 35 (2000):

For the assessment, are we allowed to code the modified versions of int and pairs sequentially, as is lecture slide 5-11? Or do we have to stick to creating them from the given components in "course.lib"?

Answer 35:

No - when you modify those processes to introduce the reset/toggle channels, keep the same level of concurrency. But this can't be done just by inserting extra components from "course.lib" - you have to use some others. A big hint is supplied by the inclusion of the replace process in your starter file (exercises/q4.occ) - you just have to work out how to use it. The model answer reuses the existing sub-components (of numbers, integrate and pairs) unchanged - their behaviour is modified simply by inserting an extra process into their respective circuits.

Modified versions of slide 5-11 type implementations will be accepted, but will not attract full marks.

Keywords: q4


Question 34 (2000):

I am having trouble with the layout.max.chans process. I am calling it within another PROC as follows:

  PROC q4 (...)
    ...
    ...
    [max.chans] CHAN OF INT c:
    PAR
      ...
      ...
      ...
      ...
      ...
      layout.max.chans ([c], screen)
  :

Am I calling it correctly?

Answer 34:

No. Your c variable is already an array holding max.chans elements (that happen to be channels). The expression [c] creates an array with one element (that happens to be an array of three channels) - this is not what layout.max.chans is expecting! Your call should be:

      layout.max.chans (c, screen)

Keywords: q4


Question 32 (2000):

When implementing the response to an `s' being pressed should it either:

Answer 32:

The former - see the answer to Question 26 (2000).

Keywords: q4 , suspend


Question 31 (2000):

Can we use the keyword STOP in response to a `q' being pressed in Assignment 2?

Answer 31:

Yes - but KRoC is currently set up to regard STOP as an error, so your program will crash. That's OK but not very nice!

We might change KRoC to handle a STOP differently - occam allows more than one semantics. The default one is the current one - treat it as an error. The (arguably proper) one is that the process executing the STOP just stops, but other processes running in parallel continue.

If we made this change, then simply getting your monitor process to execute a STOP would stop that monitor - but the rest of your network might carry on producing output (depending on how you set it up). That would be wrong.

So, your monitor process needs to do something to block everything else as well (e.g. cause a deadlock). The model answer blocks all of the network, but leaves the monitor running (all it does is go into a state where it black holes all keyboard input). The system is not deadlocked because the monitor is still alive and accepting further input. Nothing more is being produced, though, and keyboard input is consumed but ignored - we have livelock.

Bringing a network to a graceful halt (by causing all its component processes to reach their natural end without triggering deadlock) is hard. The paper in the course book ("Graceful Termination - Graceful Resetting") shows how to do it - it's fairly mechanical but tedious. For this exercise, you would have to make new versions of all the basic cycle processes used from the course library - these new versions would be ready to terminate (i.e. no WHILE TRUEs).

But graceful termination is not required. Just getting the monitor to execute STOP is also not good. Getting the monitor to trigger a deadlock (in response to a `q') is easy and will earn full marks (for this part).

Keywords: q4 , stop

Referrers: Question 13 (2001)


Question 30 (2000):

I am currently working on modification 3 of q4. I have modified the code so that it switches between being a plus and minus process - but when switching to the minus process all the numbers printed are 1 greater than the number entered. Is this OK or should a further modification be made to compensate for this error?

Answer 30:

It's OK! Turning the plus into a minus changes pairs into a differentiate, except that the first number that ought to be output is missing. All the question asks is that you make this change (dynamically, in response to a `p' from the keyboard). What it does doesn't matter. So the fact that it turns that last process into something that (almost) cancels out the second, leaving you with traffic that equals the input to the second - except that one number gets lost - is fine.

Keywords: q4


Question 29 (2000):

Help! I am trying to do part three of question 4 (the second assignment) and I can't get the following to compile. The error message is that state is not declared on the line marked:

  WHILE TRUE
    SEQ
      BOOL state:
      state := TRUE  -- start with normal pairs process
      WHILE state    -- <<<< COMPILER COMPLAINS HERE
        ...  loop body

Surely though, it is - just above the line which causes the compiler to fail!

Answer 29:

No it's not!! It's declared two lines before the line complained of by the compiler. Declarations have scope for subsequent declarations and the first executable that follows (which must all be at the same level of indentation). In the above, the first executable following the declaration is the assignment - so state is in scope there, but not for the following executable (the while-loop).

To make the declaration have scope for more than one executable, those executables must be wrapped up in a SEQ (or PAR or WHILE or IF etc.) - that turns them into a single executable. This question has been asked before - see the answer to Question 3 (2000).

Keywords: q4 , variable-scope

Referrers: Question 54 (2004)


Question 27 (2000):

When implementing the part where the plus process is changed to a subtractor when `p' is pressed, am I right in saying we don't really have to change pairs apart from the reset. The rest is done by changing the component plus?

Answer 27:

Yes - that is one way to do it. There is another way that does not require changing that plus process - merely inserts another component into the (modified) pairs network.

Keywords: q4


Question 26 (2000):

In Q4, when you say `suspends output to the screen', do you mean the processes should keep going and not output anything to the screen, or pause and wait until they are allowed to continue?

Answer 26:

The latter - the processes should become blocked until output is allowed back through to the screen. Don't modify those processes in any way to get this functionalty. Do it the same way you did it for question 3 from the Execrcise Sheet (which was considered in your seminar groups).

Keywords: q4 , suspend

Referrers: Question 32 (2000)


Question 24 (2000):

I am working on q4.occ. Inside one of my PROC headers, I have delcared a BYTE variable:

  BYTE c:

I then read in a BYTE and store it into this variable. Then, I wish to do checks on this variable to see what character it is holding. For example:

  IF
    c = 'n'
      ...  do something

This obviously isn't how it's done? Looking back at bugs.occ quotations marks give the ASCII value of the char.

Please let me know how this is done as I can find nothing about this in the notes.

Answer 24:

There is nothing wrong with the code fragments above. A character within single quotation marks is a BYTE literal, whose value is the ASCII code of the quoted character. Mail me (or your seminar leader) your complete code and say precisely what goes wrong.

Keywords: q4


Question 17 (2000):

On q4, when I convert plus to minus in pairs ... should the output from pairs be one greater than the output from numbers along the same row of data? For example, if the current numbers value is 7, then the value in the pairs column on the same line is 8 ...

Answer 17:

Yes. (I'll say a bit more when the q2 submission deadline is over ...)

Keywords: q4

Valid CSS!

Valid XHTML 1.0!

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
Last modified Mon May 20 13:50:31 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.