CO631 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 q7
2005 |
Submission reference: IN733
Hey, just wondering if the bonus question system for the exam will be in place this year again? What I had heard about the system was that if we do all questions in the exam, we would be awarded full credit for the best 3 questions and half credit for the remaining extra question. Thanks for your time.
No. Last year's rubric was deemed too complicated (although no student or staff had any problem with it!).
All rubrics for this year's papers are published here. For Co631:
There are FOUR questions. Candidates should answer THREE questions, the ONE question from Section A and TWO from Section B.
If your answer all THREE from Section B, one of the answers will not count. Sorry -- you must follow the rubric.
Keywords: q7
Submission reference: IN638
With the random number generator are you supposed to create a new process to create the random number or does it go within an existing process. If this is the case do you have to have 2 random generators for thinking and eating. If the only way to get better marks for the assessment is to use this, why didn't we have it explained in lectures?...Thank you for your help
The "random" thing is just a FUNCTION, so you can call it inline or wrap it up in a process; I prefer inline calls. This may not be needed for the philosophers assessment set this year, however, there's plenty of documentation on it available, it's not hard to use, and it'll produce a more convincing animation. Just because it's not required doesn't mean that you can't do/use it!
Keywords: q7
Submission reference: IN629
Hi, I was just wondering what kind of delays should we put in between the philosophers thinking and eating. If we set them to eat for longer than think, then you'll see the security flag up as a 5th tries to sit, however if you set them to think for longer then you'll very rarely see the security go up, if at all. What should the time delays roughly be?
The delays should be random. See the other questions under the random keyword for details on how to use it.
However, you are right that the eating times should be a bit longer, mostly, than the thinking times ... to get a chance to see a hungry philosopher who is blocked by security.. Suggest making eating times random between 6 and 15 seconds, with the thinking times random between 2 and 8 seconds. If the action still seems a bit slow, reduce by a factor of 10 - experiment!
2004 |
Just curious if you will/have selected any more dining philosopher solutions to add to the raptor answers collection ?
Possibly -- I've already put one into the KRoC/Linux distribution's set of dining philosophers, but this can't go on raptor because it uses some of the occam-pi extensions (not supported by the version of KRoC installed on raptor). We might put some more in, and put on raptor (if compatible).
Keywords: q7 , model-answers
Hi, I've completed the q7 coursework but I would like to ask a question before I submit it. I found no need for the "PROC secure.college", so I removed it and did all the necessary wiring in "PROC q7". The animation still works and I feel I can understand my code better this way. Will I be marked down for the removal of "secure.college" ?
Yes, you will lose marks. There is a reason for having "secure.college" - namely structure! Discarding it leaves its innards and the "display" at the same level of network ... which is (a) more complicated and (b) illogical. Please tidy them back into a "secure.college" wrapping.
Keywords: q7
Continued from Question 120 (2004)... I'm actually working with a 2D array, although I don't think that makes any difference ? I'm not getting an error, it's a little strange but it appears to remove the byte, for example with:
log[0] := "Philxxxis eating " log[0][5] := (BYTE n)
after this operation, "log[0]" seems to contain "Philxxis eating ". Any ideas ? I'm feeling slightly baffled.
The reason this is probably happening is because "BYTE n" is not a printable character. Casting an INT to a BYTE does not produce the character representation of the number in base-10 (decimal) -- it produces the ASCII character with the value of the integer. If you want to print out a number as its (decimal) character representation, use "out.int".
Keywords: q7
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
That should work fine, and does for me.. What error (exactly) are you getting ? Something else must be wrong..
Referrers: Question 121 (2004)
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 Abort
Aren't these supposed to be 'model' answers? ^_^
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
Do you think anyone would be offended if someone were to name their philosophers after occam seminar leaders ;)
No ...
Keywords: q7
Hi there, can you give some clues of how to get the forks working in Q7. Everything I am trying isn't working :-(
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
Is A7 the minimum you expect from us for Q7 ?
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
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 ?
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.
How do we submit our dining philosopher's assignment?
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)
or:
/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
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.
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
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]
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
Is it possible we can actually see the implementation of the PROCs, like: "erase.screen()", "erase.bol()" and others in the utils file ?
Yes, just look at the source code! See Question 63 (2003) for an indication of where it is.
Keywords: q7 , course-library
Is this the correct piece of code for waiting a random time ?
SEQ seed := seed + id i, seed := random(num, seed) tim ? t tim ? AFTER t PLUS i
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.
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?
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
I'm thinking of changing my protocol from:
PROTOCOL REPORT CASE thinking hungry ... :
to:
PROTOCOL REPORT CASE 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.
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.
This is used for the animation:
SEQ clear.states (4 + (4 * n), out) ...
but when I try to use "clear.states" I get an error! help.
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
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.
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" #USE "course.lib" PROC hello (SEMAPHORE sem, CHAN OF BYTE out, VAL INT id) SEQ 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 OF BYTE kyb, scr, err) #PRAGMA SHARED scr SEMAPHORE sem: #PRAGMA SHARED sem SEQ initialise.semaphore (sem, 1) PAR i = 0 FOR 10 hello (sem, scr, i) :
and:
#USE "course.lib" PROC hello (SHARED CHAN BYTE out!, VAL INT id) CLAIM out! SEQ --{{{ 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) :
Keywords: q7 , shared-channel
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!
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
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 ?
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.
Is it possible to specify more than one condition in an "IF" process ? For example:
IF 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
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:
IF (x = 0) AND (y = 0) -- do something
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 SEQ 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...
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.
Why in "PROC philsopher (...)", do you have:
PAR -- pick up left ! TRUE -- forks right ! TRUE ... eat PAR -- put down left ! TRUE -- forks right ! TRUE
i.e. why is the code the same for pick up and putting down the forks ?
The reason is simply that it requires less channels. Extra channels could be added for the putting-fork-down events, but it's better if we can re-use the existing channels (less coding and less plumbing on the network diagram). The same reasoning applies to the fork process -- adding extra channels is possible, but unnecessary.
The direction of communication along the left and right channels is important to the fork process. That has to choose (i.e. ALT) between competing signals from its adjacent philosopher processes, who might be trying to pick it up. That signal is represented by a channel communication. We can only ALT between input communications, so the forks must input and the philosophers must output. This is for picking up the forks.
For putting down the forks, neither side needs to ALT ... so the direction of the communication, signalling this event, doesn't matter. So, the fork could output to the philosopher who picked it up (and be blocked until that philosopher did a corresponding input to indicate that it was putting down the fork). But, then, we would need another channel (a putting-down-channel) between each philosopher and fork - since channels may be used in one direction only and we are forced to use the existing ones in the other direction. So, the simplest thing is to reuse the existing channels and get the fork to input from it (and be blocked until the philospher holding it does an output to indicate that it was putting down the fork) ... which is what happens.
Note that we do use different channels between each philosopher and the security guard to represent the let-me-in-to-the-dining-room and let-me-out signals. The security has to ALT between all of these, so the direction of communication has to be from the philosophers to security. The security has to ALT both for the let-me-in and let-me-out signals, unlike the fork (which only has to ALT for the pick-up signals). But the security has also to refuse further let-me-in signals -- if four are already in -- whilst allowing let-me-outs! Doing that trick with only one channel used for both let-me-in and let-me-out signals is hard. So, we used separate channels.
Keywords: q7
Do we put the "VAL INT id" call inside the "PROC" header for philosopher and fork, or is this done in the main body of the "PROC" ? I think it is the former, but I'm not sure how to replicate this in "secure.college".
Be careful of your terminology -- "VAL INT id" would either be a parameter or abbreviation (that latter which you're unlikely to be using). It's not a "call" of any kind.
You are correct in thinking it should be in the PROC header for the philosopher, but what the PROC gets is a value (the "VAL" bit), not a variable. The replication in "secure.college" is already done for you -- you just need to "plug-in" the desired value (that should be fairly obvious if you look around, or compare the code with the network diagram for it). Also, looking at previous questions relating to q7 (particularly for previous years) will tell you the answer.
Keywords: q7
There seems to be some conflicting deadlines for Q7 ? On the Student Portal it says:
CO516 Parallel and Imperative Programming A4 DINING PHILOSOPHERS ANIMATION Mon, Wk 18 Tue, Wk 3 phw Mon, Wk 21 Reception
on the co516 webpage it says:
ASSESS 4 A4 DINING PHILOSOPHERS ANIMATION 60 32 3 Tuesday 17 Thursday
and my seminar leader says the 14th Feb is the deadline. Which of the above is the correct deadline?
Monday of week 18 (14th February) is the actual deadline, as we have been telling you in the seminar groups. So it's the webpage that's wrong. The data that appears under "assessments", etc. is not current -- we're not allowed to pull data from the live student database so stuff there will always lag behind the real student database.
Keywords: q7
Have we covered enough material to start the dining philosophers this holidays ?
Also are there any useful areas we can start to look at for revision (in terms of website with practice questions on what we've covered so far?)
The dining philosophers have been covered in the lecture, so yes, you could in theory make a start on this. But we'll be looking at this in more detail (e.g. ways of doing animations, etc.) in the seminars next year.
For revision material: the course notes (including the various papers on occam); Fred's occam tutorial; and past exam questions. But these are all obvious..! You should be able to decide for yourself whether something in a (past exam) question has been covered or not. Your own lecture notes may also be useful to this end.
Keywords: q7
2003 |
Whenever I report the number of philosphers sat down, it seems to just report 4 all of the time,
[snip code]
This code looks fine. It's most likely an error with the timing/delays in your animation. Without adequate `thinking' delays, the philosophers will always be trying to eat.
Keywords: q7
On the line 'forkStat[0] == 0' I get the following error message. What does it mean ?
: IF 122: forkStat[0] == 0 : SEQ Error-oc-q7.occ(122)- Operands have different types for operator "=="
The error is exactly as reported: the operands for `==' are of different types.
Firstly, comparison in occam is just `=' (this is not Java!). At a guess, `forkStat' is an array of channels, and `forkStat[0]' a single channel. You can't compare a channel with anything -- it doesn't have a value. What you need to do (if this is indeed a channel), is input the value first:
INT x: SEQ forkStat[0] ? x IF x = 0 ...
It's hard to tell for certain without seeing more of your code (whole `display' process, for example).
When you've got multiple input channels, and want to receive a value from any of them, use an ALT (or replicated ALT if suitable).
Keywords: q7
I get an error message saying that the `fork' is incorrectly indented, but I don't know why:
PAR i = 0 FOR 5 philosopher (...) fork (...)
You've removed the `PAR' inside the replicated `PAR'. A replicated PAR only replicated one process -- you're trying to give two, hence the indentation error.
The correct way to write this (as in the original `secure.college') is:
PAR i = 0 FOR 5 PAR philosopher (...) for (...)
Keywords: q7
Hi,
I dont quite understand when we should use `flush(out)'. Should this be after every time we make a statement like:
out.string ("Philosopher ", 0, out)
or after each set of changes such like:
out.string ("Fork ", 0, out) out.int (n + 1, 0, out) flush (out)
After each set of changes. See the answer to Question 91 (2000).
Hi,
Until recently I had my dining philosophers program running fine with scrolling text output, now I have added the table style animation it runs very slowly and sometimes there is a visible pause as it outputs a word. Are there any obvious things that could be causing this?
I an doing the animations like this:
SEQ clear.states (4 + (4 * n), out) cursor.x.y (32, BYTE (4 + (4 * n)), out) out.string ("Sitting", 0, out) flush (out)
Thank you.
Nothing looks wrong with the code you posted. If you're running it over a network (e.g. on raptor logged in from home), that could be the reason. It might also be raptor being slow (with everyone else doing their dining philosophers on it).
Hi,
I have a problem with parellel outputs when I make the `fork's report their states. I have one channel coming out of `secure.college' and the compiler says I am making parallel outputs on this channel. Both the forks and philosophers report down this channel. i.e.:
in `secure.college':
PAR philosopher (..., actionsOut[i], ...) fork (..., actionsOut[i], ...)
where `actionsOut' is the channel out of `secure.college'.
Is the only way to do this to have two channels out of `secure.college'. i.e.:
PAR philosopher (..., actionsPhil[i], ...) fork (..., actionsFork[i], ...)
Or is there a better way, as doing it this way will mean the multiplexer has to be much more complicated.
Thanks.
P.S. is there a rough number of microseconds you expect the delay in the philosophers to be or is this en tirely down to our discretion? thanks.
`actionsOut' is an array of channels, not a single channel. When the replicated PAR expands, each philosopher gets a separate channel (elements of the `actionsOut' array).
For example:
PROC foo ([]CHAN INT out!) PAR i = 0 FOR 5 bar (out[i]!) :
Is equivalent to writing:
PROC foo ([]CHAN INT out!) PAR bar (out[0]!) bar (out[1]!) bar (out[2]!) bar (out[3]!) bar (out[4]!) :
When the PAR replicator in your first fragment of `secure.college', you end up using the same channel for a parallel `fork' and `philosopher'.
Adding an extra array of channels is one solution, but as you point out, multiplexing this is messier. A better solution is to use channels in the same array, but in a way that avoids `collisions'. This can be done by changing the array subscript expression for either the `philosopher' or the `fork'. E.g.:
PAR philosopher (..., actionsOut[i], ...) fork (..., actionsOut[i+5], ...)
If you expand the PAR replicator, none of the resulting indexes are the same (so no parallel outputs).
In response to your last point, no, not really. The delay must be random, of course (using the random function). As rough guide, somewhere between 2 and 3 seconds, perhaps longer for the `eating' delay. Ultimately, you should find a suitable range, such that the animation runs `smoothly' (not too fast and not too slow).
Keywords: q7
On question 7, my philosophers pick up the forks fine but sometimes they tend to just pick up one fork and can eat and sometimes have 2 forks. I am using 3 multiplexers in total one for the philosophers, one for the forks and another to plex them two and also the security guard. I wonder if this could be affecting the output?
When a philosopher is eating, they should have both forks (on the display). There are three `messages' involved in this: left-fork picked up, right-fork picked up, and philosopher eating. Due to the way the system is `wired-up', the `display' process may receive these in any order. There is a chance that the ordering will be: philosopher-eating, left-fork then right-fork. Thus, it is important to ensure that display updates involving the philosopher do not intefere with display updates involving the forks -- accidently erasing previously outputted text, for example.
What you describe sounds like an artifact of the plumbing of your system - because you have 2 levels of multiplexing of report messages to your display process. Fortunately, this is fairly easy to correct!
When a philosopher or fork or the security guard outputs a report, if that report goes directly to the display process we know that that display process will update the screen (and FLUSH!) before dealing with the next report. However, if a fork (or philosopher) report goes first to a special fork (or philosopher) multiplexing process which then forwards it on to the actual display process, all the fork (or philosopher) knows - after outputting its report - is that that first level mulitplexor has got it, not that the display process has received it! The fork process may then interact with a philosopher (who is putting the fork back on the table) before the display process has shown the fork in the hand of that philospher. It is possible for the display process to animate the philospher moving to the eating position and then to the thinking position before it animates any fork movement, :(.
The simple fix is to get the philosopher or fork process to wait for confirmation from the multiplexor process to which it is connected that that multiplexor has indeed forwarded it to the display process - before the philosopher or fork process moves on. How to do this is described in the answer to Question 76 (2003).
Keywords: q7
How do we submit q7 ? Do we just hand in the hard copy at the octagon or do we need to submit this electonically as well?
The submission of the code will be electronic (so we can test/run your programs). You'll also need to submit a network diagram (on paper) to the CAS office. Keep an eye on the CS2 newsgroup for submission details (will be posted nearer the deadline).
Added later: submission directories have now been set up for you on raptor:
/usr/local/proj/co516/q7-2004/your-login-name/ (Unix view) \\raptor\files\proj\co516\q7-2004\your-login-name\ (Windows view)Please copy only your source code file(s) into there - usually this will just be one file called
You must also submit a paper copy of all relevant network diagrams for your solution. These must correspond to your code submitted electronically, with all channels labelled with the names used in your code. Don't forget to indicate directions of channel flow. This copy may be machine produced or neatly drawn by hand. This part of the submission must be to the CAS office, with a cover sheet (copies of which will be in the Co516 pigeon hole, near CAS Reception), BEFORE they close at 4pm on that Thursday.
Keywords: q7
I have an input channel into `secure.college()' of type INT which will contain the ID for each philosopher and fork. This channel will be connected to both the philospher and fork PROCs. How do I make sure that I get a number that is one greater than the previous down the channel so that each philosopher has a unique ID?
If you try and write code as you suggest above, the compiler will simply reject it (on a parallel (mis)usage error). Assigning IDs this way is hard. One question you should ask yourself is: ``do I really need to convey this information to the philosophers/forks using a channel communication ?''. The answer to that is: no. A `VAL INT id' parameter (for philosophers and forks) would be much simpler, and much clearer.
Keywords: q7
I'm trying to do a fair-ALT, but there are 11 channels to ALT over and thats a lot of of code! I was wondering is there a way of looping around FOR statements? What I mean is if the first time you write, say,
ALT i = 0 FOR 5
is there anyway so that the second time I can write
ALT i = 1 FOR 5
but have it so the 5th iteration loops back to channel 0 (i.e. the one I started on the first time). Sorry if thats unclear.
I'm not sure what you're asking here -- at a guess you're confused as to the operation of a replicated-ALT. One key idea is that it is a replicator, not a loop as such. Writing:
ALT i = 0 FOR 5 in[i] ? x P(x)
is equivalent to:
ALT in[0] ? x P(x) in[1] ? x P(x) in[2] ? x P(x) in[3] ? x P(x) in[4] ? x P(x)
For more information, look in the course notes that describe the ALT, around slide 5-29. The code for a fair-ALT is also given explicitly on slide 10-23, as you have been told many times! Also check out other related anonymous questions, particularly those on alternation and the fair-alt.
I seem to have some problems with the security. If 4 philosophers are sitting, it reports that 3 philosophers are sitting until another philosopher moves: at that point it says that 4 philosophers are sitting. This is my code for the philosopher and security:
[snip code]
Usual things about not posting huge chunks of code to the anonymous Q+A page. This sort of question should be directed to your seminar leader.
However; the code you posted looks fine. Check that your `display' process flushes the output when that information is updated. The problem you describe sounds like a classic symptom of this.
Keywords: q7
Are there any example source files of animation; I attended the seminar, but am having problems with even starting to animate.
There were four seminars you should have attended ...
You could look at `test_utils.occ' in:
/usr/local/courses/co516/examples
on Raptor. Or `examples/sort_pump.occ', but that uses `goto.x.y', which is now deprecated, rather than `cursor.x.y' (the two are essentially similar, however).
Essentially, text-animation is a repeating process of: move cursor, then output something. This can be seen most obviously in the `a7' model answer.
Source code for other animations can be found on Fred's occam page. These range from trivial to rather complex.
I'm confused on how to get the forks to move correctly. Is it a better idea to have to separate tags for left and right forks (``left.fork'', ``right.fork'') or to just have one (e.g. ``fork; INT'') ?
You need to mention what the `INT' is for, really. If it's the `id' of a fork, then that's one bit of information, but left/right is separate. Fork `i', for example, can be picked up or put down, by the philosopher on the left or right. The question is: do you need all this information from the fork, or just some of it, to do the animation ? -- watching the `a7' model answer should tell you this.
Keywords: q7
I have some mystery regarding Q7 I'd like to clear up. As I understand it the college must communicate its status to the display process via a number of channels. I think the only thing the display process needs to know is the status of each philosopher; the status of security and the forks can be deduced if we know what the philosophers are doing.
As it stands the college is self contained and there is no obvious way to report, at any given time, its status to another process. One solution I can see is to replicate all communications between the processes in college, and route them to the display process. The display process would maintain its own picture of the college, which it updates according to the inputs on its channels. This seems rather complicated.
Alternately the display process could again recieve a copy of all internal college communications, but conforming to a protocol such that it can update its picture of the college without other information about its status. For example, when a philosopher wishes to sit down, instead of outputting a boolean he outputs a specific message the display process knows to mean "waiting to sit down" and can update its picture accordingly. This is assuming that the animation is not drawn frame at a time, but continuously updated as information comes in.
In these cases what does display need to communicate with in order to get a complete picture ? Security can tell it who is wanting to sit down and stand up, but it also needs to know the fork status. Presumably this will be the job of either forks or philosopher.
I have trawled the anonymous questions of old, none of the answers to which have baffled me, but I still cannot get this fundamental.
All the questions you have asked have been discussed in your seminar groups for the last 4 weeks. These Q&A pages are in no way a substitute for attending those seminars. Your question suggests ideas that are either illegal (with respect to occam semantics) or far too complex. Simple solutions have been presented in the seminars.
Having said this, I will attempt to answer your questions. However, those who know how to do this problem should skip these answers, as correcting the confusion in your questions may confuse others unnecessarily.
In response to your first paragraph, yes, the state of the forks can be deduced from the philosopher, but it's easier to have the forks report their state. It also makes more sense; the state of a fork should be reported by the fork, not by something else.
You are sort of correct in your second paragraph, although I'm not sure what you mean by `replicate all communications'. Thankfully, setting up this extra `wiring' is not complicated in occam. However, the `display' process does not need to maintain the `state' of the college (see the next paragraph). The extra wiring can be handled using an array of channels; the `display' process gets the inputting ends as a `bundle' (array), whilst the outputting ends are distributed amongst the other processes. This will require some modifications to the `secure.college' process.
The third paragraph is essentially what we're expecting you to do for this assignment. The `philosopher', `fork' and `security' processes report their actions to the display as they happen. The display process just inputs these messages and draws on the screen accordingly. The animation should indeed be updated on-the-fly; it should not be done frame-by-frame. The only disadvantage is that the display cannot be completely redrawn (i.e. if it got corrupted, somehow). This isn't a problem for this assignment, however.
The various messages are best handled using a tagged protocol. The previous assignment, q6.occ, used a tagged protocol. The various `messages' have been discussed in the seminar groups. The q7.occ file gives some indication of what is required:
Your task is to animate this demonstration. Links will need to be made from the college to its external environment, through which the philsophers (and, maybe, the forks and the security guard) report their state. These links are gathered by a fair-ALTing server that drives a screen display in response to incoming information from the college. Thinking and eating by the philosphers should be modelled by random (but finite!) delays. The animated display should reflect the round table in the dining room ...
Running the example solutions (on raptor, see Question 80 (2003)) should give you an indication of what is required -- i.e. what is being displayed (and therefore reported) there ? (`a7' is the example minimum-but-full-marks solution; the other example solutions are more animated).
Reporting by each process should be restricted to its own `state'. I.e., the security process should not report that philosophers are trying to stand up or sit down. This is actually very hard.. The only state the security process maintains is how many philosophers are actually sat down -- it should report this. When a philosopher stands up or sits down, that should be reported by the philosopher -- not anything else. It is both more logical and simpler to have things this way, since it keeps the logic of each process `intact'. E.g. I might take your philosopher, fork, security and display processes, completely re-wire the nextwork (within reason), and still expect it to work. Having the correct functioning of processes depend on their external wiring is not really a good idea.. (such processes must conform to the protocol that they conceputally agreed on, however).
I hope this clears things up a bit. If you still have queries, or want some points explained in more detail, I'd suggest emailing or visiting your seminar-leader or other member of the course team (we all have a desk somewhere on campus).
Hi, what datatype does `cursor.x.y' take as im getting errors about wrong parameters.
The `x' and `y' parameters are BYTEs. The PROC header for `cursor.x.y' is:
PROC cursor.x.y (VAL BYTE x, y, CHAN BYTE out!)
See the answer to Question 7 (2000) for information on how to do a type-cast in occam.
Keywords: q7
I am stuck trying to do the implementation of philosopher, I know that we should try and use a random time, but at the moment I am just trying to implement it with a static time, say 5 secs.
[snip code]
Thats what ive done so far, and dont really know how to do the think and hungry stuff.
Thanks for any help
We've mentioned this before, but posting large chunks of code to the anon Q+A page and simply asking what's wrong isn't particularly useful -- the anon Q+A is a group forum, not an individual forum. You question would have been better directed to your seminar leader.
The code you pasted is largely the default `philosopher' code, with some minor additions.
If you want to know about the `random' function or timeouts, see the keyword index entries for timers and random. Reading through the questions and answers for past questions (particularly relating to q7) should hopefully answer any questions you might have. Alternatively, talk to your seminar leader (preferably during the seminar).
Keywords: q7
Can we still get full marks on q7 if we just do a basic line by line 'animation' of what is going on ?
If you have just a scrolling output of events, the answer is no. The minimum solution (that can get full marks) is a table-driven animation, shown by the `a7' example answer. This can be found on raptor in the `/usr/local/courses/co516/answers/' directory.
Keywords: q7
Referrers: Question 88 (2003)
Having problems with q7. In our seminar we were told to use:
i, seed := random (n, seed)
to create a random number. Can you explain what each of the elements are, also can you give a basic example.
This part of the Philosopher proc is going to be a base for all 5 philosophers, but there is the problem of each having the same random number for each one. Do we need to have a different value of `n' and `seed' each time the PROC is run? Or is this dealt with by the random function ?
The `seed' is there to initialise the random number generator. More specifically, it is the internal state of the `random' function -- functions cannot retain their own state.
Before you call `random' for the first time, you need to initialise `seed' to a number between 1, and the maximum positive integer minus one. When you call `random' for a second time, use the new `seed' returned by the first call, and so on.
Yes, you need a different starting seed for each philosopher (hint: each philosopher has a different `id').
`n' is the range of the random number generated. i.e. `random' will return a random value between 0 and (n-1); in your example, assigned to `i'.
I'm quite confused on how I can assign each philosopher an identity. I've modified the header of the PROC philosopher in the following way:
PROC philosopher(CHAN OF INT id, CHAN OF BOOL left, right,down, up, CHAN OF MESSAGE report)
This means that the display PROC has 16 input channels. I'm not sure this is the right way of doing it.
Assigning IDs to the philosophers is better done by simply using a ``VAL INT'', passed to each philosopher from the PAR replicator that sets the network up.
Communicating the ID to each philosopher (using the `id' channel you added) is certainly possible, but definitely not the simplest way.
Hi, I'm just experimenting with my animation for q7 and I've come across an annoying problem with protocols in occam. My problem is that each channel seems to have a buffer. This creates a problem in protocol channels because there is no FLUSH like with the screen output. This means I have forks multiplying all over the place and philosiphers jumping around in mad bursts, despite huge delays tha are supposed to be in their movement. Is there any way of creating the effect of FLUSH on a protocol channel?
Channels have no buffers - no matter what their protocol. So you have to explain/analyse your problem a bit more. Once a channel output has completed, the other side has definitely taken it. Your channel output does not complete because the channel has buffered your message in some way.
If what you want is for the outputting process *not* to continue until the inputting process has completed some response to its input, you need to program that - e.g.:
PROTOCOL THING CASE data; ... -- the message types other; ... -- other message types ... complete -- only accepted once response is complete
Then the sending process:
SEQ ... stuff c ! data; ... c ! complete -- wait for response (e.g. animation) to complete ... more stuff
and the receiving process:
c ? CASE data; ... SEQ ... response (e.g. animation) c ? CASE complete -- let sender know all is done SKIP other; ... SEQ ... response (e.g. animation) c ? CASE complete -- let sender know all is done SKIP
Note: here is a little bit more of occam! If a CASE input only deals with one case (as in the above), it can be shortened to a one-liner:
c ? CASE data; ... SEQ ... response (e.g. animation) c ? CASE complete -- let sender know all is done SKIP other; ... SEQ ... response (e.g. animation) c ? CASE complete -- let sender know all is done SKIP
If the response to that one case is SKIP, that response can, of course, be now omitted:
c ? CASE data; ... SEQ ... response (e.g. animation) c ? CASE complete -- let sender know all is done something.else; ... SEQ ... response (e.g. animation) c ? CASE complete -- let sender know all is done
Hope that helps! [Note: you only need to engage in such trickery if you have more than one process doing animation. If you have just the one and it does some animation in response to a received message, then that animation will complete before it processes the next message and does the next animation. This is all that's needed to do the minimum form of animation required for full marks - as shown by the executable model answer (answers/a7). However, to get parallel animation - see some of the other example answers - you will naturally need parallel processes and tricks as outlined above.]
Keywords: q7
Referrers: Question 106 (2003)
When will we have all of the information presented in lectures to be able to do q7? Thanks.
You have had all the technical knowledge needed for q7 since around week 10 last term. Precise details of what is required by way of animation to get full marks, together with fairly detailed suggestions as to how that may be implemented, is being presented and discussed in the seminar groups (weeks 13-15). Attendance at seminar groups is, of course, compulsory ...
Keywords: q7
2002 |
Could you please explain a little more how you would go about implementing the random time delay? I have read through the previous questions on it but I'm still a little lost. Is the time delay between philosophers doing different actions or in the display process?
It's in the philosopher processes - not the display.
The question says:
Thinking and eating by the philosophers should be modelled by random (but finite!) delays
In the "philosopher" process there are two folds:
<!--{{{ think--> SKIP <!--}}}-->
and:
<!--{{{ eat--> SKIP <!--}}}-->
You should replace the SKIPs by random delays.
Keywords: q7 , random , timers
Do we need to design the philosopher system to end "gracefully" like in previous assignments?
No.
Keywords: q7 , graceful-termination
Hi, it has been strongly suggested by our seminar leader that we use protocols for the state report channels to the display process. The reports disclose the any change is state from the philosphers, forks and the security guard. Obviously you need to fair multiplex all the philosphers together and all the forks??? However, how can you multiplex three different protocols together??? You can't can you? If not, then I guess we write some display process with three input channels one for each protocol, and work that way.
Fair mulitplex the philospher reports down to one channel. Same for the forks. That leaves 3 channels, with different protocols, coming to the display process - say a, b and c. To fair-alt those:
WHILE TRUE SEQ PRI ALT a ? ... ... react to the a mess b ? ... ... react to the b mess c ? ... ... react to the c mess PRI ALT b ? ... ... react to the b mess c ? ... ... react to the c mess a ? ... ... react to the a mess PRI ALT c ? ... ... react to the c mess a ? ... ... react to the a mess b ? ... ... react to the b mess
Bit repetitive writing the reaction codes thrice ... so make a PROC for each reaction ... just invoke that PROC thrice.
However, simpler-but-more-dangerous is just to have one protocol that all philosophers, forks and the security guard to use - that's 11 channels, all with the same super-protocol, coming out of the college. Plug those into the display and simply fair-alt that!
It's unsafe to use one protocol for all reports - since a fork, for example, could send a philosopher report by mistake! This is the sort of thing that can happen somewhere down the life-cycle of a product during maintenance. However, for this exercise, you will not lose marks for doing so ... so long as, of course, you don't make any mistakes that this approach allows!
I would like to use colour in my solution to Q7. The PROC fg.col in shared_screen.occ looks useful ... however, I am unable to use the shared_screen.occ code. I have the following lines at the top of my source code:
#INCLUDE "shared_screen.occ" #USE "shared_screen.inc"
Many errors are generated relating to this, such as:
Error-oc-shared_screen.occ(337)- pc subscripted too many times Serious-oc- Too many errors, maximum is 100.
What am I doing wrong?
Sorry - we hadn't told you how to use this package. It's not part of the basic "course" library! Before explaining how to access, let me stress that noone needs to find out about and use this stuff - it's only there to provide a rich set of drawing mechanisms for those who want to do some really fancy animation. Even then, you don't have to use it ... but you will end up inventing something similar.
Something anyone could have done is simply copy those two files:
libsrc/shared_screen.inc libsrc/shared_screen.occ
into the start of your own q7.occ file. Then, your own code could simply use anything defined in them. Note that the order is important - the shared_screen.inc must go before the shared_screen.occ file (which uses protocols and data types defined in shared_screen.inc).
Better would be to copy those files into the same directory as your q7.occ file and start your file with:
#INCLUDE "shared_screen.inc" #INCLUDE "shared_screen.occ"
Again, note the ordering! These directives simply tell the compiler to pull in those files at the point of those #INCLUDEs.
Best is not to copy those files at all and use the library. All you haven't been told is the name of the library - which is "ss". Currently, only PROCs and FUNCTIONS are saveable in kroc libraries, which means that constants, data types, prototcols (etc.) have to be pulled in as #INCLUDEs. Anyway, to do this, your file needs to start with:
#INCLUDE "ss.inc" #USE "ss.lib"
These can be followed, or preceeded, by other library accesses - e.g.
#INCLUDE "consts.inc" -- standard course library constants #USE "course.lib" -- standard course library
We're not quite done. When compiling, the occam compiler (invoked by the kroc shell script) will find the relevant files. [Note: those working with the Linux kroc need to ensure their OCSEARCH environment variable is set up correctly.] When doing final linking (also invoked by the kroc shell script), we have to tell the linker where to find the library code. In fact, the kroc script uses the standard gcc (Gnu C Compiler) to do this linking - i.e. something different from OCSEARCH happens. Anyway, the compile command needed is:
kroc q7.occ -lss
Linux users have always had to do something like this to link in the course library (which the kroc script on Solaris machines has been set up to do automatically). So, on Linux, if you want both libraries linked in to your executable, the command is:
kroc q7.occ -lss -lcourse
Enjoy!
Keywords: q7 , colour , animation
How many lines of code, rougly, is your solution to q7-dining philosophers?
The source code for the model answer executable, answers/a7, has 382 lines. These include all the lines in your starter file, exercises/q7.occ, which has 106 lines. So, it can be done with just 276 new lines ...
Keywords: q7
The random function says that it needs an integer at least 1. At the moment my seed is:
id + modified.time
I know that my id can equal zero. You said that time could be negative, so I assume that it can equal zero as well. At the moment my modified time is:
t /\ #7FFFFFFC
I have a vague understanding ofhow this works, but it looks to me that my modified.time can equal zero aswell, making it possible to break the random function. Do I need to change the bitvalue that I /\ with t?
Your id and the timer value could both be zero - the latter could be negative as well! So, your concerns about the ideas above are valid. Check out the answer to Question 69 (2000), especially David Wood's suggestion at the end.
On a general point, you are strongly advised to browse through the anonymous questions and answers from previous years. On animating the Dining Philosophers, there was much discussion and plenty of good advice. For example, look at Question 68 (2000) ... and lots of others.
2001 |
I am having trouble modifing the fork process in the dining philosopher's question. What I want to do is basically have a fair ALTing process going over the two input lines, left and right.
I have already implemented a fair ALTing process in my animate process, but the difference there was that all the input lines were called the same name -- i.e. state[0], state[1] etc., so implementing it there was easy from the definition given in the notes. The problem with the fork process is that the input lines have two distinct names, and so the definition of fair ALTing does not translate as obviously.
What I have tried to do is give them the same name, so in the fork header I have put '[]CHAN OF BOOL in', but I could not get it to work this way after many attempts. My question is: is this the correct way to be going about altering fork?
There are two ways. One is to create a channel array abbreviation for the two scaler channels - i.e.
[2]CHAN OF BOOL c IS [left, right]:
Normal anti-aliasing rules now apply - you can't use the names left and right anymore (because you have the new names, c[0] and c[1], for them). But you now have an array of channels and the usual fair ALTing coding (see slide 10-23) can now be applied.
Second way: don't be clever and just write:
WHILE TRUE SEQ PRI ALT -- first give left priority left ? .. .. right ? .. .. PRI ALT -- then give right priority right ? .. .. left ? .. ..
Do we really need the q7 process, because I place my display process in the secure.college process?
It's the q7 process that has the screen channel, along with the other compulsory channels in its parameter list that are needed for the starting process of the (kroc) occam executable. If you give that parameter signature to your secure.college and make that process the last one in your source code, then that will work fine. But that has bundled up your display process inside your college.
I would prefer the college logic to be independent of its display. That way, we can change the display logic (e.g. to drive some graphics window) without having to touch the college.
Keywords: q7
For the dining philosophers, I have created my own display process as required. However, I am not sure how to link all the processes together in a network under the q7 process. Any help??
This is a bit too general a question to answer -- need your source code to point to what you're doing wrong.
All I can offer is this. The q7 process has the screen channel -- plug that into your display along with the (newly declared) report channels, whose other ends are attached to your modified secure.college. Hope that helps.
Keywords: q7
This is more of an anonymous observation really. I'm sitting here looking at q7.occ and, to be honest, I haven't got the first clue on how to start this assesment. I've been to the lectures and the classes, but me along with quite a few others who I have been talking to over the weekend have got no idea. I appreciate that yes some people have managed to do it, but the others are struggling.
Plus also after talking with my friends we all realised that nobody says anything in the classes apart form a select few which makes for an uncomfortable atmosphere when the postgrad is standing in front of a bunch of students who don't say anything for an hour. Perhaps it would have been better to concentrate more on the dining philosophers assessment in classes? I haven't got many notes on it at all.
The assessment was set last November, when you had enough technical information to solve it. The occam variant PROTOCOL makes the solution neater and that was introduced by the end of last term. The first two seminar classes this term were devoted to explaining the assessment and talking through the recomended way to solve it. If you 'haven't got many notes on it at all', that is not our fault. That assistance was provided six weeks ago and the assessment could have been completely finished at that time. Last weekend is a bit late to start on this work and complain that you do not know what to do.
Fully participating in seminars is crucial to getting the best out of them. We try to get everyone involved to our best ability and sometimes do not succeed. Sometimes this is our fault. However, if a student has done no preparation for the seminar (e.g. has not worked on the exercises being discussed in between seminars), then that student will find it difficult to contribute to the seminar and will feel uncomfortable.
Keywords: q7
On slide 6-70 of the occam notes you say:
Modify the fork process so that it guarantees service on each input - even if the other one is perpetually busy. No philospher must starve because of greedy colleagues!
My question is what service should it guarantee on each input? What do you mean by service?
From a low-level point of view, service in occam always means accepting a channel input. High-level viewpoints depend on the high-level semantics of the process being considered.
In this case, the service performed by a fork is being-picked-up. What needs to be guaranteed is that, if philosopher 3 is sitting next to a continuously ravenous philosopher 2, philosopher 2 doesn't always get the fork. With the given code, there is no such guarantee. Phil 2 could be eating when phil 3 arrives at the table and reaches for the fork it shares with phil 2 and blocks. Eventually, phil2 finishes eating and puts down that fork ... only to become immediately hungry (zero thinking time!) and race back to the table and reach for the fork again. If that happens before the fork process has looped back to the start of its loop, the fork will see both phils trying to pick it up. With a plain ALT, it might let phil 2 pick it up. This could continue for ever!
To eliminate, the fork must fair ALT over those input channels it is servicing.
Keywords: q7
The function:
random (maxvalue, seed)
returns an (INT, INT) value. How can I assign the first INT in the pair to one variable, and the second to another? I have tried:
INT number, seed: SEQ ... (number, seed) := random (maxvalue, seed)
But I imagined it would cause an error ... and it did.
If you look at the syntax of the function declaration:
INT, INT FUNCTION random (VAL INT upto, seed)
you will see that it returns an INT, INT - i.e. no brackets! The correct syntax, therefore, is:
number, seed := random (maxvalue, seed)
For further information on this function, see Question 77 (2000). For general questions about animating the Dining Philosphers' problem, see last year's Question 66 (2000) onwards.
2000 |
I am doing my own implementation of the q7 (i.e not using any of the methods part written). I won't be docked marks because of this (presuming that my implementation is correct)?
No - that's perfectly in order.
Keywords: q7
When drawing the network diagram, do we have to show it as all the philosophers sitting round the table, with the all forks and all the channels - i.e. from the college perspective? Or do we have to draw it as the code we have written - i.e. 1 philosopher, 1 fork, security guard and display taking in channels from those 3 objects?
For each process implemented as a network of processes, you must draw that network showing all connections - i.e. all internal processes, how they are wired together and/or wired to the outside world. If your network topology for the college reflects the college geopgraphy (e.g. philosophers and forks arranged round a table), that's a nice bonus but not essential.
There will be at least two layers of network to draw - the (secure) college network and the q7 network, consisting of the college and display processes. Each network should be drawn separately - do not try to combine two layers of network on one diagram. Ideally, you should also draw individual process icons for each process (e.g. philosopher, fork, security guard, secure college and display) that shows the shape you are using for that process and its external wires (labelled with the relevant formal parameter names used in your code). All wires should be arrowed to show the direction of data flow and labelled with the channel names used in your program. All processes should be labelled with the process names used in your program (plus any non-channel formal parameters).
The following code:
PROC displaying ([]CHAN OF DISPLAY d, ...) WHILE TRUE ALT i = 0 FOR 6 d[i] ? CASE thinking out.string ("Philosopher is thinking", 25, out) hungry out.string ("Philosopher is hungry", 25, out) ... etc.
keeps giving me the error:
Not enough items in i/o list.
Why does it do that?
Because there are not enough items in your i/o list. Your DISPLAY protocol must contain variants that contain something other than just a tag name - maybe:
PROTOCOL DISPLAY CASE thinking; INT hungry; INT ... etc. :
In which case, your CASE input must provide the necessary variables for the relevant variant lines. For example:
d[i] ? CASE INT id: thinking; id ... make the report INT id: hungry; id ... make the report ... etc.
In a replicated ALT over an array of channels, how do you include a SKIP process to deal with when none of the channels is sending data? For example:
forks[f] ? CASE upfork SEQ ... display an fork in the up position downfork SEQ ... display an fork in the down position -- needs a SKIP if none of the forks positions have changed...
I think my program is deadlocking because it keeps waiting for forks to report when none of them have changed position.
You should not need such a SKIP guard. The best thing for your display process to do when nothing is being reporting is nothing, which is what will happen if you just listen to all the report channels with a replicated ALT. If your program is deadlocking, it is for another reason - such as your college processes (philosophers, forks and security guard) outputting to parameter channels that are not correctly wired to the input channels of your display process.
If you really need to poll all those report channels (and you don't - honest), you could write something like this:
WHILE TRUE PRI ALT ALT p = 0 FOR n.phils phils[p] ? CASE ... deal with philosopher reports ALT f = 0 FOR n.forks forks[f] ? CASE ... deal with fork reports INT n.sat.down: security ? n.sat.down ... deal with this report from the security guard TRUE & SKIP ... no reports available - do something else (like SKIP :-()
Keywords: q7 , alternation
I have expanded my dining philosophers animation network like this:
[5]CHAN OF PHILOSOPHER a: [5]CHAN OF FORK b: PAR secure.college (a, b) display (a, b, screen)
but the compiler is telling me:
Aliasing error, 'screen' is a free variable.
Any thoughts?
Yes. It must be the case that your display process does not name its third parameter screen, but nevertheless outputs to a channel called screen. Something like:
PROC display ([5]CHAN OF PHILOSOPHER from.phil, [5]CHAN OF FORK b, CHAN OF BYTE out) ... and in here outputs to the 'screen' channel instead of 'out' :
Now, this PROC compiles because screen is a globally visibly channel carrying the right protocol (BYTE). It must also be the case that that channel exists because you have declared display inside the body of your main q7 process, where screen is declared as a parameter. [If it had been declared on its own before your main q7 process, it would not have compiled - complaining instead about the unknown channel called screen, which would have been nice.]
Assuming the above, when the compiler came to the attempted instance:
display (a, b, screen)
it would see an attempt to associate the real channel screen with the formal parameter out. But the compiler knows that your display outputs to this screen directly - so that the process would have two names for the same channel: out and screen. occam does not allow such aliases to happen - hence the error message.
Keywords: q7 , free-variable
I am attempting to plex together multiple channels into one. Each channel uses a tagged protocol, STATUS, that I have defined. I have found a working solution:
PROC plex ([]CHAN OF STATUS in, CHAN OF STATUS out) WHILE TRUE ALT i = 0 FOR SIZE in in[i] ? CASE INT v: sitting; v out ! sitting; v thinking; out ! thinking ... same for all the other variants
However, I am not happy with this, since I am just switching based on what's in the protocol, and just outputting it in every case. What I want to be able to do is something like:
PROC plex ([]CHAN OF STATUS in, CHAN OF STATUS out) WHILE TRUE ALT i = 0 FOR SIZE in STATUS s: in[i] ? s out ! s :
All my attempts at this have failed, usually resulting in:
Error-oc-myq7.occ(117)- Name STATUS is not a TYPE.
Can you point me at the right syntax for this? Thanks.
Your question is a very good one. I'm afraid that occam2.1 has no syntax to express your perfectly reasonable request! This problem occurs when writing many standard components for handling variant (CASE) protocols - buffers, message routers as well as multiplexors and de-mutiplexors. The proposed, but so far unimplemented, occam3 language enabled the declaration of UNION data-types, that would mostly solve this problem. The draft occam3 language specification can be found on:
http://wotug.ukc.ac.uk/parallel/occam/documentation/
for those interested (1.4 MBytes postscript). Summer or group project anyone?
For the Dining Philosopers Animation, can we get full or nearly full marks with a simple text output describing each state change?
Around 20% of the marks are for a decent animation - where decent means at least to the standard of that given by:
/usr/local/work/co516/answers/a7 (on raptor)
Keywords: q7
Thinking and eating by the philosphers should be modelled by random (but finite!) delays.
Assuming we have obtained a random number, what's the best way to implement the delay ... i.e. pause execution for a random time? Is there a wait(time) function or such like?
See slide 4-40 and sections 3.4/3.5 of the "OCCAM2 CHECKLIST" paper. Spelling it out:
TIMER tim: INT t: SEQ tim ? t tim ? AFTER t PLUS waiting.time
Referrers: Question 59 (2004)
Ok, I am confused. What's the deal with all the seed things? Also what's the deal with the animation? Where can I find some examples of some coding for screen display?
[I'm combining this question with the following one (PHW)]
Please could you tell me how to generate a random number in occam? I've forgotten and can't find it in the notes. Thanks.
All these things have been explained in your seminar groups. I'll just point you at Question 76 (2000) for information about implementing the screen display and:
/usr/local/work/co516/libsrc/random.occ
for information about the random number generating FUNCTION, for which you need to set up and maintain a seed variable.
Referrers: Question 21 (2001)
I think we've already been told, but where are we meant to find the documentation on all the methods we need for the display process, in order to move the cursor around the screen etc?
Yes - you have been told! See, on raptor, files:
/usr/local/work/co516/libsrc/utils.doc
which is a text file (not an MS-Word document!). The procedures you want are documented at the end of the file, following the comment (fold) line:
... screen stuff (VT220 protocol)
Alternatively, you could browse the full source code:
/usr/local/work/co516/libsrc/utils.occ
There's also a simple demo of the cursor.x.y procedure in:
/usr/local/work/co516/examples/test_utils.occ
Referrers: Question 77 (2000) , Question 78 (2000)
I get a compiler error when I adpated the philosopher's process to accommodate the sending of data when the philosopher does an action. It says that within a PAR scope, I cannot output to the same report channel (to the display process) in parallel branches of the PAR. Which is fair enough. But how can I get past this?
One way is to put in two report channels from the philosopher and, then, either a separate multiplexor process that merges those two down to one or just take both report channels to the display process (which will get a bigger array of input channels to service).
Better, though, is to get your fork processes to have report channels to the display. Then, don't bother reporting fork acquisitions from the philosopher (which is, I guess is what you were trying to do in parallel - because the fork acquisitions occur in parallel). The forks can report where they are directly on their own report channels.
Keywords: q7 , parallel-output
When I recieve the appropiate case statement, I want to output a string. But what command does that?
It sounds like you don't know about:
out.string ("any old string", fieldwidth, screen.channel)
from the course library? Look at any of the examples in your examples directory on raptor - or the answers directory at:
/usr/local/work/co516/answers/
Keywords: q7
When tapping the channels for the philosophers and forks, Fred recommended giving each one an id. If it were Java, I would simply assign each object an individual id when their constructor was called. Can I do something similar in occam?
Yes. To set up a number, say n, of thing processes and give each instance its own id is easy. First, the PROC header for a thing must take an id parameter - for example:
PROC thing (VAL INT id, ...) ... body of thing :
Then, to set up the instances:
PAR i = 0 FOR n thing (i, ...)
That's all.
Keywords: q7
Once the first draft of my q7 program is compiled and run, it produces this error:
Philosopher 1 is thinking KROC: Range error / STOP executed (signal 4) KROC: Fatal error code 1, core dumped Abort (core dumped)
I don't know what this means, so I would be grateful if you could point me in the right direction ...
It means your program crashed. There are several possible causes of this run-time error:
I'm afraid the message you report is all you get from the KRoC/Solaris system. If you compile this with KRoC/Linux using the command:
kroc -d myfile.occ -lcourse
it will tell you the file name and line number of the offending line. [Note: the "-lcourse" flag above is just to link in the course library - something which is automatic with the Solaris version of the kroc command. The active ingredient of the above command is the "-d" flag.]
Keywords: q7 , range-error , stop
Referrers: Question 43 (2004) , Question 30 (2003) , Question 86 (2003) , Question 11 (2002)
In a post, Fred says that the maximum negative 32 bit int is -2147483648, so I have coded appropriately ...
-- ensure seed is positive & legal IF seed = (-2147483648) <---------ERROR!!! seed := 2147483647 seed < 0 seed := -seed seed = 0 seed := 1 TRUE SKIP
But I get an error on the line arrowed above which says:
Overflow when evaluating constant expresssion
Help!! Have I done something wrong or is the info on cs2 wrong?
The compiler treats -2147483648 as an expression, so it gets an error when trying to evaluate 2147483648 (which is larger than the largest INT). If it got past that, it would get another error trying to negate it.
occam has a special way of naming the largest and smallest of any of its number types. For example,
MOSTNEG INT MOSTPOS INT
give you, respectively, the most negative and positive integers. Other ways we can write MOSTNEG INT are:
#80000000 1 << 31
But ... my colleague, David Wood, suggests you might like to consider:
TIMER tim: INT seed: SEQ tim ? seed seed := (seed >> 2) + 1
Keywords: inverting , int , random , q7
Referrers: Question 29 (2002)
I've forgotten how to implement the lookup table for the screen positions for the dining philosophers. Any help would be appreciated.
Your animation code should not be highly repetitive with the same logic repeated with different magic numbers - e.g. for displaying new positions of the different philosophers. Having a table of anchor coordinates for each philosopher may help. A table is simply an array of VALues (i.e. constants). For example:
VAL [][2]BYTE phil.anchor IS [[40, 5], [70, 10], [55, 15], [35, 15], [10, 10]]:
where the [][2]BYTE could have just been [][]BYTE, but being specific about the dimension of the coordinates (rather than the number of them) seems right. We could have been even more explicit and written [5][2]BYTE, but that seems too much. Any way, the compiler will fill in the sizes of any blanks in what we write after the IS.
With the above, it's nice to give names to the two indices of the [2]BYTE array coordinates - e.g.
VAL INT X IS 0: VAL INT Y IS 1:
Then, if we want to move the screen cursor to the anchor point for philosopher i - and we know that that i is a valid philosopher number (i.e. 0 through 4):
cursor.x.y (phil.anchor[i][X], phil.anchor[i][Y], screen)
or, more efficiently:
VAL [2]BYTE phil.i IS phil.anchor[i]: cursor.x.y (phil.i[X], phil.i[Y], screen)
since it only checks the array index (for out-of-bounds error) and calculates the address of phil.anchor[i] once.
Keywords: q7 , cursor , table , animation
Referrers: Question 84 (2003) , Question 29 (2002)
How do I create a replicated protocol CASE statement for the dining philosophers. I have written:
PROC display ([]CHAN OF MYPROTOCOL reportin, CHAN OF BYTE out) WHILE TRUE ALT i = 0 FOR 10 INT n: reportin[i]? CASE thinking out.string ("Philosopher Sat Down", 50, out) hungry out.string ("Philosopher is hungry", 50, out) etc... :
But I keep getting incorrect indentation errors. Do I need any SEQ or PARs here or is the problem elsewhere?
There is nothing illegal with the above code fragment, assuming that your etc... introduces another variant of MYPROTOCOL. Your local (but unused) declaration of INT n, for example, is perfectly legal just above the ALT guard. It could also be located just above (and aligned with) any of the CASE variants if that were useful.
Indentation errors are trivial to correct. Mail me your code and tell me the line number of any indentation errors reported by the compiler and I'll tell you what's wrong. If it's a general point, I'll make up the relevant (anonymous) question and post an answer to these pages.
Keywords: q7 , incorrect-indentation
For question 7, I am trying to draw a boarder for the dining philosophers room. I can do it with lots of cursor.x.y and out.string procedures but this seems time consuming. I thought of doing it in a replicated PAR or replicated SEQ and I wrote this code:
#INCLUDE "consts.inc" #USE "course.lib" PROC a (CHAN OF BYTE out) PAR i = 1 FOR 26 SEQ cursor.x.y (4, i, out) out.string ("#", 0, out) : PROC test (CHAN OF BYTE keyboard, screen, error) PAR a (screen) ... other things :
But when I compile it, it says there is a type mismatch in parameter 2 of cursor.x.y. This is the y coordinate that I am changing so that the character gets printed on the line below the first one to create a column like this:
# # # # # #
Why does the compiler not like the second parameter of the cursor.x.y proceedure? Doesen't it just need to be a number?
The second parameter of cursor.x.y needs to be a BYTE. Replicator control variables (e.g. your i) are INTs. You need to cast it into a BYTE:
cursor.x.y (4, BYTE i, out)
See the answer to Question 7 (2000) for information on casting between occam types.
Your PAR replicator also won't work because it implies parallel outputs to the out channel - illegal! So it has to be a SEQ replicator. In any case, unless the occam kernel supports, and is running on a multiprocessor machine, the SEQ replicator for code like this will be faster than a PAR (which will have to startup and shutdown 25 software processes).
Your code would also be slightly snappier with:
PROC a (CHAN OF BYTE out) SEQ cursor.x.y (4, 1, out) SEQ i = 1 FOR 26 -- the "2" could be anything though SEQ out ! '#' -- don't need out.string for a single char cursor.down (1, out) cursor.left (1, out) out ! FLUSH
Keywords: q7 , type-mismatch , type-cast , cast , cursor
Referrers: Question 21 (2001) , Question 74 (2000)
Last modified Mon May 15 17:39:47 2006
|