CO538 Anonymous Questions and Answers Keyword Index |
This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.
To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.
Keyword reference for protocol
2011 |
Submission reference: IN2061
Hello there, I am wondering; is it possible to use an id-like process to link two channels of the same protocol without having to read the data from the protocol by yourself and re-send it along?
Connecting two (same-protocol) channels with an id-like process yields a buffered channel with capacity 1. The CSP library for Java (JCSP) provides for the construction of occam-like (i.e. unbuffered) channels by default, but also for buffered channels of any capacity (including infinite) and varying kinds of buffering (blocking, like Choices slide 105, overflowing, slide 107, or overwriting, slide 108). At some time, it would probably be good to introduce this into occam-pi – it would be more convenient, safer and more efficient for the compiler to construct such buffering than the programmer.
A second point raised by your question is that of generics. It would be nice to be able to parametrise the types of messages carried by channels plugged in to processes that don't care. For example:
PROC id <TYPE P> (CHAN P in?, out!) WHILE TRUE P m: SEQ in ? m out ! m :
Instances of such a generic process would have the obvious form – e.g.
id <REAL64> (a?, b!)
which would instance an id process for channels carrying double-precision floating-point numbers.
However, defining the above idea is complicated by the current concept of message PROTOCOLs in occam-pi (see the Protocol slides, not yet covered in the course). It should probably wait for a more powerful type system for occam-pi (that is planned).
You are also asking, I think, for a syntactic sugaring that saves "having to read the data from the protocol by yourself and re-send it along"? Perhaps, something like:
PROC id <TYPE P> (CHAN P in?, out!) WHILE TRUE out ! (in ?) :
or maybe:
PROC id <TYPE P> (CHAN P in?, out!) WHILE TRUE in? > out! :
It's a thought! See also Question 56 (2010).
However, for all forms of engineering (such as language design), always consider Occam's Razor: "Numquam ponenda est pluralitas sine necessitate", which roughly translates to "Don't invent things you don't need" or "keep it as simple as possible". For programming languages, this means only adding mechanisms that are really needed ... where real need covers new ideas (that let us do useful things we couldn't do before) and more powerful forms of expression (that let us do common things more easily than we did before). We have to work hard to honour this principle. Software engineering constructs virtual artifacts – unconstrained by limits imposed by the physical world. As such, it's only too easy to build something complex that doesn't quite do the job ... than something simple that does.
Keywords: generics , protocol , occam , razor
2010 |
Submission reference: IN1953
Is there any chance of a FORWARDing keyword to be made e.g.
out ? FORWARD in
which, if in and out were channels carrying INTs, would be the same as:
INT i: SEQ in ? i out ! i
This would be very useful in the case of variant protocols e.g.
out.variant ! FORWARD in.variant
This would replace:
INT i, j, k: in.variant ? CASE x.case; i out.variant ! x.case; i y.case; i, j out.variant ! y.case; i; j z.case; j, k out.variant ! z.case; j; k
which would be much smpler to write. I think this would be useful if you were writing an id process for variant protocols, or in channel bundles wanting to send a request and then forwarding on the response (e.g. having a main control process in mars robots and then forwarding the response from a process (turn etc) to the operator response channel).
Either that or being able to store a variant protocol as a variable e.g.
VARIANT OPERATOR.RESPONSE variant.variable: -- where OPERATOR.RESPONSE is a protocol that the VARIANT is a type of INT result: in ? CASE turn variant.variable := turn.complete ... do turn move variant.variable := move.complete ... do turn ... later out ! variant.variable; result
This would reduce the amount of coding where the output on a variant protocol is dependent on the input on a variant protocol. A permutation of that would be to save the whole output in the protocol e.g.
variant.variable := turn.complete, result
Or something like that.
You are right that routine forwarding/buffering of messages carried by variant protocol channels is tedious (though trivial) and that something should be done about it.
One proposal is for union types, which give you something like the variant.variable in your question. This, together with an idea for automatic dynamic memory allocation (which saves memory bloat), look promising for the future.
The current list of enhancement proposals for occam-pi can be browsed here.
Keywords: mars , protocol , union
Referrers: Question 30 (2011)
2007 |
Submission reference: IN1452
On the 2006 exam paper, at question 1(d) the closest answer is that it is a
variant protocol but the CASE
is missing.
Is it a typing error? Or am i missing anything here?
You are quite right. There was a typing error in the question
and the CASE
line was missing from the PROTOCOL
declaration. We hope not to repeat that!
See Question 104 (2006) for information on question 1(e) from the same paper. Note: the year numbers for these anon Q&As corresponds to the start of the academic year – these year's questions are labelled (2007). Note also: the typing error in the 2006 question was not noticed by the question setter, checker, external examiner, nor any students taking the exam! Question 104 (2006) was answered almost a year after the exam and the typo (repeated in that answer) had still not been spotted. We apologise.
Keywords: protocol
2006 |
Submission reference: IN1177
Hi, I've been looking at last year's exam paper and came across the following question:
(e) Write a server loop that receives and processes one PACKET per loop from channel deliver. It must save payload data into suitably declared variables and process them in some way (leave blank lines in your code for this processing ... or use the ‘three-dots’ notation to indicate their position). The loop must terminate if poison is received.
Would the following be an acceptable answer to this?
PROC server (CHAN PACKET deliver?) INT x: [1024]REAL64 y: INITIAL BOOL running IS TRUE: WHILE running deliver ? CASE BYTE size payload; x; size::y ... deal with this variant poison running := false :
Thanks in advance.
The protocol was declared in the previous part of this question:
PROTOCOL PACKET payload; INT; BYTE::[]REAL64 poison :
You would have scored the full (3) marks for your answer above. However, since the largest size value is 255, your array y is unnecessarily large. Also, the variables used for receiving the message should probably be localised just to the reception area – and their declarations, like all declarations, should end with a colon. For example:
PROC server (CHAN PACKET deliver?) ... local state (declarations and initialisation) WHILE running deliver ? CASE INT x: BYTE size: [255]REAL64 y: payload; x; size::y ... deal with this variant poison running := false :
Referrers: Question 66 (2007) , Question 66 (2007)
Submission reference: IN1036
I was wondering how you would do a double variant protocol. I want to have a variant to express the types (philosopher, fork, security) as well as having a separate one to indicate the actions. Currently I have:
PROTOCOL FORKSTATUS CASE on.table left.pickup right.pickup : PROTOCOL MIXEDSTATUS CASE philosopher; INT; BYTE fork; INT; FORKSTATUS security; INT :
But when I say:
report ! fork; id; left.pickup
it complains about left.pickup not being defined. Also to how would I make this readable in the CASE statements, because I would somehow need to say something like:
report ? CASE INT id: BYTE status: philosopher; id; CASE
You can't do this, as you say, handling the input sensibly is hard. The normal approach would be to define some constants and use these. What we really want is an enumerated type, but until then, something like:
-- fork status values VAL INT ON.TABLE IS 0: VAL INT LEFT.PICKUP IS 1: VAL INT RIGHT.PICKUP IS 2: PROTOCOL STATUS CASE fork; INT; INT ... : ...
Keywords: coursework , protocol
Submission reference: IN996
Is there an easy way to pass Strings between processes? It seems that you
have to specify the length, such as [30]BYTE
, but this doesn't seem a
particularly amazing way to do it. Is there a way to say
[however-long-it-needs-to-be]BYTE
?
If this question is prompted for animating the dining philosophers,
relax – you don't have to pass strings around.
The college components (philosphers, forks and security guard) should
send coded messages to the animating process, which reacts by outputting
text strings to the screen.
The coded messages can be simple BYTE
s (or INT
s)
representing states like "I'm hungry", "I'm on the table"
or "I've counted in n philosophers".
However, if you have some other reason for passing around strings, use a counted array protocol as presented in the last lecture. For example:
PROTOCOL STRING IS BYTE::[]BYTE :
This protocol (actually message structure) allows you to pass
around arrays of BYTE
s (e.g. strings), preceded with
a (BYTE
) count of how long they are.
Since the largest byte value is 255, that is the longest string that
can be passed with this protocol.
This means that, so long as a receiving array for such a message has
255 elements, it will always be large enough – i.e. there will
be no run-time array bounds overflow.
2004 |
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.
Two questions in one here. First of all waht is a counted array?
Second currentley I am trying to create a cell for q6. All I am trying to do at the moment is read in the protocol then just output what ever comes in. So just like the ID in the lego.occ. Looking at Fred's Occam tutorial as the protocol is a tagged-protocol I need to do something like:
PROC cell(CHAN OF NAME.NUMBER in, out) in ? case string; INT::[]BYTE; INT ... do something poison ... do something else :
How do I read in the "string; INT::[]BYTE; INT" and the "poison" into a varible.
First question: section 7.4 of the "occam2 Checklist". Also, slides 5-45 through 5-47.
Second question: section 7.3 of the "occam2 Checklist". Also, slides 10-18 through 10-21 (in the Powerpoint Chapter 10, these are currently slides 20 through 25).
Please look through your notes before asking questions here!
How can I make a simple routine that forwards data of `NAME.NUMBER' ? I'm trying:
SEQ INT size: in ? size::n; m out ! size::n; m
And have also tried:
SEQ INT size: in ? string; size::n; m out ! string; size::n; m
But I'm getting errors such as "string is not delcared" and "Simple input is not allowed on a channel with a tagged protocol".
I have looked over the chapter 10 pages, but it doesn't cover protocol input for just one type of input. I assume you don't need to use another CASE here.
The first problem is the scope of `size'. See the answers to Question 19 (2004), Question 29 (2000) and Question 3 (2000).
As for the tagged-protocol input, why do you `assume you don't need to use another CASE here'? Slide 10-21 in the printed notes (chapter 10, slide 25, in the Powerpoint) and section 7.2 of the "occam2 Checklist" show you the syntax for this:
in ? CASE INT size: string; size::n; m out ! string; size::n; m
If you don't specify the `poison' case, that's fine ... but if a `poison' arrives, your process will STOP (i.e. crash!).
So, the above is what the code fragments in your question should have been, assuming that your variables `n' and `m' have also been defined somewhere (e.g. just before or after your `size' declaration). However, this code fragment only forwards `string' variants of the `NAME.NUMBER' protocol -- not all data variants as the wording in your question implies. In your solution to Q6, you will need to be handling all variants of `NAME.NUMBER'.
However, here's another bit of occam. When inputting a `CASE' protocol, if you are sure that only one variant message will arrive, there is a special syntax ... but you still have the `CASE' keyword and the relevant tag name. For your example, the shortcut code would have been:
INT size: SEQ in ? CASE string; size::n; m out ! string; size::n; m
though it's not actually any shorter (because of the need for the `SEQ')!
2003 |
When trying to implement a cell I get the error:
Error-oc-q6.occ(160)- Simple input is not allowed on a channel with a tagged protocol
on:
in?string; length::name; mark
See the answer to Question 53 (2003)
This is probably stupidly simple but my mind has gone blank. I've got an input of type NAME.NUMBER in q6 coming into my cell. I've taken the first INT and put it into a variable, now I want to take the next so many inputs (the number represented by the int) which is the name and put them into a list of char variable. How do I do it? Is there a line of code which will add one char to the end of a list?
I think there is some confusion here. Just for the record, occam has neither char or list types. What it does have are BYTEs and arrays.
You say that you read the first INT into a variable, but I can't see how that would compile -- there would be a protocol mismatch (or other) error. The purpose of a counted-array communication/protocol (as described by `INT::[]BYTE') is to communicate both a length and that number of array elements. Thus, you do not need to do this yourself; all you need do is ensure that the inputting side's array is large enough to hold anything the outputter might send (a run-time error occurs if this is not the case).
As a fairly basic (!) example, consider:
#USE "course.lib" PROC hello (CHAN OF BYTE kyb, scr, err) PROTOCOL TEST IS INT::[]BYTE: CHAN OF TEST c: PAR --{{{ output process VAL []BYTE str IS "Hello, counted-array world!*n": c ! (SIZE str)::str --}}} --{{{ input (and report) process [64]BYTE tmp.str: -- should be large enough INT tmp.len: SEQ c ? tmp.len::tmp.str out.string ("The message was: ", 0, scr) out.string ([tmp.str FOR tmp.len], 0, scr) --}}} :
See also the answer to Question 53 (2003).
In response to the answer to Question 53 (2003):
I have implemented the `CASE' as suggested and is all ok until it gets to the poison condition:
poison out ! name.length::name; score
I get the error:
I/O list does not begin with a tag
(in reference to the second line)
What does this mean? Thank you :-)
It means that your I/O list does not begin with a tag! -- An I/O list is the list of operands/expressions after an input `?' or output `!' operator. A tag is a label from a tagged (case) protocol definition.
In a similar way to case (tagged) input, you must specify the tag when using a tagged protocol. Change your second line so it reads:
out ! string; name.length::name; score
Keywords: protocol
Hi, a question about Q6:
I want to store the in channel. I have written the following line:
in ? string; temp.name.length::temp.name; temp.score
The compiler says it that string has not been defined. Yet in the `read.data' process, `string' is used and is not defined within the process. It doesn't work without the string either as it the compiler says:
Simple input is not allowed on a channel with a tagged protocol
Any help please?
The second of the two errors is more meaningful -- the `in' channel is of a tagged-protocol. The protocol in this case is `NAME.NUMBER', defined in q6.occ as:
PROTOCOL NAME.NUMBER CASE string; INT::[]BYTE; INT -- string; name; number poison -- sent, and only sent, as the last message :
The `string' referred to is the one in the above protocol definition.
There are two forms of tagged input in occam. The first allows for multiple CASEs; the second for a specific CASE only. For example, from the `display' PROC (in q6.occ):
in ? CASE --{{{ poison poison ok := FALSE --}}} --{{{ string; name; number --{{{ variables [max.name.length]BYTE name: INT name.length: INT mark: --}}} string; name.length::name; mark SEQ out.string ([name FOR name.length], max.name.length, out) out.int (mark, max.name.length, out) out.string ("*c*n", 0, out) --}}}
This shows the first form of tagged input -- where the `display' process handles both tags. The second form is just for a single tag, but not to dissimilar:
--{{{ variables [max.name.length]BYTE name: INT name.length, mark: --}}} SEQ in ? CASE string; name.length::name; mark ... do something
Also see the answers to Question 26 (2002) and Question 18 (2001).
Referrers: Question 57 (2003) , Question 58 (2003) , Question 59 (2003)
2002 |
This is part of my display proc which reads in the reports from philosophers and prints the relevant thing:
ALT i = 0 FOR 10 in[i] ? CASE thinking ... sitting ... ... etc.
and this is some of my protocol:
PROTOCOL report CASE thinking; INT sitting; INT ...etc...
I'm getting the error:
Error-oc-q7.occ(132)- Not enough items in i/o list
is this something to do with the type of ALT I am using or the protocol?
Your ALT is wrong - the protocol looks OK. As the error message says, you have not supplied enough items in your i/o lists. For instance, to match the pattern defined by your thinking tag, you must follow the tag with an INT variable:
ALT i = 0 FOR 10 INT index: in[i] ? CASE thinking; index ... sitting; index ... ... etc.
Keywords: protocol
I get this funky error and don't know what it means and how to solve it. Any tips would be appreciated.
Simple input is not allowed on a channel with a tagged protocol
It happened when I tried to store a NAME.NUMBER using:
in ? nameTemp; scoreTemp
NAME.NUMBER is a tagged - sometimes called a CASE or variant - protocol. See slide 10-21, section 7.3 of the Checklist paper or the display process in q6.occ, for how to input from a channel carrying such protocool. It should be somelthing like:
in ? CASE ... local delarations string; length::nameTemp; scoreTemp ... response to name-mark code poison ... response to poison code
Referrers: Question 53 (2003) , Question 27 (2002)
2001 |
I keep getting the error:
Simple input is not allowed on a channel with a tagged protocol ...
when I just try to connect the collate process between the read.data and display in Q6. What do you think I should do?
You should not try to do simple input on a channel with a tagged protocol! Tagged (or CASE) protocols are explained in Section 7 of The occam Checklist and in slides 10-18 through 10-22 (which have been talked though in lectures). See also the code in the display process given in your q6.occ started file.
Referrers: Question 53 (2003)
2000 |
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.
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. |