Глубина замены идентификаторов
Блокноты MuPAD® будут демонтированы в будущем релизе. Используйте live скрипты MATLAB® вместо этого.
Live скрипты MATLAB поддерживают большую часть функциональности MuPAD, хотя существуют некоторые различия. Для получения дополнительной информации смотрите, Преобразовывают Notebook MuPAD в Live скрипты MATLAB.
Переменная окружения LEVEL
определяет максимальную глубину замены идентификаторов.
Возможные значения: положительное целое число, меньшее, чем 231.
Когда объект MuPAD® оценен, идентификаторы, происходящие в нем, заменяются их значениями. Это происходит рекурсивно, т.е. если сами значения содержат идентификаторы, то они заменяются также. LEVEL
определяет максимальную глубину рекурсии этого процесса.
Технически, оценка объекта MuPAD работает можно следующим образом. Для составного объекта обычно сначала операнды оценены рекурсивно, и затем сам объект оценен. Например, если объект является вызовом функции с аргументами, аргументы оценены сначала, и затем функция выполняется с оцененными аргументами.
Относительно оценки идентификаторов текущая глубина замены зарегистрирована внутренне. Первоначально, это значение является нулем. Если с идентификатором сталкиваются во время рекурсивного процесса оценки, как описано выше, и текущая глубина замены меньше, чем LEVEL
, то идентификатор заменяется его значением, текущая глубина замены увеличена одной и доходами оценки рекурсивно со значением идентификатора. После того, как идентификатор был оценен, текущая глубина замены сбрасывается к ее предыдущему значению. Если текущая глубина замены равняется LEVEL
, однако, то остановки рекурсии и идентификатор остаются неоцененными.
Значением по умолчанию LEVEL
на интерактивном уровне является 100
. Однако значением по умолчанию LEVEL
в рамках процедуры является 1
. Затем идентификатор только заменяется его значением, которое не оценено рекурсивно.
Значение LEVEL
может быть изменено в рамках процедуры, но это сбрасывается к 1
каждый раз, когда новая процедура вводится. После того, как процедура возвращается, LEVEL
сбрасывается к его предыдущему значению. Смотрите Пример 3.
Оценка локальных переменных и формальные параметры процедур, типа DOM_VAR
, не затронуты LEVEL
: они всегда оцениваются с глубиной замены 1
. Это означает, что локальная переменная или формальный параметр заменяются его значением, когда оценено, но значение не оценено далее.
Смотрите пример 3.
Смотрите пример 4.
Функциональный eval
оценивает свой аргумент с глубиной замены, данной LEVEL
, и затем оценивает результат снова с той же глубиной замены.
Вызов level(object, n)
оценивает свой аргумент с глубиной замены n
, независимый от значения LEVEL
.
Если, во время оценки, глубина замены MAXLEVEL
, достигнут, то оценка отключена с ошибкой. Это - эвристика для распознавания рекурсивных определений, как в примере delete a; a := a + 1; a
. Здесь, a
заменялся бы a + 1
бесконечно часто. Обратите внимание на то, что это не имеет никакого эффекта, если MAXLEVEL
больше, чем LEVEL
. Значением по умолчанию MAXLEVEL
является 100
, т.е. это равно значению по умолчанию LEVEL
на интерактивном уровне. Однако различающийся LEVEL
, MAXLEVEL
не изменяется в рамках процедуры, и следовательно рекурсивные определения обычно не распознаются в рамках процедур. Смотрите страницу справки MAXLEVEL
для примеров.
Значением по умолчанию LEVEL
является 100
на интерактивном уровне; LEVEL
имеет это значение после запуска или сброса системы через reset
. В рамках процедуры значением по умолчанию является 1
. Команда delete LEVEL
восстанавливает значение по умолчанию.
Мы демонстрируем эффект различных значений 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:
В следующих вызовах идентификатор полностью оценен a
:
delete a, b, c: a := b: b := c: c := 7: a
После присвоения значения 2
к LEVEL
a
оценен только с глубиной два:
LEVEL := 2: a; delete LEVEL:
Если мы устанавливаем MAXLEVEL
на 2
также, оценка a
производит ошибку, несмотря на то, что нет никакого рекурсивного включенного определения:
LEVEL := 2: MAXLEVEL := 2: a
Error: Recursive definition: Reached maximal evaluation level.
delete LEVEL, MAXLEVEL:
Этот пример показывает различие между оценкой идентификаторов и локальными переменными. По умолчанию значением LEVEL
является 1
в рамках процедуры, т.е. глобальный идентификатор заменяется его значением, когда оценено, но нет никакой дальнейшей рекурсивной оценки. Это изменяется, когда LEVEL
присвоен большее значение в процедуре:
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()
Напротив, оценка локальной переменной заменяет его своим значением без дальнейшей оценки. Когда eval
применяется к объекту, содержащему локальную переменную, затем эффект является оценкой значения локальной переменной с глубиной замены LEVEL
:
q := proc() save LEVEL; local x; begin x := a0: print(x, eval(x)): LEVEL := 2: print(x, eval(x)): end_proc: q()
Команда x:=a0
присваивает значение идентификатора a0
, а именно, неоцененное выражение a1+a2
, к локальной переменной x
и x
, заменяется этим значением каждый раз, когда это оценено, независимо от значения LEVEL
.
LEVEL
не влияет на оценке polynomials
:
delete a, x: p := poly(a*x, [x]): a := 2: x := 3: p, eval(p); LEVEL := 1: p, eval(p); delete LEVEL:
То же самое верно для arrays
и 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: