再会,

当试图通过使用标准TraceTraceScan命令以及最近thread中开发的漂亮可视表示法来理解Mathematica的评估顺序时,我在行为上遇到了一些歧义。

首先,当我评估



我懂了



所有子列表都对应于子评估(如文档中所述)。最后一个表达式1+a可能对应于评估结果,尽管在文档中没有明确说明。但是,列表中间的表达式a+11+a到底是什么意思呢?它们对应于the standard evaluation sequence的哪些评估步骤?

第二个奇怪之处是TraceScan。考虑以下:



您可以看到列表中的最后两个表达式是1+aa+1。两者都是(子)评估的结果。但是实际输出是1+a,所以我不明白为什么a+1在评估链的末尾?为何在评估链中间没有a+1呢(就像Trace一样)?是 bug 吗?

P.S.这些结果在Mathematica 7.0.1和5.2中得以再现。

最佳答案

fpTraceScan参数由两个参数调用。第一个是原始未评估的表达式。第二是评估结果。在您的示例中,第二个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/

10-11 06:36