这个问题的主要观点是TraceScan
的第一个参数的操作背后的逻辑(以及相关的第四个参数,但问题不是必需的):它有时会排除某些评估步骤(Trace
选项TraceOriginal->True
给出)但有时它包含它们,如以下示例所示。我有兴趣了解此行为背后的逻辑以及如何强制TraceScan
提供完整的评估步骤。这个问题最初出现在this主题中(参见我对答案的评论)。 WReach here给出了TraceScan
与Trace
的行为的一般比较,但它没有回答以下问题:
1。)为什么TraceScan
没有给出最终表达式f[a,1]
Trace
给出的案例:
In[1]:= SetAttributes[traceScan,HoldAll];
traceScan[expr_]:=(list={};TraceScan[AppendTo[list,#]&,expr];list)
In[3]:= ClearAll[f,a];
Trace[f[a,1],TraceOriginal->True]
Out[4]= {f[a,1],{f},{a},{1},f[a,1]}
In[5]:= ClearAll[f,a];
traceScan[f[a,1]]
Out[6]= {f[a,1],f,a,1}
2。)并且,在以下情况中,为什么Trace
和TraceScan
都给出了
最终表达式f[1,a]
仅为Trace
提供中间表达式
f[a,1]
对应于应用Orderless
的{{1}}属性之前的评估步骤:
f
3。)为什么在最后一种情况下,In[7]:= ClearAll[f,a];
SetAttributes[f,Orderless]
Trace[f[a,1],TraceOriginal->True]
Out[9]= {f[a,1],{f},{a},{1},f[a,1],f[1,a]}
In[12]:= ClearAll[f,a];
SetAttributes[f,Orderless]
traceScan[f[a,1]]
Out[14]= {f[a,1],f,a,1,f[1,a]}
和Trace
都会给出最终结果
在应用TraceScan
的{{1}}属性之前,表达式ff[1,b]
和中间表达式ff[b,1]
对应于评估步骤:
Orderless
4。)有没有办法迫使ff
总是给出详尽无遗的
有关评估的信息为In[21]:= ClearAll[f,ff,a];
SetAttributes[ff,Orderless];f=ff;a=b;
Trace[f[a,1],TraceOriginal->True]
Out[23]= {f[a,1],{f,ff},{a,b},{1},ff[b,1],ff[1,b]}
In[24]:= ClearAll[f,ff,a];
SetAttributes[ff,Orderless];f=ff;a=b;
traceScan[f[a,1]]
Out[26]= {f[a,1],f,ff,a,b,1,ff[b,1],ff[1,b]}
吗?
另外
这是TraceScan
的另一个更具信息性的版本,它使用第四个参数:
Trace
答案 0 :(得分:1)
案例1和2。引用the Documentation:
通常情况下,......
Trace
仅在函数后截取表达式 参数已被评估。通过设置TraceOriginal->True
,您 也可以{/ 1}}在函数之前查看表达式 论证已被评估。
似乎设置Trace
只会导致将额外信息添加到TraceOriginal->True
的默认输出中。结果,我们看到了不必要的额外“中间表达”Trace
,在f[a,1]
和TraceScan
显示的情况下,它们实际上并未出现在评估链中:
TracePrint
所以它看起来像In[1]:= ClearAll[f, a];
SetAttributes[f, Orderless]
TracePrint[f[a, 1]]
During evaluation of In[1]:= f[a,1]
During evaluation of In[1]:= f
During evaluation of In[1]:= a
During evaluation of In[1]:= 1
During evaluation of In[1]:= f[1,a]
Out[3]= f[1, a]
中的错误。
案例3。在这种情况下,一切都按预期工作,因为中间表达式Trace
确实出现在评估链中,作为应用与ff[b,1]
相关的定义的结果。没什么意外的。
结论。 f
和Trace
都提供了有关评估链的详尽信息,但TraceScan
生成的输出还可能包含误导性的“中间表达”,即实际上只是链条的初始表达。