再会,
当试图通过使用标准Trace
和TraceScan
命令以及最近thread中开发的漂亮可视表示法来理解Mathematica的评估顺序时,我在行为上遇到了一些歧义。
首先,当我评估
我懂了
所有子列表都对应于子评估(如文档中所述)。最后一个表达式1+a
可能对应于评估结果,尽管在文档中没有明确说明。但是,列表中间的表达式a+1
和1+a
到底是什么意思呢?它们对应于the standard evaluation sequence的哪些评估步骤?
第二个奇怪之处是TraceScan
。考虑以下:
您可以看到列表中的最后两个表达式是1+a
和a+1
。两者都是(子)评估的结果。但是实际输出是1+a
,所以我不明白为什么a+1
在评估链的末尾?为何在评估链中间没有a+1
呢(就像Trace
一样)?是 bug 吗?
P.S.这些结果在Mathematica 7.0.1和5.2中得以再现。
最佳答案
fp
的TraceScan
参数由两个参数调用。第一个是原始未评估的表达式。第二是评估结果。在您的示例中,第二个AppendTo
使用第一个参数,因此您看到的是未评估的表达式。将#
更改为#2
,然后您将看到期望的结果。
还要注意,第二个参数没有包装在HoldForm
中(尽管有文档说明),因此通常来说,必须小心使用为fp
参数保留其参数的函数,以免产生虚假评估。
比较Trace和TraceScan
Mathematica 8 documentation中详细描述了Trace
的行为。它指出,默认情况下,Trace
仅在计算了头和参数之后才显示表达式。因此,我们看到这样的序列:
In[28]:= SetAttributes[f, Orderless]
Trace[f[a, 1]]
Out[29]= {f[a,1],f[1,a]}
仅显示输入表达式及其结果。
TraceOriginal
选项控制(引用)“是否在计算表达式的头部和参数之前先查看表达式”。当此选项为True
时,输出将补充有head和arguments表达式:In[30]:= Trace[f[a,1], TraceOriginal->True]
Out[30]= {f[a,1],{f},{a},{1},f[a,1],f[1,a]}
新列表的第一个元素是在计算head和arguments之前的原始表达式。然后,我们看到头和参数正在评估。最后,在对head和arguments求值之后,我们再次看到顶级表达式。列表的最后两个元素与原始跟踪输出的两个元素匹配。
如链接的文档所述,
Trace
对于返回的表达式非常有选择性。例如,它完全忽略了琐碎的评估链。 TraceScan
是全面的,它会为每个评估(不管是否微不足道)调用提供的函数。您可以使用以下TraceScan
表达式查看全面的评估集:TraceScan[Print, f[a,1], _, Print[{##}]&]
下表将
Trace
生成的带有TraceOriginal
和不带有TraceScan
的输出与Trace
表达式的输出进行匹配:Trace Trace TraceScan
Original
f[a,1] f[a,1]
f
{f} {f
,f}
a
{a} {a
,a}
1
{1} {1
,1}
f[1,a]
{f[1,a]
,f[1,a]}
f[a,1] f[a,1] {f[a,1]
f[1,a] f[1,a] ,f[1,a]}
鉴于
Trace
的内部是不可访问的,因此在此表中有一定的推测,关于哪个条目与哪个条目匹配。进一步的实验可能会提供调整对齐方式的信息。但是,关键是TraceScan
生成的所有信息都可以通过TraceScan
获得,而ojit_code提供了更多信息。关于wolfram-mathematica - 了解跟踪*,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5562126/