kent logo

CO538 Anonymous Questions and Answers

This page lists the various questions and answers. 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.

We have taken the liberty of making some minor typographical corrections to some of the questions as originally put. Although most of the questions here will have been submitted anonymously, this page also serves to answer some questions of general interest to those on the course.

When asking questions, please do not simply paste in your code and ask what is wrong with it, as these types of question are hard to answer in a public forum (resulting in either no answer, or an answer which will only be of use to the person asking the question). In many cases, a question about code can be formulated in general terms. For example, if you have an `IF' block that results in an `incorrect indentation' error, you might ask, ``what is the correct syntax for an occam `if' statement ?''. Questions of this form are easier to answer, and are meaningful to all.

Questions that are not suitable for these public pages (i.e. those that contain assignment-specific code), should be mailed to your seminar-leader.

Question 101:

Do we need to use occam that is going to work on raptor or can we make use of the additions in the KRoC/Linux version. For example I'm considering using the STEP stride part for the replicator.

Next when using replicators, why can't I pass "i" into the "cursor.x.y()" PROC in this code ?

    PAR i = 8 FOR 5 STEP 2
        cursor.x.y (23, i, out)
        -- print stuff

Where "i" is the line number. The error is a type mismatch for parameter 2 in "cursor.x.y()". Surely "i" is an integer and should be accepted ?

Any help appreciated...

Answer 101:

For KRoC/Linux extensions (rather, occam-pi extensions), yes, using those is fine. We'll most likely be testing your code on such a machine.

The reason you can't pass "i" as a parameter is because "cursor.x.y" takes "VAL BYTE" parameters (not "VAL INT"). The solution for such things is to cast the parameter to the appropriate type:

    cursor.x.y (23, BYTE i, out)

Given the code you've got above, it should generate another error also (related to parallel usage), but that should be slightly more obvious.

Keywords: q7 , cast

Question 102:

Is it possible to specify more than one condition in an "IF" process ? For example:

      x = 0 AND y = 0
        -- do something

If so which operators should be used ? When I compile something similar to the above I get an error saying:

    Expected new line, found AND

Answer 102:

This error occurs because you need explicit bracketing (occam has no operator precedence), even though the alternatives don't make much sense in this case. The correct way to write that would be:

      (x = 0) AND (y = 0)
        -- do something

Keywords: q7 , operators

Question 103:

How do I output the value of "n.sat.down" to the screen ? Is the only way to add an "out" channel the PROC header and do an "out.int" on it ?

Answer 103:

If "n.sat.down" is a tag in a variant protocol, it doesn't have any meaningful value. Some meaningful data might be communicated as part of the protocol, however. You mention adding an "out" channel, but to what PROC in particular ?

To avoid complication, the correct place to handle the output of this information is in your "display" process. Wiring it up to the "security" process (by default the only process that knows how many philosophers are sat down) should be fairly straight-forward.

Keywords: q7 , output

Question 104:

I have a quick question relating to my 'animation' - could you give any tips/ideas for nice(r) way of making the philosophers move about the screen without hard coding in the locations of every movement?

