|
Four types of iterative statement are available: the
for-statement that provides definite iteration, and the
for random-, while-, and repeat-statements
that provide indefinite iteration.
Iteration may be performed over an arithmetic progression of
integers or over any finite enumerated structure. Iterative statements
may be nested. If nested iterations occur over the same enumerated
structure, abbreviations such as for x, y in X do may be used;
the leftmost identifier will correspond to the outermost loop, etc.
(For nested iteration in sequence constructors, see Chapter SEQUENCES.)
Early termination of the body of loop may be specified through use
of the `jump' commands break and continue.
for i := expr1 to expr2 do
The expressions in this for loop must return integer values, say
b, e and s (for `begin', `end' and `step') respectively.
The loop is ignored if either s>0 and b>e, or s<0 and b<e.
If s=0 an error occurs. In the remaining cases, the value
b + k.s will be assigned to i, and the statements
executed, for k=0, 1, 2, ... in succession, as long as
b + k.s ≤e (for e>0) or b + k.s ≥e (for e<0).
In the second form above, where the step size is omitted, it is taken
to be 1.
Each of the elements of the finite enumerated structure S will be
assigned to x in succession, and each time the statements will be
executed.
Check whether or not the Boolean expression has the value true; if it has,
execute the statements. Repeat this until the expression assumes the value
false, in which case statements following the end while; will
be executed.
The following short program implements a run of the famous 3x + 1
problem on a random integer between 1 and 100.
> x := Random(1, 100);
> while x gt 1 do
> x;
> if IsEven(x) then
> x div:= 2;
> else
> x := 3*x+1;
> end if;
> end while;
13
40
20
10
5
16
8
4
2
Execute the statements, then check whether or not the Boolean expression
has the value true.
Repeat this until the expression assumes the value
false, in which case the loop is exited, and statements following
it will be executed.
This example is similar to the previous one, except that it only
prints x and the number of steps taken before x becomes 1.
We use a repeat loop, and show that the use of a break
statement sometimes makes it unnecessary that the Boolean expression
following the until ever evaluates to true. Similarly, a
while true statement may be used if the user makes sure the
loop will be exited using break.
> x := Random(1, 1000);
> x;
172
> i := 0;
> repeat
> while IsEven(x) do
> i +:= 1;
> x div:= 2;
> end while;
> if x eq 1 then
> break;
> end if;
> x := 3*x+1;
> i +:= 1;
> until false;
> i;
31
For each iteration of the loop a random element of S is assigned to x
and the statements are executed.
The loop will repeat with a new random selection each time until a
break command is executed as part of the statements.
Some objects (such as sequences, indexed sets, associative arrays, etc.)
have an index or other value associated with each element.
The standard iteration would loop through the elements in the object,
but sometimes this other value is also wanted.
Magma provides a special syntax to make it easy to get both the
values at once.
For conciseness, the explanations below assume that the other value is an
index; the actual interpretation of the dual iteration variables is
described in the Handbook section for each type which supports dual iteration.
Each of the elements of the finite enumerated structure S will be
assigned to x in succession, with the associated index assigned to i,
and each time the statements will be executed.
For each iteration of the loop a random element of S is assigned to x,
and its associated index assigned to i, and the statements are executed.
The loop will repeat with a new random selection each time until a
break command is executed as part of the statements.
> p := 10037;
> for x in [1 .. 100] do
> for y in [1 .. 100] do
> if x^2 + y^2 eq p then
> x, y;
> break x;
> end if;
> end for;
> end for;
46 89
Note that break instead of break x would have broken only
out of the inner loop; the output in that case would have been:
46 89
89 46
[Next][Prev] [Right] [Left] [Up] [Index] [Root]
|