Wolfram mathematica 为什么';您是否持有未估价的股票?

Wolfram mathematica 为什么';您是否持有未估价的股票?,wolfram-mathematica,Wolfram Mathematica,Mathematica的计算器通常保存(或恢复?HeadsUnevaluated作为Symbols参数提供的表达式: In[1]:= f[s, Unevaluated[1 + 1]] Out[2]= f[s, Unevaluated[1 + 1]] In[5]:= Trace[f[s,Unevaluated[1+1]],TraceOriginal->True] Out[5]= {f[s,Unevaluated[1+1]],{f},{s},f[s,1+1],f[s,Unevaluate

Mathematica的计算器通常保存(或恢复?
Head
s
Unevaluated
作为
Symbol
s参数提供的表达式:

In[1]:= f[s, Unevaluated[1 + 1]]

Out[2]= f[s, Unevaluated[1 + 1]]

In[5]:= Trace[f[s,Unevaluated[1+1]],TraceOriginal->True]

Out[5]= {f[s,Unevaluated[1+1]],{f},{s},f[s,1+1],f[s,Unevaluated[1+1]]}
但对于
RuleDelayed
,情况并非如此。此外,在
规则延迟
的情况下,任何数量的
未评估的
包装被剥离:

In[1]:= Attributes@RuleDelayed
RuleDelayed[s, Unevaluated[1 + 1]]
RuleDelayed[s, Unevaluated@Unevaluated[1 + 1]]
RuleDelayed[s, Unevaluated@Unevaluated@Unevaluated[1 + 1]]
RuleDelayed[Unevaluated@Unevaluated@Unevaluated[1 + 1], 1 + 1]

Out[1]= {HoldRest, Protected, SequenceHold}

Out[2]= s :> 1 + 1

Out[3]= s :> 1 + 1

Out[4]= s :> 1 + 1

Out[5]= 2 :> 1 + 1
dummyFunction /; (++numberOfEvaluations; False) := Null;

In[36]:= numberOfEvaluations=0;
rd[dummyFunction,Unevaluated@Unevaluated[Unevaluated[1+1]]];
numberOfEvaluations
numberOfEvaluations=0;
RuleDelayed[dummyFunction,Unevaluated@Unevaluated[Unevaluated[1+1]]];
numberOfEvaluations
Out[38]= 4
Out[41]= 4
规则延迟
的情况下,为什么求值器会剥离任何数量的
未求值的
包装?它在哪些方面有用?是否有可能为任意
符号
f
)模拟这种行为


也不清楚为什么
跟踪
显示的
规则延迟
图片比
f
更复杂:

In[2]:= Trace[RuleDelayed[s,1+1],TraceOriginal->True]
Out[2]= {s:>1+1,{RuleDelayed},{s},s:>1+1,s:>1+1,{RuleDelayed},{s},s:>1+1}

它看起来像是
RuleDelayed
被计算了两次…

Unevaluated
作为规则中最外层的包装出现时被剥离。这就是
Unevaluated
的工作原理,即
Unevaluated
不是计算任何东西的常规符号。这是一种象征。比较

In[8]:= f[s_] := g[Unevaluated[1 + 1]]

In[9]:= DownValues[f]

Out[9]= {HoldPattern[f[s_]] :> g[Unevaluated[1 + 1]]}

因为求值器是递归的,所以它最终足以摆脱
未求值的


编辑根据Alexey的评论扩展答案:

Unevaluated
是一种惰性符号,由计算器识别并在规则内执行操作的标记。因此,
Unevaluated[1+1]
保持不变,以及
f[1,Unevaluated[1+1]]
。当计算
RuleDelayed[s,Unevaluated[1+1]]
时,将剥离
Unevaluated
,然后根据计算原则重新计算整个
RuleDelayed
表达式


编辑2这是重新评估原因讨论的浓缩结果

“RuleDelayed”的实施细节导致重复评估,最终导致未评估的项目被剥离。在我回答下面的评论中,我提供了另一个命令的示例,该命令出于完全相同的原因导致双重评估。之所以会出现这种情况,是因为表达式要经过验证,一旦验证,它就会打上某个有效标志。设置有效标志将启动重新评估序列。这种情况一直持续到表达式不再更改为止。 对于其他需要验证的表达式,例如
Root
object,也会出现类似的效果:

In[41]:= Root[#1^6 + #1 - 1 & , 1]; Trace[Root[#1^6 + #1 - 1 & , 1], 
 TraceOriginal -> True]