In my more 'advanced' animation (which has been a challenge to say the least) I have had a lot of hassle using a hard coded method. The code just to move a philosopher to the table (and it's currently not very smooth) is around 300 lines. Ouch.

I am sure there is a better way of doing things but I have racked my brains and I can't think of anything :(. The only other idea was to create a "large" VAL [][5][2]BYTE array that stored all the locations, and for each movement the required value is pulled out the array. That doesn't seem much nicer though; occam doesn't seem to allow you to span this sort of thing over multiple lines either.

Any sort of help would be greatly appreciated, however small!

Answer 104:

If ever you find yourself writing long sequences of repetitive code, where the differences are primarily in number values, you are doing something wrong, ugly and inefficient! So, your 300 lines of code is not a good idea.

Your 'better way' is much better, although it can be improved (see towards the end of this answer). Your VAL [][5][2]BYTE is, presumably, a 2-dimensional array of coordinates (i.e. [2]BYTEs), with the [5] index being for the philosophers and the unsized outermost dimension (i.e. []) being for the number of coordinates (i.e. the length of the path). That might make slightly more sense (and convenience for programming) with the two outer dimensions swapped around -- i.e. VAL [5][][2]BYTE.

occam does allow long lines to be broken across multiple lines ... but maybe I never told you! You can break a long line after commas, operators and the keyword IS. For example, the very long one-line declaration:

  VAL [n.phils][][2]BYTE path IS [[[13, 12], [14, 12], [14, 13], [14, 14], [14, 15]], [[23, 12], [24, 12], [24, 13], [24, 14], [24, 15]], [[33, 22], [34, 22], [34, 23], [34, 24], [34, 25]], [[83, 82], [84, 82], [84, 83], [84, 84], [84, 85]], [[93, 92], [94, 92], [94, 93], [94, 94], [94, 95]]]:

can be much more readibly laid out:

  VAL [n.phils][][2]BYTE path IS
    [[[13, 12], [14, 12], [14, 13], [14, 14], [14, 15]],
     [[23, 12], [24, 12], [24, 13], [24, 14], [24, 15]],
     [[33, 22], [34, 22], [34, 23], [34, 24], [34, 25]],
     [[83, 82], [84, 82], [84, 83], [84, 84], [84, 85]],
     [[93, 92], [94, 92], [94, 93], [94, 94], [94, 95]]]:

The rule about indentation for continuation lines is that any indentation at least as great as the initial line is allowed. So, the following, rather stupid, layout is also possible:

  VAL [n.phils][][2]BYTE path IS
    [[[13, 12], [14, 12], [14, 13], [14, 14], [14, 15]],
           [[23, 12], [24, 12], [24, 13], [24, 14], [24, 15]],
  [[33, 22], [34, 22], [34, 23], [34, 24], [34, 25]],
   [[83, 82], [84, 82], [84, 83], [84, 84], [84, 85]],
         [[93, 92], [94, 92], [94, 93], [94, 94], [94, 95]]]:

but we wouldn't, of course, ever do that! Another use of breaking lines after commas we have seen lots of times -- in PROC headers with long parameter lists:

  PROC thing (CHAN OF INT in0, in1,
	      CHAN OF BYTE keyboard, screen, error,
	      VAL INT id, interval,
	      [][]REAL64 data)

instead of:

  PROC thing (CHAN OF INT in0, in1, CHAN OF BYTE keyboard, screen, error, VAL INT id, interval, [][]REAL64 data)

Breaking lines after operators helps keep large expressions neat -- for example:

    first := (first - second) + ( ((-first) + (third - second)) * (rotational.torque - (ratio/2)) )

could be written:

    first := (first - second) +
	       ( ((-first) + (third - second)) *
		 (rotational.torque - (ratio/2)) )

which might help a little.

Getting back to improving your path description for a wandering philosopher ... rather than declare a table of absolute coordinates for each path position, consider a table of relative movements. For example:

  VAL [n.phils][][2]BYTE path IS
    [[[left, 3], [up, 5], [right, 2], [up, 4], [left, 1], [down, 2]],
     [[down, 8], [up, 3], [left, 6], [down, 1], [left, 6], [down, 3]],
     [[right, 3], [down, 2], [right, 8], [down, 9], [right, 1], [down, 5]],
     [[up, 5], [left, 5], [down, 2], [up, 2], [down, 1], [up, 3]],
     [[up, 9], [right, 9], [up, 2], [left, 2], [up, 3], [left, 6]]]:

where your movement code interprets [left, 3] as "move left 3 places" etc. Predeclared, of course, would need to be something like:

  VAL BYTE left IS 0:
  VAL BYTE right IS 1:
  VAL BYTE up IS 2:
  VAL BYTE down IS 3:

Elsewhere would be needed a table of absolute start coordinates for each path movement.

That just leaves the problem that all the above path lengths have to be the same length? With the modern occam-pi language, that's not a problem ... we can use dynamically sized mobile arrays. For classical occam, you could pad out short paths with some dummy movement elements - e.g. STAY where:

  VAL BYTE stay IS 255:

  VAL [2]BYTE STAY IS [stay, 0]:

  VAL [n.phils][][2]BYTE path IS
    [[[left, 3], [up, 5], [right, 2], [up, 4], STAY, STAY],
     [[down, 8], [up, 3], [left, 6], [down, 1], [left, 6], STAY],
     [[right, 3], [down, 2], [right, 8], [down, 9], [right, 1], [down, 5]],
     [[up, 5], [left, 5], STAY, STAY, STAY, STAY],
     [[up, 9], [right, 9], [up, 2], [left, 2], [up, 3], STAY]]:

Keywords: q7 , animation , long-lines

Referrers: Question 43 (2009) , Question 30 (2008)

Question 105:

Just out of curiosity, which chapter will we be examined on ? Will we be expected to know about the Transputer and the different processes (talked about in chapter 2) ?

Answer 105:

You will be examined on the material presented in the lectures. For the occam part of this module, we omitted chapter 1, (most of) chapter 3, chapter 7 and chapter 9. That leaves chapters 2, 4, 5, 6, 8, 10 and some of 3 (chapter 3 has little technical content). But the papers in the course notes are also part of the examinable material. The "Checklist", "occam Approach", "Hard Real-Time" and "GOTO" papers all write up material presented through the slides. The "Emulating", "Graceful" and "Paradigms" papers explore ideas we didn't present, but a study of them will broaden your understanding and confidence. [BTW, the Transputer was not mentioned in chapter 2 and, no, you will not be examined on the Transputer!]

For the rest of this term, we will be studying concurrency in Java through the JCSP packages, which provide the same model you have learnt through occam. The JCSP materials are also, of course, examinable.

All this will be apparent to those attending lectures. If you miss any, it is your responsibility to find out what you missed ...

Keywords: exams

Referrers: Question 129 (2004)

Question 106:

Could you explain "SHARED" channels again and maybe give an example ? From the class they seem like a cleaver idea but now when it comes to coding them I am a little lost.

Answer 106:

[Note: the first part of this answer is now obsolete! The SEMAPHORE data type is no longer supported by the multicore run-time systems for occam-pi. The second part of this answer (using SHARED channel) is the correct way to do things now.]

There are two ways to do shared-channels in occam, and which one you choose will depend on whether you're coding on Linux or Solaris.

KRoC/Linux has built-in support for shared channels, called "anonymous channel types" in the form most useful for Q7. You can find a fairly terse example of these here.

Shared channels on the KRoC installed on raptor must be done manually -- by turning off compiler usage-checks and using "SEMAPHORE"s to provide mutual exclusion.

For comparison and reference, below are two equivalent versions of a simple test program that use shared channels:

    #INCLUDE "semaphore.inc"            -- NOTE: this version is no longer valid.
    #USE "course.module"

    PROC hello (SEMAPHORE sem, CHAN BYTE out!, VAL INT id)
        claim.semaphore (sem)
        --{{{  output stuff
        out.string ("hello world from ", 0, out!)
        out.int (id, 0, out!)
        out.string ("*n", 0, out!)
        release.semaphore (sem)

    PROC main (CHAN BYTE kyb, scr!, err!)
      #PRAGMA SHARED scr
      SEMAPHORE sem:
      #PRAGMA SHARED sem
        initialise.semaphore (sem, 1)
        PAR i = 0 FOR 10
          hello (sem, scr!, i)

and (if using KRoC):

    #USE "course.module"

    PROC hello (SHARED CHAN BYTE out!, VAL INT id)
      CLAIM out!
          --{{{  output stuff
          out.string ("hello world from ", 0, out!)
          out.int (id, 0, out!)
          out.string ("*n", 0, out!)

    PROC main (SHARED CHAN BYTE scr!)
      PAR i = 0 FOR 10
        hello (scr!, i)

but (if using the Transterpreter – see Question 22 (2008)):

    #USE "course.lib"

    PROC hello (SHARED CHAN BYTE out!, VAL INT id)
      CLAIM out!
          --{{{  output stuff
          out.string ("hello world from ", 0, out!)
          out.int (id, 0, out!)
          out.string ("*n", 0, out!)

    PROC main (CHAN BYTE key?, scr!, err!)

      SHARED ! CHAN BYTE screen:             -- output end shared


        PAR i = 0 FOR 10
          hello (screen!, i)

	WHILE TRUE                           -- byte "id" process
	  BYTE ch:
	    screen ? ch
	    scr ! ch


Keywords: q7 , shared-channel

Question 107:

This is used for the animation:

      clear.states (4 + (4 * n), out)

but when I try to use "clear.states" I get an error! help.

Answer 107:

Saying what error you get might be useful.. But "clear.states" must be something you've defined yourself -- it's not provided by any library. The errors generated by the compiler are generally meaningful and useful, and should be telling you what the problem is.

Keywords: q7

Question 108:

I'm thinking of changing my protocol from:



        thinking; INT
        hungry: INT

to tell me which philisopher is hungry, thinking, etc. Is this a wise move or is there another way I can find this out in the "display" process ? Currently I'm ALTing over the channels to see if they're thinking, hungry, etc.

Currently if a philisopher is thinking it prints (philosopher is thinking) with no knowledge of who is thinking.

Answer 108:

Yes, this probably is a wise move. The only other way you can get that information is by having the "display" process knowledgeable about its wiring. I.e., in the array of "REPORT" channels, which channel is connected to which philosopher, etc. This is not entirely desirable, however, since re-wiring such a network would break the "display" process.

Keywords: q7 , protocol

Question 109:

How many more channels need to be added to the PROC header of the philosopher? When I add an output channel to my "fork", "philosopher" and "security" PROCs, I get an error in the "secure.college" PROC stating parallel outputs on one channel. How do I get around this?

Answer 109:

Form the code from the diagram of it -- you'll see that there is only one additional (report) channel coming out of a philosopher, so that's all that should be added to its header. The error relating to parallel output is in "secure.college", so that is where the error lies -- not in "philosopher", etc. A key rule is you can't do parallel outputs to the same channel. So, we need an array of channels, one for each of the reporting processes inside "secure.college". The "display" process takes the other (reading) end of that array of channels. How to do this has been covered fairly extensively in the seminars. If you're already using an array of channels, check the indices you're using -- one or more must be wrong if the compiler is giving you this error (you can expand the replicators by hand to see where the error lies).

Keywords: q7

Question 110:

Is this the correct piece of code for waiting a random time ?

      seed := seed + id
      i, seed := random(num, seed)
      tim ? t
      tim ? AFTER t PLUS i

Answer 110:

More or less, yes. Make sure you initialise "seed" appropriately though -- the code above initialises it based on itself (if undefined, it'll stay undefined). As covered in the seminars, a quick way to get an initial seed value is:

    tim ? seed
    seed := (seed >> 2) + 1   -- maybe also add in the `id'

Remember also that your seed should be explicitly initialised like this just once -- before loop entry. Within the loop, cycling through the philosopher's life, the seed value gets updated as you use the random function. The sequence of seed values takes you through the "random" numbers. If you re-initialise the seed every time round the loop, the computed randomness will be lost.

Keywords: q7 , timers

Question 111:

Is it possible we can actually see the implementation of the PROCs, like: "erase.screen()", "erase.bol()" and others in the utils file ?

Answer 111:

Yes, just look at the source code! See Question 63 (2003) for an indication of where it is.

Keywords: q7 , course-library

Question 112:

Why is this bit of code gvining the error: Parallel outputs on channel out, when the channels down and up are used in security as well as philosopher?

   [Code snipped]

Answer 112:

As said many times before, we can't debug specific code on these pages!

However, the compiler is generating a correct error message - it usually does. Your network has mutliple processes writing to the same out channels - the up and down channels are irrelevant here.. When you've fixed that, you might want to put those out channels in the parameter list for secure.college - having them as local channels mean they don't connect to anything in the world outside the college ... such as a display process ...

Keywords: q7

Question 113:

Hello. I saw your answer to Question 109 (2003) about the colours in text and was wondering where and how to find out the codes for other colours. Thanks.

Answer 113:

Well, the answer to the question you referenced says to do a quick Google search. I just did and it came up with this link which, when combined with Question 109 (2003), tells all, :).

Keywords: q7

Question 114:

How do we submit our dining philosopher's assignment?

Answer 114:

Copying from the newsgroup announcement ...

Your assessment, "A4 DINING PHILOSOPHERS ANIMATION", is due on Monday in week 18 - i.e. Monday, 14th. February, 2005.

This time, we want to compile and run your programs! Submission directories are open at:

  \\raptor\files\proj\co516\q7\        (from Windows)


  /usr/local/proj/co516/q7/            (from Unix/raptor)

Please copy your source code (.occ) file(s) there. Please do *NOT* copy executables. You only have access to <your-login-name> directory.

If your solution follows the standard model (i.e. an array of channels connecting the college process and the display process, with the display also connected to the screen channel), you do *NOT* need to include a network diagram.

If your solution has a non-standard network, please include a network diagram with your submission. This can be as a .pdf, .ps, .ppt or .doc file. For anything else, you must submit hard copy to CAS reception together with a cover sheet. A neat hand-drawn diagram is very acceptable through that route.

The submission directories will close at midnight between Monday/Tuesday - i.e. at 00:00 on Tuesday, 15th. February.

Keywords: q7

Question 115:

When I try to run my q7 answer on my Linux box (Mandrake 10.1) I get this error:

    KRoC: unable to find clock file (.kroc_clock or /etc/kroc_clock)

What does it mean and what can i do to fix it ?

Answer 115:

It's because you're missing the KRoC clock file. When you installed the software it prints out a message saying that you must copy "~/.kroc_clock" to the current-directory or to "/etc/". This file just contains your CPU speed in MHz (as read from "/proc/cpuinfo"). Newer versions of KRoC/Linux (1.3.4-pre4 and above I think) will automatically read the speed out of "/proc/cpuinfo" if a clock file isn't found.

Keywords: q7 , linux

Question 116:

Is A7 the minimum you expect from us for Q7 ?

Answer 116:

It's minimal in the sense that if you implement something that produces similar output you can get 100%. But that's a generous estimate; some marks are inevitably lost for untidy coding, errors, etc.

Keywords: q7

Question 117:

Hi there, can you give some clues of how to get the forks working in Q7. Everything I am trying isn't working :-(

Answer 117:

The forks already work by default -- adding the reports shouldn't break them! The best idea would be to mail your seminar leader with a copy of the code, who can then advise on what the problem is.

Keywords: q7

Question 118:

Do you think anyone would be offended if someone were to name their philosophers after occam seminar leaders ;)

Answer 118:

No ...

Keywords: q7

Question 119:

Oh dear oh dear - q7-bodden-2003: it just crashed on me after running for a while! Shocking.

  KROC: Fatal error / STOP executed (signal 4)
  KROC: Fatal error code 1, core dumped

Aren't these supposed to be 'model' answers? ^_^

Answer 119:

Humm ... I guess you mean the a7-bodden-2003 program ... there isn't a q7-bodden-2003 one?!! [Actually, it's simple naming typos like these that cause masses of software crashes, :(]

But, seriously, a7 is the model demo executable. All others are to give you ideas/challenges. We haven't verified them completely. Thanks for telling us that that one breaks. We will fix ...

Keywords: q7

Question 120:

In occam, if I've got a BYTE array, I would have thought I could do something like this: (where "i" is an INT)

    array[5] := BYTE i

but it doesn't appear to work, can you explain why that is, when something such as this works perfectly fine: (where "b" is a BYTE).

    array[5] := b

Answer 120:

That should work fine, and does for me.. What error (exactly) are you getting ? Something else must be wrong..

Keywords: q7 , arrays

Referrers: Question 121 (2004)

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:23 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.