了解痕迹*

时间:2011-04-06 06:08:43

标签: wolfram-mathematica

美好的一天,

当尝试使用标准TraceTraceScan命令以及最近thread中开发的漂亮视觉表示来理解 Mathematica 的评估序列时,我的行为面临一些模棱两可的问题。

首先,当我评估时

  

在[1]中:=跟踪[a + 1,TraceOriginal-> True]

我得到了

  

输出[1] =   {A + 1,{加},{A},{1}中,+ 1,1 + A,{加},{1},{A},1 +α}

所有子列表都对应于子评估(如文档中所述)。最后一个表达式1+a可能对应于评估结果,尽管文档中没有明确说明。但是在列表中间究竟表达a+11+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+aa+1。两者都是(子)评估的结果。但实际输出是1+a,所以我不明白为什么a+1在评估链的末尾?为什么在a+1的情况下评估链中间没有Trace?这是一个错误吗?

P.S。这些结果用 Mathematica 7.0.1和5.2再现。

2 个答案:

答案 0 :(得分:3)

问题的第一部分很简单。 列表中间的表达式a+11+aOrderless的{​​{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提供更多信息。