在mathematica中选择特定的符号定义(不是转换规则)

6 wolfram-mathematica

我有以下问题.

f[1]=1;
f[2]=2;
f[_]:=0;

dvs = DownValues[f];
Run Code Online (Sandbox Code Playgroud)

这给了

dvs = 
   {
      HoldPattern[f[1]] :> 1, 
      HoldPattern[f[2]] :> 2, 
      HoldPattern[f[_]] :> 0
   }
Run Code Online (Sandbox Code Playgroud)

我的问题是我想只提取f [1]和f [2]等的定义,而不是一般定义f [_],我不知道如何做到这一点.

我试过了,

Cases[dvs, HoldPattern[ f[_Integer] :> _ ]] (*)
Run Code Online (Sandbox Code Playgroud)

但它没有给我什么,即空列表.

有趣的是,将HoldPattern更改为临时^脚注

dvs1 = {temporary[1] :> 1, temporary[2] :> 2, temporary[_] :> 0}
Run Code Online (Sandbox Code Playgroud)

发行

Cases[dvs1, HoldPattern[temporary[_Integer] :> _]] 
Run Code Online (Sandbox Code Playgroud)

{temporary[1] :> 1, temporary[2] :> 2}
Run Code Online (Sandbox Code Playgroud)

它的工作原理.这意味着(*)几乎是一种解决方案.

我不明白为什么它适用于临时而不是HoldPattern?如何使用HoldPattern直接使其工作?

当然,问题是什么得到评估,什么不得等.在Mathematica编码时的以太问题.对于真正的大师来说......

最好的问候佐兰

脚注=我手动输入它作为替换"/ .HoldPattern - > temporary"实际上执行f [_]:= 0规则并给出一些奇怪的,我当然希望避免这种情况.

Leo*_*rin 7

原因是你必须逃避HoldPattern,或许用Verbatim:

In[11]:= Cases[dvs, 
            Verbatim[RuleDelayed][
               Verbatim[HoldPattern][HoldPattern[f[_Integer]]], _]]

Out[11]= {HoldPattern[f[1]] :> 1, HoldPattern[f[2]] :> 2}
Run Code Online (Sandbox Code Playgroud)

只有少数头是必要的,并且HoldPattern是其中之一,正是因为它通常对模式匹配器是"不可见的".对于您temporary或其他负责人来说,没有必要这样做.请注意图案f[_Integer]的包装方式HoldPattern- 此时间HoldPattern用于直接目的 - 保护图案免受评估.请注意,RuleDelayed它也包含在内- 这Verbatim实际上是另一种常见情况Verbatim- 这是必需的,因为它Cases有一个涉及规则的语法,我们不想Cases在这里使用这种解释.所以,这是IMO一个非常好的例子来说明HoldPatternVerbatim.另请注意,完全可以实现目标HoldPattern,如下所示:

In[14]:= Cases[dvs,HoldPattern[HoldPattern[HoldPattern][f[_Integer]]:>_]]

Out[14]= {HoldPattern[f[1]]:>1,HoldPattern[f[2]]:>2}
Run Code Online (Sandbox Code Playgroud)

但是,HoldPattern用于逃避目的(代替Verbatim)是IMO在概念上的错误.

编辑

为了稍微调整一下情况Cases,这里有一个简单的例子,我们使用Cases涉及转换规则的语法.这种扩展语法Cases不仅指示查找和收集匹配的片段,而且还在它们被找到后立即根据规则对它们进行变换,因此结果列表包含变换后的片段.

In[29]:= ClearAll[a, b, c, d, e, f];
Cases[{a, b, c, d, e, f}, s_Symbol :> s^2]

Out[30]= {a^2, b^2, c^2, d^2, e^2, f^2}
Run Code Online (Sandbox Code Playgroud)

但是,如果我们需要找到自己规则的元素呢?如果我们试试这个:

In[33]:= Cases[{a:>b,c:>d,e:>f},s_Symbol:>_]
Out[33]= {}
Run Code Online (Sandbox Code Playgroud)

它不起作用,因为Cases将第二个参数中的规则解释为使用扩展语法,查找符号并替换它的指令_.由于它默认在级别1上搜索,并且符号在此处的级别2上,因此它什么也没找到.注意:

In[34]:= Cases[{a:>b,c:>d,e:>f},s_Symbol:>_,{2}]
Out[34]= {_,_,_,_,_,_}
Run Code Online (Sandbox Code Playgroud)

无论如何,这不是我们想要的.因此,我们必须强制Cases将第二个参数视为普通模式(简单而非扩展的语法).有几种方法可以做到这一点,但所有这些方法都以某种方式"逃避" RuleDelayed(或Rule):

In[37]:= Cases[{a:>b,c:>d,e:>f},(s_Symbol:>_):>s]
Out[37]= {a,c,e}

In[38]:= Cases[{a:>b,c:>d,e:>f},Verbatim[RuleDelayed][s_Symbol,_]:>s]
Out[38]= {a,c,e}

In[39]:= Cases[{a:>b,c:>d,e:>f},(Rule|RuleDelayed)[s_Symbol,_]:>s]
Out[39]= {a,c,e}
Run Code Online (Sandbox Code Playgroud)

在所有情况下,我们要么避免扩展语法Cases(最后两个例子),要么设法使用它(第一种情况).