Documentation |
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, the maximal evaluation level is reached.
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, the maximal evaluation level is reached.
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 occurring 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, the maximal evaluation level is reached.
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