kent logo

CO538 Anonymous Questions and Answers

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

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

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

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

Question 41:

Submission reference: IN1366

Sorry, I can't do both assessments in parallel as I will deadlock. I'm sure theres a formal proof of this too.

Answer 41:

Nope! occam-pi is all about designing parallel systems that do interesting things fast and don't deadlock (nor a bunch of other bad things). These two assignments are independent – so no problem to work on them in parallel, :).

See also Question 39 (2007).

Question 42:

Submission reference: IN1369

What is the operator for raise-to-the-power? For example, 2^32 – what does occam-pi have for ^?

Answer 42:

occam-pi does not have a buiit-in raise-to-the-power operator. There is a built-in function for floating-point raise-to-the-power::


which returns x^y ... but I don't think you want that!

[By the way, the built-in adjective above just means that we don't have to import any module to use it – in the same way that java.lang classes don't need to be imported.]

The actual number 2^32 is, of course, too high to be represented by 32-bit integers. I'm a bit worried by various large numbers being mentioned (see also the 360 degrees, for angular velocities, in Question 40 (2007)). There is no need for large numbers in this exercise.

If we really need a power operator for integers, we can define our own:

    --* This computes a restricted integer power (not very efficiently).
    --  The power size must be positive.
    --  If the numbers are too large, there will be arithmetic overflow.
    -- @param x The number to be raised
    -- @param y The raising power (must be >= 0)
    -- @return [@ref x]^[@ref y]
      INT result:
          result := 1
	  SEQ i = 0 FOR y
            result := result*x
        RESULT result

To use this function, just use the specified symbol as an infix operator – for example:

    answer := n^i

This demonstrates two further mechanisms in occam-pi (that are not part of this course module): in-lining and user-defined operators.

The in-lining doesn't change any semantics – it just removes the function call overhead (inserting code for the body of the function wherever the call is made).

We can build new operators as single or double symbols, using any exisiting operator symbol (or ^, @, &, %, ...). As is normal, operator symbols can be overloaded – but each operator should be defined for a unique operand-type-result-type signature (otherwise, usual block-structure scope rules hide the previously defined operator for that signature). Operators are either infix binary or prefix unary (respectively two-parameter or one-parameter operator functions). If we put such things in some appropriate occam-pi module, the language acquires new operators. To this extent, occam-pi is user-extensible.

But this is an aside ... I still don't think you need a power operator. What you might need (and which the code already uses in compute.speed) is left-shift, <<, and right-shift, >>. So long as it doesn't overflow:

    n << i

shifts the bit pattern in n left by i bits. If n were positive, this multiplies it by 2^i (so long as there is no numeric overflow). Similarly:

    n >> i

shifts the bit pattern in n right by i bits. If n were positive, this divides it by 2^i (rounding towards zero). Maybe this is what you are after?

Keywords: cylons , operators , power

Referrers: Question 43 (2007)

Question 43:

Submission reference: IN1372

Hi, I'm changing the compute.speed function, but I had some trouble understanding the first one. Can you explain the code below because I can't find any explanations for the operators?

    IF i = 0 FOR 7
      range <= (robot.radius << i)
        speed := i


Answer 43:

The left and right shift operators, << and >>, are defined is slide 33 of basics and in section 2.2 ("Built-in Operators") of the occam-pi Quick Reference Wiki, which is linked from this module's web page.

