美好的一天,
当尝试使用标准Trace
和TraceScan
命令以及最近thread中开发的漂亮视觉表示来理解 Mathematica 的评估序列时,我的行为面临一些模棱两可的问题。
首先,当我评估时
在[1]中:=跟踪[a + 1,TraceOriginal-> True]
我得到了
输出[1] = {A + 1,{加},{A},{1}中,+ 1,1 + A,{加},{1},{A},1 +α}
所有子列表都对应于子评估(如文档中所述)。最后一个表达式1+a
可能对应于评估结果,尽管文档中没有明确说明。但是在列表中间究竟表达a+1
和1+a
的确切含义是什么?它们对应的the standard evaluation sequence评估步骤是什么?
第二个奇怪的是TraceScan
。请考虑以下事项:
在[1]中:= list = {}; 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
?这是一个错误吗?
P.S。这些结果用 Mathematica 7.0.1和5.2再现。
答案 0 :(得分:3)
问题的第一部分很简单。
列表中间的表达式a+1
和1+a
是Orderless
的{{1}}属性触发,并且这些字词按默认顺序排列。
这是standard evaluation sequence tute中的第8点。
Plus
中的“陌生感”也出现在版本8中。
因为,这是一个罕见的命令,这里是TraceScan
TraceScan [f,expr,form,fp]适用于f 在评估之前和fp之后 对表达中使用的表达式的评估 评估expr。
请注意,如果您将其应用于表达式TraceScan
,则会获得
a + 1 + b
从这里开始,很明显发生了什么。评估后适用In[32]:= TraceScan[Print["f \t",#]&, a+1+b, _, Print["fp\t",#]&]
During evaluation of In[32]:= f a+1+b
During evaluation of In[32]:= f Plus
During evaluation of In[32]:= fp Plus
During evaluation of In[32]:= f a
During evaluation of In[32]:= fp a
During evaluation of In[32]:= f 1
During evaluation of In[32]:= fp 1
During evaluation of In[32]:= f b
During evaluation of In[32]:= fp b
During evaluation of In[32]:= f 1+a+b
During evaluation of In[32]:= fp 1+a+b
During evaluation of In[32]:= fp a+1+b
Out[32]= 1+a+b
- 因此最终的fp
实际上与第一个fp
相对应。它直到最后才打印,因为需要首先评估子表达式。
答案 1 :(得分:3)
使用两个参数调用fp
的{{1}}参数。第一个是原始未评估的表达。第二个是评估结果。在您的示例中,第二个TraceScan
正在使用第一个参数,因此您将看到未评估的表达式。将AppendTo
更改为#
,然后您会看到您期望的结果。
另请注意,第二个参数是 not 包装在#2
中(尽管文档),因此通常必须注意使用一个函数来保存{{1避免生成虚假评估的参数。
比较Trace和TraceScan
HoldForm
中详细描述了fp
的行为。它声明,默认情况下,Trace
仅在头部和参数被评估后显示表达式。因此,我们看到如下序列:
Trace
仅显示输入表达式及其结果。 In[28]:= SetAttributes[f, Orderless]
Trace[f[a, 1]]
Out[29]= {f[a,1],f[1,a]}
选项控制(引用)“是否在评估其头部和参数之前查看表达式”。当此选项为TraceOriginal
时,输出将补充头部和参数表达式:
True
新列表的第一个元素是之前的原始表达式,并且计算了参数。然后我们看到正在评估的头部和参数。最后,在评估头部和参数之后,我们再次看到顶级表达式 。列表的最后两个元素与原始跟踪输出的两个元素匹配。
正如链接文档所述,In[30]:= Trace[f[a,1], TraceOriginal->True]
Out[30]= {f[a,1],{f},{a},{1},f[a,1],f[1,a]}
对它返回的表达式非常有选择性。例如,它完全省略了琐碎的评估链。 Trace
是全面的,并且为每次评估调用提供的函数,无论是否琐碎。您可以使用以下TraceScan
表达式查看全面的评估集:
TraceScan
下表匹配TraceScan[Print, f[a,1], _, Print[{##}]&]
使用和不使用Trace
时产生的输出,以及TraceOriginal
表达式的输出:
TraceScan
鉴于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
生成的所有信息都可以使用Trace
- 并且TraceScan
提供更多信息。