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.
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.
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).
Submission reference: IN1369
What is the operator for raise-to-the-power?
For example, 2^32
– what does occam-pi have for ^
?
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::
REAL32 FUNCTION POWER (VAL REAL32 x, y)
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 INLINE FUNCTION "^" (VAL INT x, y) INT result: VALOF SEQ 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)
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
Cheers.
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:
IF 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
Submission reference: IN1371
Can you make the submission dir's for the final assessments pretty please?
Done!
See \proj\co631\cylons\
and \proj\co631\philosophers\
.
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?
Sorry – it's on the to-do list!
Right now, the rastergraphics.module
has no text drawing
procedures, :(.
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.
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
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)
See the second bulleted item in the reports for Week 18 on the module webpage.
Keywords: cylons
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?
You have four nested ALT
s!!
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
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
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
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?
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)
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?
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
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.
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
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?
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:
MOBILE
can only have one variable holding it - if we assign
or send from that variable, the MOBILE
moves to the target leaving
the original variable with nothing;
MOBILE
can be CLONE
d –
if you CLONE
a MOBILE
, you get a duplicate copy.
So, if we send a CLONE
, the variable from which the clone
was taken still has the original –
it's the CLONE
that's gone.
Here is a delta
process for channels carrying RANGES:
PROC delta.ranges (CHAN RANGES in?, out.0!, out.1!) WHILE TRUE RANGES ranges: SEQ in ? ranges PAR 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:
PAR 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!) WHILE TRUE RANGES a, b: SEQ in ? a b := CLONE a PAR 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 INT
s
(each INT
is a pixel colour).
RASTER
is defined in the rastergraphics.module
,
included at the start of the file.
Keywords: cylons
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?
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
(ANGLE
s per cycle).
Keywords: cylons
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?
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
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 SEQ 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?
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
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:
WHILE TRUE SEQ CLAIM output! out ! ID; 't' ... more code IF ID = 0 SKIP TRUE STOP ... 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)
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
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.
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.
Submission reference: IN1407
Hi, I am working on the inheritance protocols for the dining phil assignment and the following code:
PROTOCOL SECURITY IS INT: PROTOCOL PHIL IS INT; [28]BYTE: PROTOCOL FORKP IS INT; [19]BYTE: PROTOCOL REPORT EXTENDS SECURITY, PHIL, FORKP:
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
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
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?
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.
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. |