美好的一天,
当尝试使用标准 Trace
和 TraceScan
命令及其最近开发的漂亮的视觉表示来理解Mathematica的评估序列时线程,我在他们的行为中遇到了一些含糊之处。
首先,当我评估时
In[1]:= Trace[a+1,TraceOriginal->True]
我得到
输出[1]=
{a+1,{加},{a},{1},a+1,1+a,{加},{1},{a},1+a}
所有子列表都对应于子评估(如文档中有说明)。最后一个表达式1+a
可能对应于评估的结果,尽管文档中没有明确说明。但是列表中间的表达式 a+1
和 1+a
究竟意味着什么?它们对应于标准评估序列的哪些评估步骤?
第二个奇怪之处是 TraceScan
。考虑以下几点:
In[1]:= 列表={}; TraceScan[AppendTo[列表,StyleForm[#,"输入"]]&,(a+1),_,AppendTo[列表,#]&];列表
输出[1]=
{a+1、加、加、a、a、1、1、1+ a、加、加、1、1、a、a、1+a、a+1}
可以看到列表中的最后两个表达式是 1+a
和 a+1
。两者都是(子)评估的结果。但真正的输出是 1+a
所以我不明白为什么 a+1
位于评估链的末尾?为什么评估链中间没有 a+1
,就像 Trace
的情况一样?这是一个错误吗?
PS 这些结果使用 Mathematica 7.0.1 和 5.2 重现。
Good day,
When trying to understand the Mathematica's evaluation sequence by using standard Trace
and TraceScan
commands and their nice visual representations developed in the recent thread, I faced some ambiguities in their behavior.
First of all, when I evaluate
In[1]:= Trace[a+1,TraceOriginal->True]
I get
Out[1]=
{a+1,{Plus},{a},{1},a+1,1+a,{Plus},{1},{a},1+a}
All sublists correspond to sub-evaluations (as it is stated in the Documentation). The last expression 1+a
probably corresponds to the result of the evaluation although it is not clearly stated in the Documentation. But what exactly mean expressions a+1
and 1+a
in the middle of the list? To which evaluation steps of the standard evaluation sequence they correspond?
The second oddity is with TraceScan
. Consider the following:
In[1]:= list={}; TraceScan[AppendTo[list,StyleForm[#,"Input"]]&,(a+1),_,AppendTo[list,#]&]; list
Out[1]=
{a+1, Plus, Plus, a, a, 1, 1, 1+a, Plus, Plus, 1, 1, a, a, 1+a, a+1}
You can see that the last two expressions in the list are 1+a
and a+1
. Both are results of (sub)evaluations. But the real output is 1+a
and so I do not understand why a+1
is at the end of the evaluation chain? And why is no there a+1
in the middle of the evaluation chain as it was in the case of Trace
? Is it a bug?
P.S. These results are reproduced with Mathematica 7.0.1 and 5.2.
发布评论
评论(2)
TraceScan
的fp
参数是用两个参数调用的。第一个是原始的未计算表达式。二是评估结果。在您的示例中,第二个AppendTo
使用第一个参数,因此您将看到未计算的表达式。将#
更改为#2
,然后您将看到您期望的结果。另请注意,第二个参数未包含在
HoldForm
中(尽管有文档),因此通常必须小心使用保存其参数的函数fp
参数以避免生成虚假评估。比较 Trace 和 TraceScan
Trace 的行为进行了相当详细的描述。 html" rel="nofollow">Mathematica 8 文档。它指出,默认情况下,
Trace
仅在计算头部和参数之后显示表达式。因此,我们看到这样的序列:仅显示输入表达式及其结果。
TraceOriginal
选项控制(引用)“是否在计算头和参数之前查看表达式”。当此选项为 True 时,输出将补充头部和参数表达式:新列表的第一个元素是计算头部和参数之前的原始表达式。然后我们看到头部和参数正在被评估。最后,在计算头和参数之后,我们再次看到顶级表达式。列表的最后两个元素与原始跟踪输出的两个元素匹配。
正如链接文档所述,
Trace
对于返回的表达式非常有选择性。例如,它完全省略了琐碎的评估链。TraceScan
非常全面,它会为每次评估(无论是否琐碎)调用所提供的函数。您可以使用以下TraceScan
表达式查看完整的评估集:下表将使用和不使用
TraceOriginal
时Trace
生成的输出与与TraceScan
表达式的输出:鉴于
Trace
的内部无法访问,此表中存在一定程度的关于哪个条目与哪个条目匹配的猜测。进一步的实验可能会提供调整对齐的信息。然而,关键是Trace
生成的所有信息都可以使用TraceScan
获得,而且TraceScan
还提供更多信息。The
fp
argument toTraceScan
is called with two arguments. The first is the original unevaluated expression. The second is the result of the evaluation. In your example, the secondAppendTo
is using the first argument so you are seeing the unevaluated expression. Change#
to#2
and then you will see the results you expect.Also note that the second argument is not wrapped in
HoldForm
(documentation notwithstanding), so in general one must take care to use a function that holds its arguments for thefp
argument to avoid generating spurious evaluations.Comparing Trace and TraceScan
The behaviour of
Trace
is described in considerable detail in the Mathematica 8 documentation. It states that, by default,Trace
only shows expressions after the head and arguments have been evaluated. Thus, we see a sequence like this:Only the input expression and its result is shown. The
TraceOriginal
options controls (quote) "whether to look at expressions before their heads and arguments are evaluated". When this option isTrue
then the output is supplemented with the head and argument expressions:The first element of the new list is the original expression before the head and arguments are evaluated. Then we see the head and arguments being evaluated. Finally, we see the top-level expressions again, after the head and arguments have been evaluated. The last two elements of the list match the two elements of the original trace output.
As the linked documentation states,
Trace
is very selective about what expressions it returns. For example, it omits trivial evaluation chains completely.TraceScan
is comprehensive and calls the supplied functions for every evaluation, trivial or not. You can see the comprehensive set of evaluations using the followingTraceScan
expression:The following table matches the output produced by
Trace
with and withoutTraceOriginal
, along with the output of theTraceScan
expression:There is certain amount of speculation in this table about which entry matches against which, given that the internals of
Trace
are inaccessible. Further experiments might give information that adjusts the alignment. However, the key point is that all of the information generated byTrace
is available usingTraceScan
-- andTraceScan
provides more.问题的第一部分很简单。
列表中间的表达式
a+1
和1+a
是Plus
的Orderless
属性所在的位置火灾和术语按默认顺序排列。这是标准评估序列中的第 8 点。
TraceScan
中的“奇怪之处”也出现在版本 8 中。因为这是一个罕见的命令,这里是
TraceScan
的文档请注意,如果将其应用于表达式
a + 1 + b
,您将得到From here,很清楚发生了什么。fp 实际上对应于第一个
fp
在评估之后应用 - 因此最终的f
。它直到最后才打印,因为需要首先计算子表达式。The first part of the question is easy.
The expressions
a+1
and1+a
in the middle of the list are where theOrderless
attribute ofPlus
fires and the terms are arranged in the default order.This is point number 8 in the standard evaluation sequence tute.
The "strangeness" in
TraceScan
also occurs in version 8.Because, it's a rare command, here's the documentation for
TraceScan
Note that if you apply it to the expression
a + 1 + b
you getFrom here, it's clear what's happening.
fp
applies after the evaluation - so the finalfp
actually corresponds to the firstf
. It doesn't print until the very end because the subexpressions need to be evaluated first.