See also Question 42 (2007), which observes that shifting the bit-pattern of a positive integer leftwards multiplies it by 2 for each bit shifted. So, expanding the above replicator fully (it's only 7 times) and replacing the shifts with equivalent multiplies, we get:

      range <= (robot.radius * 1)
        speed := 0
      range <= (robot.radius * 2)
        speed := 1
      range <= (robot.radius * 4)
        speed := 2
      range <= (robot.radius * 8)
        speed := 3
      range <= (robot.radius * 16)
        speed := 4
      range <= (robot.radius * 32)
        speed := 5
      range <= (robot.radius * 64)
        speed := 6

So long as range is not more than 64 times the radius of the robot, a speed will be assigned. In brain.0, that range is the minimum clear distance reported by the laser scanner. It sets the speed on a logarithmic scale, stopping it if it's bumped into something.

The greatest value the laser scanner can return is the length of its rays (see the variable laser.range in the main process). In that main process, laser.range is set to 32 times the robot.radius – so the above code is safe. If you change that ratio, you may need to protect that replicated IF – see Question 30 (2007).

Keywords: cylons , operators , shift

Question 44:

Submission reference: IN1371

Can you make the submission dir's for the final assessments pretty please?

Answer 44:

Done!   See \proj\co631\cylons\ and \proj\co631\philosophers\.

Question 45:

Submission reference: IN1370

I'd like to change the way the robots are drawn so that each one is drawn with its number within its body.

Is there any easy way to draw a character with the raster stuff, or would it be a case of drawing lines etc?

Answer 45:

Sorry – it's on the to-do list! Right now, the rastergraphics.module has no text drawing procedures, :(.

Question 46:

Submission reference: IN1373

Would it be possible for you to make another sheet regarding the philosophers assessment? I have found it quite useful to have one for cylons.

Answer 46:

Again, I'm sorry! I think there is enough information in slides 3-60 from applying, in the q7.occ starter file and from the discussions in your seminar groups. You are also advised to browse through the wealth of material in the Anonymous Q&A repository – check out q7 and random in its keyword index.

I'll say this again ... since it's really really helpful: check out q7 from the keyword index of the Anonymous Q&A repository!

Keywords: q7

Question 47:

Submission reference: IN1375

I've just come to wrap up my cylons and am testing it on a different pc than the one on which I developed it. For some reason I'm getting a load of memory addresses spat out on the terminal and then this:

    exiting...(unimplemented instruction)
    The error occurred around like 91 in cordic.occ

I'm using the latest version of the transterpreter by the way ((20080116) transterpreter-2008.01.16)

Answer 47:

See the second bulleted item in the reports for Week 18 on the module webpage.

Keywords: cylons

Question 48:

Submission reference: IN1374

Hi, I've started wiring up the phils problem, and have most of it working. I plan on wiring it up normally and then switching to shared channels if I get time.

I've just come to wire in the forks and keep introducing deadlock :(

Because the two forks are picked, and done so in parallel I want to do something like this:

    ...  code omitted

That is read one fork's message then get the next one; or at least that's what I want it to do. What am I doing wrong here?

Answer 48:

You have four nested ALTs!! Nothing with that complexity is needed.

I'm assuming this code is in your display process – the one at the receiving end of all the report channels from the individual players (phils, forks and security guard) within the college. This display process should be pretty dumb – just displaying stuff whenever any report arrives. It should not be enforcing any ordering on the reports it receives (e.g. read one fork's message then get the next one). It should just receive a report (e.g. fork 2 has been picked up by the philosopher on its right) and display that fact to anyone looking at the terminal window. It could then receive a report about another fork ... or from the security guard ... or from a philosopher ... and display whatever is being reported.

It's up to the college processes to ensure illegal reports don't arrive ... like a philosopher reporting that it is thinking and, then, eating without going through a hungry state (when it may be held up by security) ... or a fork being held by two philosophers at the same time. The display just displays whatever is reported!

If all the (11) report channels belong to a single array, all the display process has to do is a single replicated ALT over all the elements. It knows which type of report it is (from the opening tag in the message protocol) and from which philosopher or fork it is (by the index of the element of the array on which the message arrived – e.g. 0-4 are from philosophers, 5-9 from forks and 10 is from the security guard).

If you use a channel with SHARED writing-ends, then the display process just listens on that one channel – no ALT is needed at all! The message protocol will need enriching so that the phils/forks also report their identity (just an INT) after the report type tag – but that's easy ... once you have worked out how each phil/fork gets to know its identity, which the starter code file (q7.occ) doesn't provide.

Keywords: q7

Question 49:

Submission reference: IN1376

I am currently doing the Cylons assesment and I have encountered the CSUB0 error. Is there any place where I can find what that error means? Or can you explain me the cause of such error?

The error is in the function:

    ...  code omitted

Answer 49:

We're sorry about this low-level error message! It will be changed. CSUB0 is one of the BYTE-codes in the intermediate language generated by the occam-pi compiler and which the Transterpreter interptrets. It is the instruction generated to check that numbers (usually array indices) are within certain bounds. So, it almost always means an array bounds violation.

You pointed in your code snippet to the line on which the run-time system told you contained the error. That line has a reference to an array element. The index in that reference has gone out of bounds – your code has a bug.

