## Documentation Center |

On this page… |
---|

The value of an identifier can contain arbitrary MuPAD^{®} objects,
including identifiers. If the value of an identifier contains another
identifier, MuPAD tries to find the value of that second identifier.
If the value of that second identifier also contains identifiers, MuPAD tries
to find their values, and so on. Typically, evaluation continues until
the system replaces all identifiers that have values by these values.
The final result can contain identifiers that do not have assigned
values. This recursive evaluation process is called a *complete
evaluation*. Each evaluation step in this recursive process
is an evaluation level. For example, evaluate the value of the identifier `y`:

y := a + x: a := 1: y

The resulting expression `x + 1` is the complete
evaluation of `y`. The `level` function demonstrates
each step of this recursive evaluation. The zero level of evaluation
returns the identifier `y` itself:

level(y, 0)

The first level accesses the value of the identifier, and returns that value:

level(y, 1)

When you evaluate `y` up to the second level,
the system recognizes that the expression `x + a` contains
identifiers, which can also have assigned values. When searching for
these values, the system finds that the identifier `a` has
the value 1, and the identifier `x` does not have
an assigned value:

level(y, 2)

In this example, MuPAD completely evaluates the identifier `y` by
using just two evaluation steps. Evaluating `y` up
to the third and higher levels returns the same expression:

level(y, 3)

delete a, x, y

MuPAD does not always evaluate identifiers completely.
For some expressions, a complete evaluation requires a huge number
of steps. To avoid very long or infinite evaluations, the system implements
two environment variables, `LEVEL` and `MAXLEVEL`. These variables
limit evaluation levels. If the current evaluation level exceeds the
limitation set by one these variables, MuPAD stops the evaluation
process before the system can replace all identifiers by their assigned
values.

The environment variable `LEVEL` limits evaluation levels to a specified
value. It does not try to detect and prevent an infinite evaluation
loop. For interactive computations, the default value of the environment
variable `LEVEL` is:

LEVEL

When the evaluation level reaches the value of `LEVEL`, MuPAD stops
the evaluation and returns the result of the last computed evaluation
step:

LEVEL := 10: x := x + 1: x

delete LEVEL, x

MuPAD does not specify one uniform value of `LEVEL` for
all computations. For most computations, the value is 100, but there
are exceptions to this rule:

If the evaluation occurs in a procedure, MuPAD limits the evaluation level to 1.

If the evaluation occurs in a matrix, MuPAD limits the evaluation level to 1.

MuPAD does not evaluate arrays, tables, and polynomials. (The evaluation level for these objects is 0.)

MuPAD does not evaluate a returned value of the

`last()`function call or its equivalent`%`. (The evaluation level is 0.)MuPAD does not evaluate returned values of some other system functions. For example, the system does not evaluate the results returned by the

`subs`and`text2expr`functions. The help pages for such functions provide the information about the evaluation levels of the returned values.If the evaluation occurs in a function call

`level(expression, n)`, MuPAD disregards the environment value`LEVEL`. Instead, the system uses the evaluation level`n`.

For example, although `LEVEL = 100` by
default, the function call `level(a + x, 1)` evaluates
the expression `a + x` to the first evaluations
level:

a := b: b := 2: level(a + x, 1)

delete a, b, x

For more examples of incomplete evaluations and information about enforcing such evaluations, see Enforcing Evaluation.

To detect and prevent infinite loops, MuPAD implements
another environment variable, `MAXLEVEL`. The default value of `MAXLEVEL` for
all computations is

MAXLEVEL

When evaluation level reaches the value of `MAXLEVEL`, MuPAD assumes
that the evaluation is infinite and issues an error:

MAXLEVEL := 2: a := b: b := c: c := d: a

Error: Recursive definition. [See ?MAXLEVEL]

delete MAXLEVEL, a, b, c, d

If the value of `MAXLEVEL` is greater than the value of `LEVEL`,
the global variable `MAXLEVEL` does not affect that evaluation.
Otherwise, the value of `MAXLEVEL` limits the number of evaluation
steps. For example, the default values of `LEVEL` and `MAXLEVEL` are
equal (both values are 100). If an evaluation reaches the level 100, MuPAD uses
the global variable `MAXLEVEL` and, therefore, issues an error:

x := x + 1: x

Error: Recursive definition. [See ?MAXLEVEL]

delete x

You can change the values of the environment variables `LEVEL` and `MAXLEVEL`.
For example, the following equations define the identifiers *x*_{k} recursively:

(x[k] := (k + 1)*x[k + 1]) $ k = 1..9: x[10] := 10:

Using the `level` function, evaluate the identifier *x*_{1} to
the levels from 1 to 10. For this identifier, the level 10 returns
the complete evaluation:

for l from 0 to 10 do print(level = l, hold(x[1]) = level(x[1], l)) end_for

Since the default value of the environment value `LEVEL
= 100` is greater than 10, in interactive computations MuPAD returns
the completely evaluated identifier *x*_{1}:

x[1]

Delete the identifiers *x*_{k}:

delete x

Set the value of the environment variable `LEVEL` to 2:

LEVEL := 2:

Now, MuPAD evaluates the identifier *x*_{1} only
up to the second level:

(x[k] := (k + 1)*x[k + 1]) $ k = 1..9: x[10] := 10: x[1]

The new value of `LEVEL` affects all interactive evaluations,
except for evaluations in arrays, matrices, tables, and polynomials.
For example, use the following recursive definition for the identifiers `a`, `b`,
and `c`. Evaluation of the identifier `a` proceeds
only to the second level:

a := b: b := c: c := 1: a

For further computations, delete the identifiers:

delete x, a, b, c:

The new value of `LEVEL` does not affect evaluations that
happen in procedures. The evaluation level in procedures remains equal
to 1. For example, create the procedure `myProc` that
defines the values of the identifiers `a`, `b`,
and `c` recursively:

myProc:= proc(d) begin a := b: b := c: c := d: a end_proc:

The procedure evaluates the identifier `a` up
to the first evaluation level:

myProc(10)

delete a, b, c, d:

You can change the evaluation level inside a particular procedure. This change does not affect evaluations occuring in other procedures or inside interactive computations:

myProc:= proc(d) begin LEVEL := 3: a := b: b := c: c := d: a end_proc: myProc(10)

For further computations, delete the identifiers and restore
the value of `LEVEL` to
its default:

delete a, b, c, d: delete LEVEL:

Another environment variable, `MAXLEVEL` enables the
system to detect and interrupt infinite evaluation loops. The default
value of this variable is 100. This value is recommended for most
computations. If your code has recursive evaluations that require
more than 99 steps, change the value of `MAXLEVEL`. For example,
the following definition of the identifier *x*_{1} requires
111 evaluation steps. MuPAD issues an error because the system
cannot evaluate *x*_{1} in
99 steps and assumes that the evaluation loop is infinite:

(x[k] := (k + 1)*x[k + 1]) $ k = 1..110: x[111] := 1: x[1]

Error: Recursive definition. [See ?MAXLEVEL]

delete x

To avoid the error, the value of `MAXLEVEL` must exceed
the number of required evaluation steps at least by 1. Changing the
value to 112 resolves the error. Now, MuPAD evaluates the identifier *x*_{1} to
the 100th evaluation level, which is the default value of the environment
variable `LEVEL`:

MAXLEVEL:= 112: (x[k] := (k + 1)*x[k + 1]) $ k = 1..110: x[111] := 1: x[1]

delete x

To evaluate *x*_{1} to
the 111th evaluation level, you must change both `LEVEL` and `MAXLEVEL` variables.
Also, you can use the `level` function instead of changing the
value of `LEVEL`:

MAXLEVEL:= 112: (x[k] := (k + 1)*x[k + 1]) $ k = 1..110: x[111] := 1: level(x[1], 111)

Increase the value of `MAXLEVEL` only when you know that your
code requires it. Do not increase this value for computations where
you can avoid it. If your code has infinite loops, the increased level
of `MAXLEVEL` can
significantly decrease performance. Always restore the default value
for further computations:

delete x, MAXLEVEL

Was this topic helpful?