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 incorrect-indentation
2006 |
Submission reference: IN750
With IF statements, is it possible to have a number of statements executed in the body, for example:
IF value <> 0 out ! 42 out ! -99 TRUE SKIP
This however give a compile time error. Is there a way to allow multiple statements to be executed.
The structure of an IF is:
IF condition process ... ...
What you have in your code is two processes indented under the condition -- so you need to say how you want them executed. Sequentially would make sense here, e.g.:
IF value <> 0 SEQ out ! 42 out ! -99 TRUE SKIP
Missing SEQs are a common cause of the "incorrect indentation" error from the compiler.
Keywords: if , incorrect-indentation
2004 |
I have nearly finished the first CO516 occam assesment, but I am getting couple of error messages which have bewildered me.
I am getting two types of error. The first one is "incorrect indentation". I am getting this error in reference to the two lines indicated below, but as far as I can see they are ok.
I am also getting an error which states that "a" and "b" (which refer to PROCs) are "not declared" in "PROC q1".
My code follows, I would be very grateful for any pointers.
PROC q1 (CHAN OF BYTE keyboard, screen, error) CHAN OF INT aToB: PAR a (aToB) -- a not declared b (aToB, screen) : PROC a (CHAN OF INT aToB) INT num: SEQ num := 0 WHILE TRUE SEQ IF (num = 0) num := 1000 aToB ! num -- indentation error (num <> 0) num := num - 1 aToB ! num : PROC b (CHAN OF INT aToB, CHAN OF BYTE screen) INT num: WHILE TRUE SEQ aToB ? num out.int (aToB, 10, screen) out.string ("*n", 0, screen) :
In occam, the scope of PROC declarations follows that of other (e.g. variable) declarations. Specifically that a "name" (as declared by any declaration) may not be used until it has been defined. This applies to PROC and FUNCTION definitions, DATA TYPE and PROTOCOL declarations, and ordinary variable/channel/etc declarations. The "undefined" error you get in "PROC q1" is correct -- "a" and "b" are not defined yet. To correct this, the declarations of "PROC a (...)" and "PROC b (...)" should be moved above the declaration of "PROC q1 (...)". Thus they will be defined when referenced by q1.
Unlike C and Java, the "main" procedure in occam (where the program starts) is not defined by any special name (e.g. "main" in C and Java programs). Instead the last PROC definition in the file is used, and must have the formal parameters:
PROC q1 (CHAN OF BYTE keyboard, screen, error)
in that order. The name of the PROC and names of the parameters are largely unimportant. The Linux version of KRoC allows some of these parameters to be omitted, but does place restrictions on what the parameters may be called. The standard KRoC top-level process interface (as above) will work perfectly (except for warnings about unused parameters).
The indentation error in your code arises because that line of code is incorrectly indented. It is incorrectly indented because it is incorrectly structured. Whenever you have more than one process in occam (e.g. the assignment and output), you need to explicitly state whether they are to be run in sequence or in parallel. See the other questions relating to incorrect-indentation for examples of correct usage.
Although the code for "PROC a" is largely fine, it could be improved somewhat. Firstly, the brackets around the "IF" conditions are not necessary --- brackets in expressions are only required when there is ambiguity (since occam does not have any operator precedence -- see below). "IF" conditions are just boolean expressions. Secondly, the "num <> 0" condition would probably be better as just "TRUE". This is because "num <> 0" can't possibly be false, but also because "TRUE" is more meaningful as "otherwise do this" than some expression. Finally, you have duplicated code in both branches of the "IF" (the output). It would be better to "pull" these outside the IF" (and this sort of thing applies to any programming language). I'd also query the use of "aToB" as a sensible formal parameter name in "PROC a" here. Using "aToB" strongly implies that channel connects this "A" process to some "B" process. Although this turns out to be the case here, it might not be always, and that could be misleading. Better to pick a name that has relevance for "PROC a", but is completely unrelated to any actual usage in a process network (i.e. where the process is "placed"). For example:
PROC a (CHAN OF INT out) INT num: SEQ num := 0 WHILE TRUE SEQ IF num = 0 num := 1000 TRUE num := num - 1 out ! num :
Aside: the reason occam has no precedences set for its operators is because many of us cannot remember what they are in those languages that do have them. For instance, how does the following parse in Java:
if ( a > b + 1 << 4 && 3*a + 2 == x) {...}
? Can you remember the relative precedence between all those operators?? Just what does that expression mean?!
In occam, we don't have to remember anything -- but we do have to bracket our expressions explicitly to give the bindings we want. What-you-see-is-what-you-get:
IF (a > (b + (1<<4))) AND (((3*a) + 2) = x) ... do something
Keywords: incorrect-indentation , variable-scope , q1
Hello, I'm having trouble with the `monitor' procedure, my code is below:
PROC monitor (CHAN OF BYTE k, CHAN OF INT num, int, prs) PAR IF k = 'n' num ! k IF k = 'i' int ! k IF k = 'p' prs ! k :
I get indentation errors, and I'm not sure how to fix this, I was told by a colleague that we are supposed to implement an infinite loop in the `monitor' process -- why is this ? and what use could this be ?
Also, in the specification for the assignment, when we press `s' to suspend the output to the screen I'm assuming that this supposed to be implemented by the `monitor' method -- am I right?
Yes, this code has incorrect indentation. The "occam-2 checklist" in the course notes (and linked from the course web-page) provide a good deal of information on the layout of occam code. The correct layout for an occam `IF' (conditional process) is:
IF condition.0 process.0 condition.1 process.1 ...
The operation is: the various conditions are checked in the order written; the first one that evaluates to `TRUE' is selected and the process under it run. The rest of the conditions are then ignored. If you look at this occam tutorial, you'll see that the equivalent Java is something like:
if (condition.0) { process.0 } else if (condition.1) { process.1 } else if ... ...
In occam, however, one of the processes must be selected -- if the `IF' "falls-off" the end, it behaves as `STOP', generating a run-time error.
What you have in your code is some way to being a nested `IF'. The correct layout for that would be:
IF condition.0 process.0 IF condition.1 process.1 IF ... ...
But this is exactly equivalent to the version above, with all the conditions aligned.
The process needs to be an infinite loop otherwise it will run once then terminate, deadlocking anything else that tries to communicate with it (since it isn't there anymore). Parallelism does not imply repetition -- if you want the network to run forever, make each component run forever. And visa-versa -- if you want the network (or a sub-network) to run once (or n-times), make each component run once/n-times. Infinite loops are just `WHILE' loops that never terminate (because their condition never becomes `FALSE'). For example:
WHILE TRUE out ! 42
Will just output 42 on the channel `out' forever (or until it deadlocks).
The suspend signal needs to be handled in `monitor' in the sense that's where the key-presses arrive and are processed. Again, it's a design decision (up to you) as to whether the `monitor' process actually does the suspending of screen output, or whether it simply signals another component in the network, that suspends there. Suspend processes (e.g. for Q3) have been covered in the seminars, so it might make sense to re-use that.
Keywords: q4 , incorrect-indentation
2003 |
The compiler doesn't seem to like the following code:
[modified code] PROC layout.max.chans (...) WHILE TRUE [max.chans]INT n: ... SEQ process that reads values in PAR then writes them out PRI ALT int x: ... guard and process :
With an error of the form:
layout.max.chans(...) -- layout.max.chans is not declared
This isn't the real error. `layout.max.chans' isn't considered declared because the compiler couldn't parse/compile it. I see what you're trying to do, but this isn't necessarily the best place to do it.
If you really want to modify `layout.max.chans', the errors are incorrect indentation at the `PRI ALT' and `int x:' isn't a valid declaration. The first error is likely a missing `SEQ', or mis-placement of the `PRI ALT'. See Question 1 (2000) for more details on this. The second is easy -- `int' should be `INT', and the guard should be indented at the same level as the declaration, with the guarded process indented under that.
Keywords: undeclared , incorrect-indentation
[code snipped]
This is what I have for step 2 or the assignment. When I compile I get an indentation error on the ':' marked ***. I cannot see any reason why this is so or is there something wrong with the rest of my code?
Also, could you tell me if I'm heading along the right track here please (not being able to compile and check it means I'm unsure of it being correct)
In answer to your first point, you have something of the form:
PROC something (CHAN INT in?) PRI ALT in ? x ... local processing TRUE & SKIP : -- ***
The error you are seeing is in fact right. The structure of an occam ALT is:
ALT -- or PRI ALT guard process guard process ... ...
I.e., the second (`TRUE & SKIP') guard has no process. The compiler expects the indentation after the guard to be more than the guard, but in your code, it finds the PROC-finishing `:' at less indentation than the guard above it, hence the incorrect-indentation error. A more useful error would be `Missing process'. As an additional point, think hard about your `TRUE & SKIP' guard. Do you really need polling ? -- we think not..
In general though, please do not post code to this question page and simply ask what is wrong with it. Such questions cannot be answered in this public forum. If you are still lost, you could try mailing your seminar leader for some clues ...
Keywords: incorrect-indentation
2002 |
Can you see why it is moaning about the indentation of the SEQ?
ALT i = 0 FOR 10 BYTE n: WHILE TRUE SEQ in[i] ? CASE
Your don't show the context of your code. Assuming the first line is legally indented, the rest would be ... except, of course, that it's illegal syntax for other reasons! An ALT guard cannot be a WHILE-loop!! Did you mean to write something like:
ALT i = 0 FOR 11 BYTE n: in[i] ? n SEQ out ! n WHILE n <> FLUSH SEQ out ! n in[i] ? n
???
Keywords: incorrect-indentation
2000 |
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
Could you please help me with reading in the protocols for Q6. From looking at the notes on 10-21, I have worked out it is a tagged protocol. Here is the code that I have written:
SEQ ok := TRUE WHILE TRUE in ? CASE INT size: string; size::name; mark poison ok := FALSE
But I get errors with incorrect indentation. I'm presuming that this is not the problem. And there is something wrong with what I have written. If I comment out the string line, it compiles - but with it in, it does not. I'm not sure how to read in the string tag. Is what I have written completly wrong? Any pointers please!
Well, I should just refer you to the answers to Question 57 (2000) and Question 53 (2000) ...
However, each tagged variant in a CASE input requires a response - the action to be performed if you get that variant. That response is written in some code that has to be indented, as usual, just after the line inputting that variant. In the above, you have such a line for the poison variant, but not for the string one. So, the compiler correctly complains that the line following that string variant is incorrectly indented - it should be your response to the input. For example:
SEQ ok := TRUE WHILE TRUE in ? CASE INT size: string; size::name; mark SKIP -- >>>>>>>>> maybe a fuller response should be here ... poison ok := FALSE
Keywords: q6 , incorrect-indentation
I am trying to do question 1. Is there a way of signifying the end of an IF statement? Below, I have covered all cases and want to continue running after having been though one of the paths in the IF block. But the compiler keeps telling me that the line "a ! value" is incorrectly indented - I don't want it to be part of the IF block! To me the to 'backdent' the lines seems fairly logical as they are no longer part of the IF block.
-- if state is false do function f, else do function g IF state = FALSE SEQ IF value = 0 SEQ value := 1000 value > 0 SEQ value := 2*value state = TRUE SEQ value := value/3 -- output this, invert state & loop a ! value state := NOT state
Your problem is that you wish to execute the "a ! value" after executing the IF block. Probably you want to execute the state assignment afterwards as well. See question 1 above. To do this, you have to enclose these three statements inside a SEQ block:
SEQ -- if state is false do function f, else do function g IF state = FALSE SEQ IF value = 0 SEQ value := 1000 value > 0 SEQ value := 2*value state = TRUE SEQ value := value/3 -- output this, invert state & loop a ! value state := NOT state
By the way, your inner SEQs (all four of them) are redundant since they only enclose one statement - excuting one statement is sequence with nothing is just executing one statement! So, it simplifies to:
SEQ -- if state is false do function f, else do function g IF state = FALSE IF value = 0 value := 1000 value > 0 value := 2*value state = TRUE value := value/3 -- output this, invert state & loop a ! value state := NOT state
Your first comment has redundant information describing the way the IF statement works. The rest of its information is useful but should be localised to where it is relevant. Your choice of state name is not very meaningful and could be improved. Also, when testing booleans, extra bits like "= TRUE" are redundant. In the following, your state boolean is replaced by f.next, whose value is the inverse of your state:
SEQ IF f.next IF -- do function f value = 0 value := 1000 value > 0 value := 2*value TRUE value := value/3 -- do function g a ! value f.next := NOT f.next -- end of loop
Now that's a bit simpler and clearer ... ;-)
But ... it's still not the simplest way to program this PROC A ... :-(
Keywords: incorrect-indentation
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. |