Out[41]= {
 HoldForm[Root[#1^6 + #1 - 1 & , 1]], {HoldForm[Root]}, 
   {HoldForm[#1^6 + #1 - 1 & ], {HoldForm[Function]}, 
  HoldForm[#1^6 + #1 - 1 & ]}, 
   {HoldForm[1]}, 
  HoldForm[Root[#1^6 + #1 - 1 & , 1]],    <-- here the root had been 
                                              stamped valid, and reevaluated
   HoldForm[Root[-1 + #1 + #1^6 & , 1]]   <-- evaluation was trivial.
[41]中的
:=Root[#1^6+#1-1&,1];跟踪[Root[#1^6+#1-1&,1],
TraceOriginal->True]
Out[41]={
HoldForm[Root[#1^6+#1-1&,1]],{HoldForm[Root]},
{HoldForm[#1^6+#1-1&],{HoldForm[Function]},
HoldForm[#1^6+#1-1&],
{HoldForm[1]},

HoldForm[Root[#1^6+#1-1&,1]],这个答案应该被认为是对@Sasha答案的补充。我相信这是一个微妙的话题,可以从多个角度进行解释

为什么这个问题非同小可 我想强调的是,所讨论的行为不是典型的,因为这不是Mathematica中大多数人的行为,也不能仅仅根据评估的一般原则来解释(特别是
未评估的
剥离的机制)在不使用特定行为的特定头部的实现细节的情况下(<代码> RuleDelayed < /代码>)。考虑一些普通的头,使用<代码> HorddRES/COD>属性:< /P>
In[185]:= SetAttributes[h, HoldRest];
h[1, Unevaluated[Unevaluated[Unevaluated[1 + 1]]]]

Out[186]= h[1, Unevaluated[Unevaluated[Unevaluated[1 + 1]]]]

In[209]:= 1:>Unevaluated@Unevaluated@Unevaluated[1+1]

Out[209]= 1:>1+1
有关剥离未估价的
包装纸的一些详细信息
这是基于David Wagner的书《Mathematica中的电源编程-内核》、David Withoff的WRI技术报告《Mathematica内部结构》中的讨论,以及我自己的经验

这是一幅非常简单的求值图。Mathematica递归求值表达式,首先从“分支”(表达式)到“分支”(子表达式)和叶子(原子),然后再到“上”。在“下”的过程中,(子表达式)的头表达式被求值,然后是部分。那些头为
未求值的部分不会被进一步求值(在这个意义上,求值器不会被递归调用),而
未求值的部分会被剥离,并被标记为已完成。在“向上”的过程中,认为零件已经过评估。有许多步骤,包括序列拼接、与属性相关的评估,如<代码>平面、<代码>无序等。然后,应用当前评估的头部规则,用户定义和内置(
UpValues
DownValues
SubValues
)。最后,这对于本次讨论很重要,对于未找到适用规则的表达式部分,将还原未计算的
包装。这就是为什么对于未定义的函数
f
,我们有:

In[188]:= ClearAll[f];
f[Unevaluated[1+1]]

Out[189]= f[Unevaluated[1+1]]
通过将
TraceOriginal
选项设置为
True
,使用
TraceOriginal
,可以确认
未评估的
包装已剥离,然后恢复:

In[190]:= Trace[f[Unevaluated[1+1]],TraceOriginal->True]

Out[190]= {f[Unevaluated[1+1]],{f},f[1+1],f[Unevaluated[1+1]]} 
当为
f
定义了一些规则时会发生什么情况?答案是每个规则应用程序都会剥离一层未评估的

In[204]:= 
f[x_]:=Hold[x]; 
g[x_]:=f[x];
{f[Unevaluated[1+1]],g[Unevaluated[1+1]]}
{f[Unevaluated@Unevaluated[1+1]],g[Unevaluated@Unevaluated[1+1]]}
{f[Unevaluated@Unevaluated@Unevaluated[1+1]], g[Unevaluated@Unevaluated@Unevaluated[1+1]]}

Out[206]= {Hold[1+1],Hold[2]}
Out[207]= {Hold[Unevaluated[1+1]],Hold[1+1]}
Out[208]= {Hold[Unevaluated[Unevaluated[1+1]]],Hold[Unevaluated[1+1]]}
如果知道表达式particiapte的给定部分将进行多少次求值,原则上可以将该部分封装在
Unevaluated
的许多层中,以防止其求值。但是,通常不可能包含此信息,并且
Unevaluated
不应用作持久保持包装器-这是是
Hold
的目的。但该分析可能会更清楚地表明,为了使任何数量的评估失败,进行评估的负责人必须为其定义非琐碎的规则。换句话说,通常情况下,评估过程中包括剥离一层
未评估的
的部分(本身,“在表达的过程中”,诱导其重新评估-t
ClearAll[rd];
SetAttributes[rd, {HoldAllComplete, SequenceHold}];
rd[lhs_, Verbatim[Unevaluated][rhs_]] /;
   Head[Unevaluated[rhs]] =!= Unevaluated := Append[rd[lhs], Unevaluated[rhs]];
rd[lhs_, Verbatim[Unevaluated][rhs_]] := rd @@ {lhs, rhs};
rd[lhs_, rhs_] /; Hold[lhs] =!= Hold[Evaluate[lhs]] := Prepend[rd[rhs], lhs];
In[173]:= 
a=1;
rd[a,Unevaluated[1+1]]
rd[a,Unevaluated@Unevaluated[1+1]]
rd[a,Unevaluated@Unevaluated[1+1]]

Out[174]= rd[1,1+1]
Out[175]= rd[1,1+1]
Out[176]= rd[1,1+1]
In[183]:= 
DeleteCases[Trace[rd[s,Unevaluated[1+1]],TraceOriginal->True],
    x_/;!FreeQ[x,Head|Hold|Append|HoldPattern[rd[_]]]]

Out[183]= {rd[s,Unevaluated[1+1]],{rd},rd[s,Unevaluated[1+1]],
    rd[s,1+1],{rd},rd[s,1+1],rd[s,1+1]}

In[184]:= Trace[RuleDelayed[s,Unevaluated[1+1]],TraceOriginal->True]

Out[184]= {s:>Unevaluated[1+1],{RuleDelayed},{s},s:>1+1,s:>1+1,{RuleDelayed},{s},s:>1+1}    
ClearAll[rd];
SetAttributes[rd, {HoldRest, SequenceHold}];
Options[rd] = {"Validated" -> None};
expr : rd[args__] /; ("Validated" /. Options[Unevaluated[rd]]) =!= 
   Hold[expr] := (Options[
    Unevaluated[rd]] = {"Validated" -> Hold[expr]}; rd[args])

In[6]:= rd[Unevaluated@Unevaluated[1 + 1], 
 Unevaluated@Unevaluated[Unevaluated[1 + 1]]]

Out[6]= rd[2, 1 + 1]
dummyFunction /; (++numberOfEvaluations; False) := Null;

In[36]:= numberOfEvaluations=0;
rd[dummyFunction,Unevaluated@Unevaluated[Unevaluated[1+1]]];
numberOfEvaluations
numberOfEvaluations=0;
RuleDelayed[dummyFunction,Unevaluated@Unevaluated[Unevaluated[1+1]]];
numberOfEvaluations
Out[38]= 4
Out[41]= 4
ClearAll[rd];
SetAttributes[rd, {HoldRest, SequenceHold}];
SetAttributes[returnLast, {HoldRest}]
SetAttributes[{NotValidatedQ, setValidatedFlag}, HoldAllComplete];
Options[rd] = {"Validated" -> None};
NotValidatedQ[expr_] := ("Validated" /. Options[Unevaluated[rd]]) =!= 
   Hold[expr];
setValidatedFlag[expr_] := 
  Options[Unevaluated[rd]] = {"Validated" -> Hold[expr]};
returnLast[first_, last_] := last;
expr : rd[args__] /; NotValidatedQ[expr] := 
 returnLast[setValidatedFlag[expr], rd[args]]
rdList = DeleteCases[
   Trace[rd[Unevaluated@Unevaluated[1 + 1], 
     Unevaluated@Unevaluated[Unevaluated[1 + 1]]], 
    TraceOriginal -> 
     True], ({HoldForm[(validatedQ | setValidatedFlag)[_]], ___} | 
     HoldForm[_returnLast] | {HoldForm[returnLast]})] /. 
  rd -> RuleDelayed

RuleDelayedList = 
 Trace[RuleDelayed[Unevaluated@Unevaluated[1 + 1], 
   Unevaluated@Unevaluated[Unevaluated[1 + 1]]], 
  TraceOriginal -> True]
In[52]:= rdList = 
  Trace[rd[Unevaluated@Unevaluated[1 + 1], 
     Unevaluated@Unevaluated[Unevaluated[1 + 1]]], rd, 
    TraceOriginal -> True] /. {HoldForm[_returnLast] -> Sequence[], 
    rd -> RuleDelayed};
RuleDelayedList = 
  Trace[RuleDelayed[Unevaluated@Unevaluated[1 + 1], 
    Unevaluated@Unevaluated[Unevaluated[1 + 1]]], RuleDelayed, 
   TraceOriginal -> True];

rdList === RuleDelayedList

Out[54]= True