# Iterative Statements

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](../../SetsSequencesMappings/Sequences/index-sequences.md#chapseq).) Early termination of the body of loop may be specified through use of the ‘jump’ commands `break` and `continue`.

## Definite Iteration

### `for i := expr₁ to expr₂ by expr₃ do`

### `for i := expr₁ to expr₂ 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\cdot s$ will be assigned to `i`, and the statements executed, for $k=0, 1, 2, \ldots$ in succession, as long as $b+k\cdot s \le e$ (for $e>0$) or $b+k\cdot s \ge e$ (for $e<0$).

In the second form above, where the step size is omitted, it is taken to be 1.

### `for x in S do
    statements
end for;`

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.

## Indefinite Iteration

### `while Boolean expression do
    statements
end while;`

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.

### `Example: while (ex-9a6f96)`

The following short program implements a run of the famous $3x+1$ problem on a random integer between 1 and 100.

```magma
> 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

```

### `repeat
    statements
until Boolean expression;`

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.

### `Example: repeat (ex-bdac72)`

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`.

```magma
> 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 random x in S do
    statements
end for;`

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.

## Dual Iteration

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.

### `for i -> x in S do
    statements
end for;`

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 random i -> x in S do
    statements
end for;`

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.

## Early Exit from Iterative Statements

### `continue;`

The `continue` statement can be used to jump to the end of the innermost enclosing loop: the termination condition for the loop is checked immediately.

### `continue identifier;`

As in the case of `break`, this allows jumps out of nested `for` loops: the termination condition of the loop with loop variable identifier is checked immediately after `continue identifier` is encountered.

### `break;`

A `break` inside a loop causes immediate exit from the innermost enclosing loop.

### `break identifier;`

In nested `for` loops, this allows breaking out of several loops at once: this will cause an immediate exit from the loop with loop variable identifier.

### `Example: break (ex-c95fc5)`

```magma
> 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:

```magma
46 89
89 46

```