As it says at the top of this page, this is not a forum for debugging your code. However ... you might check your min.index function, which return the minimum range and not the index of the minimum range. Also, in your left.to.center function (once you've fixed the above problem), the index will still go out of range if, for instance, your min.index parameter was equal to MID.RAY.

Keywords: cylons , stop , csub0

Question 50:

Submission reference: IN1377

Occasionally, my Cylon changes from being all one colour to having a black and white spot in the middle. This will persist of 3 or 4 seconds. Why is this? Is this some aspect of the simulation I'm not aware of?

Answer 50:

Yep – the image rendering checks that a Cylon has not moved into a wall. See Pass 3 of the drone process. If a drone detects a hit, it allows it but renders that Cylon as you describe. So, if you see that happen, that's not good!

Each brain has its own drone, which represents the laser scanner and movement engine for the Cylon. The drone moves the Cylon (according to its current linear and angular velocities), renders it in the world images (rasters) flowing through, does its laser scan, reports the results to its brain, and receives new values computed by the brain for its velocities. For various logical reasons, the image rendering is done in three passes of the same image raster – this recycling is managed by the front and back processes (see the network diagram at the top of the file).

Of course, you don't need to know any of this to do the assignment!

Keywords: cylons

Referrers: Question 51 (2007)

Question 51:

Submission reference: IN1378

My problem, Question 50 (2007), happened while my Cylon was still using the supplied compute.speed function. I wouldn't have thought anything I did with the angle would have let the Cylon move into a wall?

Answer 51:

But some things you can do with the angle will move a Cylon into a wall!

The compute.speed function returns a speed depending on the minimum range detected by the laser scanner. Suppose a Cylon has its back to a wall. Its laser scans empty space – so its brain decides on a big forward velocity. Suppose its brain also decides on a big rotational velocity – say 120 degrees. That gets transmitted to its wheels (or whatever) along with the big forward velocity ... which results in the Cylon turning round and going splat, right into the wall, :(.

Cylons shouldn't rotate too fast, unless they are going forward very slowly or not at all. They don't know what's behind them!!

Keywords: cylons

Question 52:

Submission reference: IN1381

What exactly are we supposed to put into the report? The assignment says that we should detail any other rules we have implemented. Is this all you want, or is their anything else that should be included in the report? If you only want rules then my report isn't going to be a very long document.

Answer 52:

The report need not be very long at all – the worksheet asks only for a short report. It should say what rules you have decided for brain.1 to implement, together with any other changes you may have made to the simulation as a whole (this latter being optional). If you have gone parallel inside brain.1, that network should be drawn. If you have added/removed processes from the rest of the system, you should say why and draw the new network.

This report could be done as part of the documentation comments within you source file – but you may find it easier in a word-processed document.

Otherwise, new code that you write must be properly commented – preferably using the formal occamDoc style used in the starter file. Any clever coding fragments (which may be single lines) must have that cleverness explained. Any key variables declared must have their purpose explained. Anything obscure (without clarifying documentation) will be penalised.

Your report, if separate from your source code file, must be submitted alongside your source code. If you cannot produce an electronic version (in some reasonbly common format) for a separate report, you may hand hard copy in to CAS Reception – but that must be done before they close at 4pm. You will also have to ask for, and complete, a cover sheet for this assessment (title: "A4 - Robotics").

Keywords: cylons

Question 53:

Submission reference: IN1382

Hello, I am trying to re-implement my Cylons assignment to use processes for the rules (as most of it is done using functions), but I am having trouble with the RANGES data. I have tried to use a delta process to copy the data stream to two processes (a speed and direction process) ... but the second parallel output in the delta always outputs an empty array. Is there anyway of copying the RANGES stream or can this only be done with integer streams?

Answer 53:

Yes, there is a simple way. But RANGES is a MOBILE data type, which does not get taught till the next module (Co632).

If you want to do as you describe, you need to know two things:

Here is a delta process for channels carrying RANGES:

  PROC delta.ranges (CHAN RANGES in?, out.0!, out.1!)
      RANGES ranges:
        in ? ranges
          out.0 ! CLONE ranges
          out.1 ! CLONE ranges

We have to CLONE twice in the above for the PAR to be safe. If we wrote:

          out.0 ! CLONE ranges
          out.1 ! ranges

the second component of the PAR sends the mobile data in ranges away, leaving the variable ranges changed (actually undefined). So, what is being cloned on the first component would depend on whether that happens before or after the second component. This breaks the parallel usage rules of occam-pi (which are there to ensure the scheduling order within a PAR doesn't matter). [Unfortunately, the present occam-pi compiler allows the above – this will be fixed. Meanwhile, don't do it!]

Here is a neat way to program the delta with only a single CLONE per cycle:

  PROC delta.ranges (CHAN RANGES in?, out.0!, out.1!)
      RANGES a, b:
        in ? a
        b := CLONE a
          out.0 ! a
          out.1 ! b

See the scene process in cylons.occ for another example of cloning. The data type being cloned there is RASTER, a MOBILE 2-D array of INTs (each INT is a pixel colour). RASTER is defined in the rastergraphics.module, included at the start of the file.

Keywords: cylons

Question 54:

Submission reference: IN1383

I often find that my silly Cylons seem to be facing in one direction but not necessarily always moving in that exact direction. This generally happens when I am near a wall. Is this a bug in the code or something I have somehow managed ... because I can't understand how I could have done this?

Answer 54:

I'm afraid it's probably your bug ... without seeing your code, I can't know for sure.

Keep nagging at it! With a rotational velocity of zero, Cylons move forward in a straight line – following their central (red) ray. With a fixed small rotational velocity, they will curve in a fixed radius arc. Those rotational velocities should never get large. The worksheet recomends values between -10 and +10. See Question 40 (2007) for problems associated with large rotational velocities (ANGLEs per cycle).

Keywords: cylons

Question 55:

Submission reference: IN1391

I have a question about this previous question/answer: Question 61 (2006).

I'm a little bit confused about this answer, are we able to put in another process into "secure.college"? Or are we supposed to have our reporting process communicating from inside the philosopher? If we are supposed to call the reporting process from inside the philosopher how would it be possible to wire the reporting process to the screen as it would be outside the main q7 process?

Answer 55:

The point about that was not to interfere with the collection of processes inside "secure.college", but rather re-wire them in a way that allows your display process to live 'outside' the secure-college process. Thus, the top-level Q7 process will run the modified "secure.college" and any "display" process (connected to the screen) in parallel. To get information from the individual philosophers/forks to the display process will require adding channels (or a single shared channel), and those channels must pass through "secure.college" (i.e. they will appear in its interface).

Keywords: q7

Question 56:

Submission reference: IN1392

Within the philosopher PROC, i've implemented a looping function to report the state to the display PROC (via a shared-channel), then pause for some amount of time:

    SEQ i = 0 FOR 5
        CLAIM report!
          report ! thinking; id; i
        pause (second)

What i want to do though is wrap this in another PROC, however am stuck at how to go about relaying what the state is (the report has a CASE protocol type) and the state i want to relay is the "thinking" or any of the others i have I thought of have the added PROC to recive a VAL INT, to which then uses that over a CASE of IF seq, though this just would have duplicated code of the above.

Is there any way to pass a PROTOCOL tag to a PROC parameter, similar to a VAL in occam-pi?

Answer 56:

No, you cannot have data items of PROTOCOL types. This is because the data transported by the variant (CASE) protocol depends on the case -- which would require either UNION types or var-args PROCs, neither of which we currently have in occam-pi. I'd question whether or not wrapping up such an output in a PROC is sensible anyway, but you could use VAL INTs to indicate which tag you're wanting to output (and make sure the PROC gets the necessary information for any particular case).

If you're just after code separation, do a separate PROC for each type, e.g.:

    PROC report.thinking (...)
      ...  code

which you can declare inside the body of the philosopher process.

Keywords: q7

Question 57:

Submission reference: IN1405

Hi, I am doing the dining phil assessment and I am getting some wierd behaviour out of the philosophers method. in the following code:

      CLAIM output!
        out ! ID; 't'
      ...  more code
        ID = 0
      ...  more code
      CLAIM output!
        output ! ID; 'e'
      ...  more code

the first output of ID (which is a parameter) provides the correct values (0-4 for specific phils). I have proved this by putting the 'STOP' test above the first claim. however, the subsequent outputs are always 0 an i cannot get the 'STOP' test to work, i.e. it never stops. this leads me to believe that ID is being changed somehow when it is sent down the channel. can you give me any tips?

(all of the output channels work correctly, its just that the value of ID changes some how)

Answer 57:

This seems a little odd.. If you're compiling in "stop" error-mode, then a process that goes STOP will just quietly stop, and leave other processes running. In "halt" error-mode (which is the default), a process that goes STOP will shut-down the whole program (and cause it to exit with an error message). The behaviour you describe (correct initial outputs, but then only ID 0 reported), sounds like something in "stop" error-mode (i.e. all but philosopher 0 die quietly). Putting a STOP above the first output in "stop" error-mode would induce deadlock, which the run-time detects and exits with an error message. If the type of ID is VAL INT (presumably it is), then it's not going to change, unless something has gone very wrong with your KRoC/Transterpreter installation.

But perhaps you are saying that you have 5 different philosopher processes, one for each ID? In which you have tests for different correct values (0-4 for specific phils)?? That would be very silly though ...

So, with just one philosopher PROC and five instances (each with a different ID value passed to them), the one with ID 0 will survive your test and the other four will STOP, crashing the system.

If the type of ID were a mobile something, and the output channel carried mobiles, then ID could be subject to change (but then couldn't a be a VAL INT parameter). Otherwise, there is no way sending the value of ID down a channel will change what is in ID, regardless of whther it is a VAL.

We really can't tell what your problem is with the code snippet you posted, I'm afraid. You could try mailing us directly ...

Keywords: q7

Question 58:

Submission reference: IN1406

Hi, could you tell me if it is possible and if so how to: initiallise an array of strings with values in it ie something like this

  VAL [][]BYTE strs IS ["hello","fish","mango"]:

i can't work out how to do it.

Answer 58:

In a 2-dimensional array, all sub-arrays must have the same dimension. Here, your individual strings are of different sizes. See Question 33 (2006) and related questions.

Keywords: q7 , strings

Question 59:

Submission reference: IN1407

Hi, I am working on the inheritance protocols for the dining phil assignment and the following code:




crashes the transterpreter. I get this message:

  Warning: Changed source file saved.
  Compiling: q7.occ
  Fatal-occ21-q7.occ(61)- unknown tag N_SPROTDEF in pi_valcheck

Any ideas what I am doing wrong?? In the lecture notes there are only examples of inheritance using CASE protocols. Am I only allowed to use those? Thanks for your help

Answer 59:

In the shared-etc slides, slide 28 (the first one on this topic) says: "A variant (or CASE) PROTOCOL can extend previously defined ones". So, yes – I'm afraid inheritance is only defined for CASE (i.e. variant) protocols. One protocol extends another by adding new variants. We have to have the tags to distinguish between the different variants of message.

By the way, please don't put strings (e.g. [28]BYTE) into your report protocols. For one thing, occam-pi doesn't support strings very well (until we start working with mobile arrays, whoses sizes are dynamic). For another, constructing particular strings for the report messages should not be done by the processes generating those reports. Do that separately – e.g. in a display process receiving those reports. This separates two concerns: the logic of the system making the reports and the presentation of the reports.

Keeping these separate means we can change the look-and-feel of the running system (e.g. to introduce all sorts of animation) without touching the logic of the system. De-coupling such things is simply good (software) engineering.

But we do apologise for the compiler crashing on your (illegal) code. That won't happen with the new compiler(s) in development! The Transterpreter and KRoC currently share the same compiler. Downloading KRoC delivers full sources for the compiler. We are always grateful for any fixes, :).

Keywords: q7

Question 60:

Submission reference: IN1416

What do we need to submit for the remaining assignments? do we need to draw diagrams again for robots and d.p or is it just source code? Also what time is the deadline? Is it midnight like the previous online assignments?

Answer 60:

These have been answered previously. If your dining phils network is anything more complex than the college connected to a display process by an array of channels (or a shared channel), then yes: please draw the network. You may have a richer network because of certain animation effects. If so, you will have drawn your networks when designing so this will not be an extra burden.

For the Cylons, if your re-programmed brain has a network of sub-processes, please submit its network diagram. If you have modified the network in the rest of the system, submit the modification. Any electronic format (that we can view) will do.

The submission deadline in the midnight at the end of Tuesday.

Valid CSS!

Valid XHTML 1.0!

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