Во-первых, я думаю, что вы выявили ошибку здесь.
Во-вторых, я думаю, что могу дать некоторое представление о том, почему это происходит, имея в виду, что мои знания о внутренностях математики ограничены.
Оператор, подобный следующему: f [z_]: = 2 z в полной форме:
SetDelayed[f[Pattern[z, Blank[]]], 2 z]
Это устанавливает для DownValue [f] значение:
{HoldPattern[f[z_]] :> 2 z}
Затем позжекогда выражение, такое как f [2], позже оценивается, выполняется предварительное формирование, например, следующее:
f[2] /. HoldPattern[f[z_]] :> 2 z
, что будет равно 4. Теперь это все возможно, потому что сопоставление с образцом происходит с Pattern [z, Пробел []] из первого блока кода.Это работает, даже если вы очевидно установили z на число.Другими словами.
z = 5;
f[z_] := 2*z
Тем не менее выдает те же значения понижений для f:
{HoldPattern[f[z_]] :> 2 z}
Это возможно, поскольку Pattern имеет атрибут HoldFirst.
Атрибут HoldFirst имеет значениенедостаточно защиты, если вы оцените это внутри модуля.Пример:
SetAttributes[tmp, HoldFirst];
Module[{expr},
expr = 2 z;
tmp[expr]
]
выводит:
tmp[expr$8129]
Я предлагаю, так как атрибут HoldFirst не обеспечивает иммунитета к правилу перезаписи переменных модуля, что любой шаблон в правиле, содержащий локальную переменную, имеет своиПеременные шаблона переписаны.sym-> Symbol [SymbolName [sym] ~~ "$"]
Module[{expr},
Hold[z_ -> (z; expr)]
]
(*Hold[z$_ -> (z$; expr$1391)]*)
z переписано с обеих сторон правила простым альфа-преобразованием.
Если правило делаетне содержит локальную переменную, перезапись не происходит:
Module[{expr},
Hold[z_ -> (z)]
]
(*Hold[z_ -> z]*)
Вместо того, чтобы искать, соответствует ли локальная переменная переменной правила, применяется указанное выше общее правило.
Таким образом, проблема в том, чтолокальный expr не оценивается до того, как произойдет альфа-преобразование.Или, возможно, еще лучше было бы заключить expr в лениво вычисленное альфа-преобразование, которое потребуется для RuleDelayed.
Этого не происходит в блоке, поскольку блок не переписывает ни одну из локальных переменных.
Есть еще идеи?Кто-нибудь видит дыры в моей логике?