Note: This page has been translated by MathWorks. Please click here

To view all translated materals including this page, select Japan from the country navigator on the bottom of this page.

To view all translated materals including this page, select Japan from the country navigator on the bottom of this page.

Substitution depth of identifiers

**MuPAD® notebooks are not recommended. Use MATLAB® live scripts instead.**

**MATLAB live scripts support most MuPAD functionality, though there are some differences. For more information, see Convert MuPAD Notebooks to MATLAB Live Scripts.**

The environment variable `LEVEL`

determines
the maximal substitution depth of identifiers.

Possible values: a positive integer smaller
than 2^{31}.

When a MuPAD^{®} object is evaluated, identifiers occurring
in it are replaced by their values. This happens recursively, i.e.,
if the values themselves contain identifiers, then these are replaced
as well. `LEVEL`

determines the maximal recursion
depth of this process.

Technically, evaluation of a MuPAD object works as follows. For a compound object, usually first the operands are evaluated recursively, and then the object itself is evaluated. E.g., if the object is a function call with arguments,the arguments are evaluated first, and then the function is executed with the evaluated arguments.

With respect to the evaluation of identifiers,
the *current substitution depth* is recorded internally.
Initially, this value is zero. If an identifier is encountered during
the recursive evaluation process as described above and the current
substitution depth is smaller than `LEVEL`

, then
the identifier is replaced by its value, the current substitution
depth is increased by one, and evaluation proceeds recursively with
the value of the identifier. After the identifier has been evaluated,
the current substitution depth is reset to its previous value. If
the current substitution depth equals `LEVEL`

, however,
then the recursion stops and the identifier remains unevaluated.

The default value of `LEVEL`

at interactive
level is `100`

. However, the default value of `LEVEL`

within
a procedure is `1`

.
Then an identifier is only replaced by its value, which is not evaluated
recursively.

The value of `LEVEL`

may be changed within
a procedure, but it is reset to `1`

each time a new
procedure is entered. After the procedure returns, `LEVEL`

is
reset to its previous value. See Example 3.

The evaluation of local variables and formal parameters of procedures, of type `DOM_VAR`

, is not affected
by `LEVEL`

: they are always evaluated with substitution
depth `1`

. This means that a local variable or a
formal parameter is replaced by its value when evaluated, but the
value is not evaluated further.

See Example 3.

`LEVEL`

does not affect the evaluation of arrays, tables and polynomials.

See Example 4.

The function `eval`

evaluates
its argument with substitution depth given by `LEVEL`

,
and then evaluates the result again with the same substitution depth.

The call `level(object, n)`

evaluates its
argument with substitution depth `n`

, independent
of the value of `LEVEL`

.

If, during evaluation, the substitution depth `MAXLEVEL`

,
is reached, then the evaluation is terminated with an error. This
is a heuristic for recognizing recursive definitions, as in the example ```
delete
a; a := a + 1; a
```

. Here, `a`

would be replaced
by `a + 1`

infinitely often. Note that this has no
effect if `MAXLEVEL`

is
greater than `LEVEL`

. The default value of `MAXLEVEL`

is `100`

,
i.e., it is equal to the default value of `LEVEL`

at
interactive level. However, unlike `LEVEL`

, `MAXLEVEL`

is
not changed within a procedure, and
hence recursive definitions are usually not recognized within procedures.
See the help page of `MAXLEVEL`

for examples.

The default value of `LEVEL`

is `100`

at
interactive level; `LEVEL`

has this value after starting
or resetting the system via `reset`

.
Within a procedure, the default value is `1`

.
The command `delete LEVEL`

restores the default value.

We demonstrate the effect of various values of `LEVEL`

at
interactive level:

delete a0, a1, a2, a3, a4, b: b := b + 1: a0 := a1: a1 := a2 + 2: a2 := a3 + a4: a3 := a4^2: a4 := 5:

LEVEL := 1: a0, a0 + a2, b; LEVEL := 2: a0, a0 + a2, b; LEVEL := 3: a0, a0 + a2, b; LEVEL := 4: a0, a0 + a2, b; LEVEL := 5: a0, a0 + a2, b; LEVEL := 6: a0, a0 + a2, b; delete LEVEL:

In the following calls, the identifier `a`

is
fully evaluated:

delete a, b, c: a := b: b := c: c := 7: a

After assigning the value `2`

to `LEVEL`

, `a`

is
evaluated only with depth two:

LEVEL := 2: a; delete LEVEL:

If we set `MAXLEVEL`

to `2`

as well,
evaluation of `a`

produces an error, although there
is no recursive definition involved:

LEVEL := 2: MAXLEVEL := 2: a

Error: Recursive definition: Reached maximal evaluation level.

delete LEVEL, MAXLEVEL:

This example shows the difference between the evaluation of identifiers and local
variables. By default, the value of `LEVEL`

is `1`

within
a procedure, i.e., a global identifier is replaced by its value when
evaluated, but there is no further recursive evaluation. This changes
when `LEVEL`

is assigned a bigger value inside the
procedure:

delete a0, a1, a2, a3: a0 := a1 + a2: a1 := a2 + a3: a2 := a3^2 - 1: a3 := 5: p := proc() save LEVEL; begin print(a0, eval(a0)): LEVEL := 2: print(a0, eval(a0)): end_proc:

p()

In contrast, evaluation of a local variable replaces it by its
value, without further evaluation. When `eval`

is applied to an object containing
a local variable, then the effect is an evaluation of the value of
the local variable with substitution depth `LEVEL`

:

q := proc() save LEVEL; local x; begin x := a0: print(x, eval(x)): LEVEL := 2: print(x, eval(x)): end_proc: q()

The command `x:=a0`

assigns the value of the
identifier `a0`

, namely the unevaluated expression `a1+a2`

,
to the local variable `x`

, and `x`

is
replaced by this value every time it is evaluated, independent of
the value of `LEVEL`

.

`LEVEL`

does not affect on evaluation of `polynomials`

:

delete a, x: p := poly(a*x, [x]): a := 2: x := 3: p, eval(p); LEVEL := 1: p, eval(p); delete LEVEL:

The same is true for `arrays`

and `tables`

:

delete a, b: A := array(1..2, [a, b]): T := table(a = b): a := 1: b := 2: A, eval(A), T, eval(T); LEVEL := 1: A, eval(A), T, eval(T); delete LEVEL:

Was this topic helpful?