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: IN1330
The diagrams that we need to submit for q4 ...
do we need to submit a diagram for all the new processes we have made
(numbers2
, integrate2
, pairs2
)
or is it just a layout of our processes for q4
?
Thanks.
Please submit a diagram for any process network you have changed (from any diagram given in the question sheet or starter file). Diagrams could be ASCII text art (as in the starter file) or any standard electronic document (also deposited in your submission directory) or a neat hand drawing (handed in to the CAS office with a cover sheet for this assessment number and module ... or scanned in and copied into your submission directory).
So yes ... we do want diagrams for your modified numbers2
,
integrate2
, pairs2
and q4
process networks. Only process networks need diagrams –
not serial logic.
Keywords: q4
Submission reference: IN1328
With relation to Question 15 (2007). I have exactly the same problem and I don't really understand the explanation.
The pause
function in print.streams
goes much faster than the one in my
speed
process (I do comment the one in print.streams
out before trying
the one in my speed
process). I have noticed that some of the output done in
print.streams
is PAR
but even if I copy and paste the in/out in my speed
process a few times (to delay the delay
process from happening) it will not
reach anywhere near the same speed is if it were done in print.streams
.
Why will the pause
in speed
not go as fast as the one
in print.streams
?
Thanks.
Without seeing your program, I've no idea ... but can hazard a guess.
The delay
process imposes the same delay on any process
invoking it – it will be just the same in print.streams
as in your speed
control process.
In print.streams
, the pause
is executed once
per cycle – i.e. once for each line of output.
Now, where is your speed
process and what stream is it
controlling?
If it is in the stream of BYTE
s coming out from print.streams
,
you had better not be invoking pause
in every cycle – otherwise,
you will be getting that pause for every character generated, not for every line!
Your will be controlling characters per second, not lines per second.
If this is you problem, a simple fix is to invoke pause
only
if the BYTE
flowing through is '*n' (newline).
There is, though, a better and more efficient solution ...
By the way, there is no PAR
output in print.streams
– only PAR
input.
Keywords: q4
Referrers: Question 23 (2007) , Question 25 (2007) , Question 25 (2007) , Question 25 (2007) , Question 28 (2007)
Submission reference: IN1331
I am a bit confused. I am on the speed section of q4
.
I understand that time increments every microsecond.
I have declared a TIMER
and got the time
and I have a variable which I PLUS
to the time
to set up my speed delay.
I have set the initial value to be 1,000,000 (1 second) but
the output comes out a lot slower than 1 line per second.
Any ideas why this might be? Thanks.
Check that you are not making the same mistake as that suggested in the answer to Question 22 (2007).
Keywords: q4
Referrers: Question 25 (2007)
Submission reference: IN1329
print.streams
waits 1 second until it outputs the next line.
While it waits, do the other processes (number
,
pairs
and integrate
) wait also?
In occam-pi, can we force the channels to input to a process, while that
process waits for some time to pass, in order to accept at a later stage?
Yes to your first question. They are all blocked while
print.streams
is sleeping since that has
to take the output streams they are trying to generate.
No to your second question. Nobody can force input into a process! If a process is not inputting anything, then no input can occur – what-you-see-is-what-you-get. Any process trying to output something down a channel to a process owning the other end, but not currently inputting from it, simply has to wait. No data is lost. When-and-only-when the target process gets around to do some input, the message will flow from the source to target &ndash nothing is missed.
[Note the contrast with Object Orientation. Any object can be forced to take input (delivered by method invocation) at any time, whether it's ready for it or not. There's nothing an object can do to prevent this. Sorting out the resulting mess when that happens is one of the reasons why OO – even single-threaded OO – can be a real headache ... ]
Keywords: q4
Submission reference: IN1332
Hi, thanks for answer my question about time delay, Question 23 (2007), but I don't think I have the same problem as Question 22 (2007).
This is my code for speed
and q4
processes.
I don't use a pause
function so I am not sure what is causing the extra delay.
The speed
process is sitting between the output of
print.streams
and a freeze
process I wrote
to freeze all the output before sending it to the screen.
... code omitted
We can't discuss the details from your code here.
But you do have the same problem as suggested for Question 22 (2007)!
You're not using the pause
process to get a delay,
but you are using a TIMER
to get the delay directly
... and you are doing that delay for every character in
the data stream!!
The fix is described in the answer to Question 22 (2007).
By the way, pause
is a process, not a function
– terminology is important.
Submission reference: IN1327
When are we going to get our first and second assessments back?
We've got the third assessment due tomorrow, and I've got zero feedback on the work I did for the other assessments... that seems more than a little unfair given that I know some of the groups have got their work back.
Most people have had their marked work for the first assessment back – some as marked scripts, some by email (depends on the supervisor). Scripts were handed back in seminars, so anyone not going would have missed out. I'm hoping that feedback on the second assessment will also happen in the seminar groups today and tomorrow (or has already happened by email). Model solutions for both these assessments have been available for more than a week.
Having said that, please mail me (p.h.welch@kent.ac.uk) directly if you are missing any assessment feedback and have been attending your seminar groups regularly. Apologies in advance to any in this category – I will check out what has happened and get back to you quickly.
Thanks.
Referrers: Question 27 (2007)
Submission reference: IN1333
With regard to Question 26 (2007), I'm in seminar group 2 (Weds, 1100, KS11), and I've attended both seminars (as of Tuesday night). We've received nothing on paper and nothing by email for assessment 1 or assessment 2.
Thanks – investigating ...
Referrers: Question 29 (2007) , Question 29 (2007)
Submission reference: IN1334
I have got what I believe is a correct solution to q4. However when I calculate the delay for 1024 lines/sec and then run it, the output doesn't go fast enough. In a second I only get around 300 lines to the output.
If I change the delay in my speed process to be 0 the output still doesn't seem to go fast enough. If I put it to -1 then the output roars away!
Is this a problem in transterpreter? Maybe running too slow or is there likely to be a delay in my program?
This came in too late (68 minutes before the submission deadline!) to be answered. But a system can only generate lines of output as fast as its output device can take it. If we program it to generate faster, the choice is between losing data or being blocked by the receiving process (in this case, the terminal screen emulator). In occam-pi, we always chose the latter - i.e. the system slows down. See Question 17 (2007).
If that was not your problem though, see Question 22 (2007) and Question 15 (2007).
Submission reference: IN1359
Following up Question 27 (2007) ...
Following up Question 27 (2007), I understand that marked scripts for assessments 1 and 2 were emailed to members of that seminar group on the Wednesday morning on Week 18. That was one day late for assessment 1 (for which I apologise), but six days early for assessment 2.
We always try to beat – by some margin – the three week rule for providing feedback on assessments. In this case, model answers for both assessments were provided, together with the marked scripts, within that deadline (except for the scripts for assessment 1 being one day late for one of the groups).
For information, the model answer for assessment 3 is already available from the
usual place on raptor
:
\courses\co631\answers\a3.occ <== supporting exercise (not part of the assessment) \courses\co631\answers\a4.occ <== model answer for assessment 3
Submission reference: IN1341
In the lectures, we were told that the IF
statement requires
a TRUE
statement at the end.
But in the compute.speed
function of the assesment 4,
there is not any TRUE
statement:
INT FUNCTION compute.speed (VAL INT range, robot.radius) INT speed: VALOF IF i = 0 FOR 7 range <= (robot.radius << i) speed := i RESULT speed :
And still though we do not get a compiler error. How can this happen???
Nope – you were not told that an IF
statement requires
a TRUE
statement at the end! [To correct your terminology,
there is no such thing as a TRUE
statement ... you mean
a TRUE
condition. However, this is not your problem here.]
The semantics of an IF
include the property: if all of its conditions
evaluate to FALSE
, it STOP
s (which, in the default
mode of compilation provided by the Transterpreter, provokes a run-time error).
So, we only need a final TRUE
condition if we have not dealt with
all possible run-time conditions explicitly (earlier in the IF
)
and we need a none-of-the-above condition (triggering an appropriate
action – which is often just SKIP
).
The same is true for a replicated IF
, such as appears
in the compute.speed
function (used by the brain.0
process in the cylons.occ
starter file).
No enclosing IF
, nesting the replicated IF
with a final TRUE
conditional process, is mandated by the
language – so there is no error for the compiler to report.
Therefore, the writer of this code is confident that at least one of
the replicated IF
conditions will always turn out to be
TRUE
.
In fact, for the given parameters of the system (see the various VAL
declarations early in the file), this will be true.
However, if we vary things (e.g. reducing the robot.radius
size,
used in the replicated condition of this function and initialised in line 649),
this replicated IF
will indeed fail!
Not good.
So, protect it – for example:
INT FUNCTION compute.speed (VAL INT range, robot.radius) INT speed: VALOF VAL INT MAX.SPEED IS 7: -- maybe this should be in the global list of VALs ... IF IF i = 0 FOR MAX.SPEED range <= (robot.radius << i) speed := i TRUE speed := MAX.SPEED RESULT speed :
Summary: Yes – the code is unsafe and the replicated IF
should be protected (by nesting inside a simple IF
with a TRUE
condition).
No – the code is perfectly legal as it is and the compiler is right to accept it.
Keywords: cylons
Referrers: Question 43 (2007)
Submission reference: IN1344
Can we write our own implementation of compute.speed
method for brain.1
?
Because brain.1
has its different behaviour than brain.0
.
Yes, of course!
But call it something different ... so that brain.0
will continue to function.
Keywords: cylons
Submission reference: IN1355
In the last seminar, some of the groups apparently got a walkthrough of the
cylons.occ
code, with things like pointers on which bit to modify to
achieve certain changes in behaviour and so on, a live demo of some code
changes, and some discussion on possible approaches/end-results.
Is this material going to be replicated in the Cylons worksheet so that the group/s who didn't get this aren't unfairly disadvantaged?
What happens in the seminar groups is largely driven by those attending. It is not possible to ensure that all groups experience the same things, nor is it desirable. However, we (the seminar leaders and myself) do plan the outline of work for the seminars so that there will be a common framework.
For assessment 4, there are no pointers necessary for which parts
of the cylons.occ
starter file to modify, other than those
given in the worksheet for the assignment.
All behaviour is governed by the logic you write for
the brain.1
process – and nothing else!
You have been given logic for a brain.0
process as a crude
example of what might be done.
The live demo of some code changes shown in one of the seminars was
a trivial variation of the live demo presented to all in the Friday
lecture of Week 18. Nobody was disadvantaged (unless they missed
that lecture).
For those who did miss that lecture, simply comment out the IF
statement in the brain.0
process.
Now you can do the demo yourself!
You will see Cylons moving through walls and through each other - not good!
There's nothing in the simulation code that enforces the solidity of
walls or the robots.
It's up to the Cylons themselves whether that happens.
For the brains you program for this assessment, allowing such behaviour
will lose marks.
You do not need to look at or understand or modify any other parts of
the system defined in the cylons.occ
starter file.
Unless you want to, of course! A good place to start would be to make sure you can follow the network diagram drawn near the start of the file with the parallel code in the top-level process. Specifying, making and documenting interesting changes in the rest of the system (e.g. being able interactively to turn off/on the display of the laser rays in the animation) would count towards the remaining 20% of marks for this assessment.
As described in the Cylons worksheet, implementing the functionality
suggested for brain.1
in the worksheet (and demonstrated in the
lectures) only earns 80%.
Implementing and explaining additional, or radically different but still worthy,
behaviour gets the rest.
Making changes described in the previous paragraph is an alternative
(or additional) way to earn that remaining 20%.
Keywords: cylons
Submission reference: IN1351
I have a bit of a problem in terms of the random
function.
I've read through the answers on here already concerning this function,
but when I use it ... it always seems to return the initial seed.
I have the following code to make the robot turn a random amount:
INT number: VAL INT maxvalue IS 30: INITIAL INT seed IS 15: IF some.condition SEQ ... code omitted number, seed := random (maxvalue, seed) ... code omitted other.condition ... whatever
I'm pretty sure it's always getting the same number. Have I used it in the correct way?
If that really is an extract from your code, then no!
If the above is inside some loop, each time round the seed
is re-declared and re-initialised to 15
.
So, that number is presented each time as the seed to the random
function and each time it will compute the same results – not very random!
Your three declarations must be made just the once, before entering the loop:
INT number: VAL INT maxvalue IS 30: INITIAL INT seed IS 15: SEQ ... any other initialisation code WHILE still.running SEQ ... stuff IF some.condition SEQ ... code omitted number, seed := random (maxvalue, seed) ... code omitted other.condition ... whatever
Now, the first time around, random
will be called with
a seed value of 15
.
But it returns two values: one is the pseudo-random number
computed and the other is an updated value for the seed.
The next time around, random
will be called with that
updated seed ... and so on.
Note: please see Question 55 (2006) about warming up the random number generator (which is simple and effective, but you have to treat it right) first! See also this same question and Question 79 (2003) for clues about better ways to set the initial value for the random number seed.
Submission reference: IN1358
In the replicators
slide 66, the greater
process
is said that it doesen't have symmetric output.
What is symmetric output?
Why does greater
process not have symmetric output?
The greater
process takes one number from each of its input
channels and sends the smaller of them down its first output channel
and the greater of them down its second output channel.
Therefore, when wiring it up in a network, the order in which we plug in
the output channels matters – there is no symmetry.
On the other hand, the order in which we plug inthe input channels does
not matter – there is symmetry.
Thus:
greater (a, b, c, d)
has the same effect as:
greater (b, a, c, d)
but is different from:
greater (a, b, d, c)
which sends the larger numbers down channel c
(wheras the first two instances both send the larger down d
).
Note: the first two arguments of greater
are its input
channels – the second two arguments are its otuput channels.
Submission reference: IN1360
I have a question about SEQ
and PAR
... we've had Peter lecturing since the
start of term, telling us to always use PAR
s wherever we can, unless we
specifically need something to happen in order, in which case you use a
SEQ
. Which all makes perfect sense.
However, the other day, we had Fred lecturing, who implied that because of
the overhead in setting up PAR
s, you shouldn't use them unless you actually
needed them. We brought up this discrepancy in the lecture, and Fred said
something along the lines of: in the exam, either is fine (unless the
question is obviously specifically looking for something to happen in
parallel or sequence).
He said that we should use our judgement in which to use in the exam, but I
don't think we have any experience in this area - we don't have a grasp on
the overhead of a PAR
(I certainly don't), but Fred obviously does, due to
writing occam compiler(s?).
I'm now a little confused, and I think other people are too, as to what I'm supposed to write in an either/or situation. Is either OK?
No – I (Peter) carefully did not say to use PAR
s wherever we can!
I said that whenever communications can be done is parallel, we must
do so – otherwise, the ways in which the process can synchronise with
the newtork in which it is embedded is needlessly constrained to happen in some
SEQ
uential order.
This can lead to needless delays (on the other processes trying to communicate)
and, in the worst case, to a needless deadlock (which is unacceptable).
For example, see the golden rule shown on slide 4 of the replicators
slides.
I have also warned that executing pure compute code (i.e. any code not involving synchronisation with other processes) in parallel may lead to a slower executing system, so we should be careful. As Fred said, there are overheads in starting up, scheduling and shutting down parallel code – even though these are very small for occam-pi run-times (e.g. ten-or-so nanoseconds for compiled code). So, if the codes we are asking to run in parallel are very short (e.g. a single assignment), it may not be worth it. Further, it is only the run-time support for compiled occam-pi that currently takes advantage of multicore processors so that parallel computations can actually happen in parallel – and the extent of that physical cuncurrency is bounded by the number of cores present (mostly no more than two right now). Any more parallel processes released than the number of cores must be scheduled, in turn, on the available cores.
The rules of occam-pi ensure that the semantics of a PAR
involving
only pure computation are exactly the same as a SEQ
.
The former says "run these processes in any order, or at the same time, till
they all finish" and the latter says "run these processes in the order
written".
If the compiler allows the PAR
, then the processes to be run
are independent from each other and any order, including the order
written, is OK.
So, if the overheads of going PAR
are higher than the time
benefits of running them at the same time (bearing in mind that we might
only have two cores and, if using the current Transterpreter, no advantage
is taken of the second core), run those small codes in SEQ
uence
– it will be faster.
There will come a time, perhaps soon, when running pure computation statements
in parallel will distribute over lots and lots of processor cores with a low
enough overhead to make it worthwhile – just not yet!
The PAR
rules of occam-pi automatically restrict this only to
codes that are safe for parallel execution, which is a plausible reason
for starting to do this now.
So, in answer to the final part of your question, either writing
a SEQ
or a PAR
for low-level short-lived computations
(so long as the PAR
version breaks no rules) is OK for exam
answers or assessment codes.
The time has already come when running long-lived processes in
parallel is worthwhile, even for processors that are only dual-core.
And ... as laid out in the golden rule and for the reasons stated above,
when communication is involved and we can specify PAR
,
we must specify PAR
.
Good question! :)
Submission reference: IN1361
For Assesment 4, does the RANGES
array come in the order of:
Or is it the other way around?
Humm ... looking at the fan
procedure, which builds
the ranges
array, it moves psi
(an ANGLE
variable) from a small value (theta - phi
) up by
even increments (delta
) through the straight-ahead
(theta
) and up to its final value (theta + phi
).
The angles psi
moves through are the angles of the rays
in the fan.
So. it depends on how the trig functions CORDIC
(which converts
from polar to cartesian coordinates) and CIDROC
(which converts
from cartesians to polars) treat polar angles. As they increase,
is the point sweeping clockwise or anti-clockwise?
In (most) common views, increasing the angle means anti-clockwise. Think of the standard view of a 2D Euclidean plane, with X and Y axes crossing at (0, 0). From the origin, an angle of 0 (degrees) usually points to the right ... an angle of 45 (degrees) points top-right ... an angle of 90 (degrees) points straight up. So, increasing angles mean sweeping anti-clockwise.
If that is indeed how CORDIC
is programmed (and the sources are
available!), then the ranges
array (which is built up in increasing
order of angle) holds the distances of the rays going anti-clockwise –
i.e. increasing array indices give ranges from the rightmost ray to
the leftmost ray.
To find out for sure, add the mechanism for single stepping the Cylons
simulation and printing our the ranges
array each step (as discussed
in your seminar groups).
With only one brain.1
robot, it will quickly become apparent which
way around the fan is represented by the ranges
.
For the standard model of behaviour suggested for brain.1
, we don't
actually need to know the answer to your question! So long, that is, as the way
angles are treated by the trig functions are the same as the way the motors
treat the angular velocity component of its movement instructions.
And they are so treated: increasing angles means anti-clockwise always ... or
clockwise always. So long as there is this consistency, which way they go
doesn't make any difference to the code that is needed for the necessary
control.
Keywords: cylons
Submission reference: IN1364
For assesment 4, I am interested in finding the angle between each ray. I have counted the rays and there are 35 rays. Therefore 34 angles? How can I get the total angle of the rays?
I will use the ray separation angle to implement the first part of the assesment. Am I taking the long way?
You don't have to count the rays!
Look at the constants defined at the start of the cylons.occ
starter file (around line 56). The constant N.RAYS
(which is commented: "number of rays
") tells us the answer
(33).
The next constant is an angle, SCAN
, set to 120 degrees and
commented: "laser
scan
sweep
".
This is the total angle sweep of the arrays, so the angle between adjacent
rays is:
SCAN / (N.RAYS - 1)
Yes – it probably is useful to use this information.
Keywords: cylons
Submission reference: IN1363
In the final hints for brain.1
you are saying that if the minimum is less
than the robot radius, it's bumped - back off quick.
If the robot, ever comes to this situation then it is most propably, be in an overlapping mode. But since is not what we really want. This case is like a quard process which we never want to be exectuted.
Therefore is like a TRUE
at the end of an IF
.
Am i missing something here?
If the minimum range reported is less than the robot radius, it has bumped into something. In reality, that bump could be a disabling crash – so it's not something you should allow to happen. The Cylon should have slowed down and/or moved away so that it didn't happen.
Having said that, if it's only a little bump (i.e. the minimum range is only just less than the robot radius) and it bounces away quickly, we'll not mark that down.
I don't understand your reference to "a quard process which we never want to be
exectuted" or "a TRUE
at the end of an IF
"?
Your question describes a state that should not happen ... but I don't see that
state in terms of an ALT
guard or IF
condition?
Keywords: cylons
Submission reference: IN1365
I feel that the amount of coursework for this module is much more than any other module I've taken.
The assessments are getting much harder and overlapping two really doesn't help. Why couldn't the two final ones have been combined into one assessment testing both skills?
It might have been ok having two assessments from one module at the start of the term, but being a final year CS student, the deadlines regarding final year projects and other modules are building up.
The final two assessments for this module are deliberately open-ended. We want to see what you can do – above a minimum requirement – and this gives you a chance to be creative. However, you will still get very good marks if you do the minimum.
The two assesments test different skills. The Cylons is about the logic for planning robot movement in response to a particular set of sensary data. It is embedded in a multi-robot graphics animation, the code for which is fun and effective but does not need to be understood or modified. The philosophers exercise is the opposite – we give you all the control logic and you are invited to construct a simple animation that shows what is happening. Testing both such skills at once would be daunting.
Each assessment has been given four weeks, with an overlap of two weeks when both can be being developed. You are not expected to work for four weeks on each of them! The long periods enable you to schedule the work in a way that works best for you.
Having said that, we do appreciate that final year students may have a special problem because their final year projects are due in week 23 (which is in the middle of the two deadlines for our final two assessments). So, for final year students, we will be relaxed about our deadlines. An announcement on this will shortly happen.
Referrers: Question 41 (2007)
Submission reference: IN1368
I added:
IF initial.angular.velocity > (ANGLE.DEGREE*360) STOP TRUE SKIP
to check the value being passed into the brain.1
method and
the STOP
condition is reached almost all the time. Does this
mean the value being passed is not between 0 degrees and 360 degrees?
If not, what is the value in relation to the 0-360 degree scale?
Also, am I right in saying that if the current angular.velocity
(during the while-loop) is say, 270 degrees (270*ANGLE.DEGREE)
then a move to the right would be something like angular.velocity
PLUS
(25*ANGLE.DEGREE)
?
Thanks.
Good question – you have been experimenting!
The values of initial.angular.velocity
are set randomly
between -5 and +5 degrees (excluding zero) – see lines 534-536
in the place.robots
procedure.
Recall: on the last page of the Cylons worksheet, the ANGLE
datatype is described. Like TIMER
values, they wrap around at
180 degrees, which is actually the same as -180 degrees. Comparisons between
ANGLE
values are therefore unsafe if the difference between them
is more than (or equal to) 180 degrees – this is exactly the same as
for time comparisons (which become unsafe beyond about 35 minutes –
see "A Brief History of Time", slides 43-53 of basics).
So, if you had added checks like:
IF initial.angular.velocity > (ANGLE.DEGREE*5) STOP initial.angular.velocity < (ANGLE.DEGREE*(-5)) STOP TRUE SKIP
no STOP
would have been executed.
Please don't have an angular.velocity
(the amount of turn
per cycle) of anything like 270 degrees – these are Cylons,
not quasars! The worksheet suggests ranges between -10 and 10
degrees.
I don't understand the last part of your question.
The angular.velocity
is the amount of turn per cycle.
The linear.velocity
is the speed in the forward direction
(along the central ray) on a scale of roughly pixels per cycle
(but not quite, since the Cylon can be moving at any angle to the
horizontal-vertical grid of pixels).
Keywords: cylons
Referrers: Question 42 (2007) , Question 54 (2007)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. |