XML

kent logo

CO538 Anonymous Questions and Answers Keyword Index

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

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

Keyword reference for incorrect-indentation

2006

Question 4 (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.

Answer 4:

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

Question 74 (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)
    :

Answer 74:

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


Question 46 (2004):

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

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

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

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

Answer 46:

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

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

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

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

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

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

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

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

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

    WHILE TRUE
      out ! 42

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

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

Keywords: q4 , incorrect-indentation

2003

Question 28 (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

Answer 28:

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


Question 16 (2003):

    [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)

Answer 16:

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

Question 35 (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

Answer 35:

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

Question 67 (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?

Answer 67:

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


Question 62 (2000):

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!

Answer 62:

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


Question 6 (2000):

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

Answer 6:

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

Valid CSS!

Valid XHTML 1.0!

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