Substitution depth of identifiers
The environment variable
the maximal substitution depth of identifiers.
Possible values: a positive integer smaller than 231.
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
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
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
then the recursion stops and the identifier remains unevaluated.
The default value of
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,
reset to its previous value. See Example 3.
The evaluation of local variables and formal parameters of procedures, of type
See Example 3.
See Example 4.
its argument with substitution depth given by
and then evaluates the result again with the same substitution depth.
level(object, n) evaluates its
argument with substitution depth
of the value of
If, during evaluation, the substitution depth
is reached, then the evaluation is terminated with an error. This
is a heuristic for recognizing recursive definitions, as in the example
a; a := a + 1; a. Here,
a would be replaced
a + 1 infinitely often. Note that this has no
LEVEL. The default value of
i.e., it is equal to the default value of
interactive level. However, unlike
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 has this value after starting
or resetting the system via
Within a procedure, the default value is
delete LEVEL restores the default value.
We demonstrate the effect of various values of
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
delete a, b, c: a := b: b := c: c := 7: a
After assigning the value
evaluated only with depth two:
LEVEL := 2: a; delete LEVEL:
If we set
2 as well,
a produces an error, although there
is no recursive definition involved:
LEVEL := 2: MAXLEVEL := 2: a
Error: Recursive definition, the maximal evaluation level is reached.
delete LEVEL, MAXLEVEL:
This example shows the difference between the evaluation of identifiers and local
variables. By default, the value of
a procedure, i.e., a global identifier is replaced by its value when
evaluated, but there is no further recursive evaluation. This changes
LEVEL is assigned a bigger value inside the
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:
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
q := proc() save LEVEL; local x; begin x := a0: print(x, eval(x)): LEVEL := 2: print(x, eval(x)): end_proc: q()
x:=a0 assigns the value of the
a0, namely the unevaluated expression
to the local variable
replaced by this value every time it is evaluated, independent of
the value of
LEVEL does not affect on evaluation of
delete a, x: p := poly(a*x, [x]): a := 2: x := 3: p, eval(p); LEVEL := 1: p, eval(p); delete LEVEL:
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: