本文介绍了在 mathematica 中选择特定的符号定义(不是转换规则)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题.

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

dvs = DownValues[f];

这给了

dvs =
   {
      HoldPattern[f[1]] :> 1,
      HoldPattern[f[2]] :> 2,
      HoldPattern[f[_]] :> 0
   }

我的问题是我只想提取 f[1] 和 f[2] 等的定义,而不是 f[_] 的一般定义,我不知道该怎么做.

My problem is that I would like to extract only definitions for f[1] and f[2] etc but not the general definition f[_], and I do not know how to do this.

我试过了,

Cases[dvs, HoldPattern[ f[_Integer] :> _ ]] (*)

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

but it gives me nothing, i.e. the empty list.

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

Interestingly, changing HoldPattern into temporary^footnote

dvs1 = {temporary[1] :> 1, temporary[2] :> 2, temporary[_] :> 0}

和发行

Cases[dvs1, HoldPattern[temporary[_Integer] :> _]]

给予

{temporary[1] :> 1, temporary[2] :> 2}

它有效.这意味着 (*) 几乎是一个解决方案.

and it works. This means that (*) is almost a solution.

我不明白为什么它适用于临时而不适用于 HoldPattern?如何让它直接与 HoldPattern 一起使用?

I do not not understand why does it work with temporary and not with HoldPattern? How can I make it work directly with HoldPattern?

当然,问题是什么被评估,什么不被评估等等.在 Mathematica 中编码时的以太问题.真正的大师的东西......

Of course, the question is what gets evaluated and what not etc. The ethernal problem when coding in Mathematica. Something for real gurus...

致以最诚挚的问候卓然

footnote = 我手动输入它作为替换/.HoldPattern -> 临时"实际上执行了 f[_]:=0 规则并给出了一些奇怪的东西,我当然想避免这种执行.

footnote = I typed it by hand as replacement "/. HoldPattern -> temporary" actually executes the f[_]:=0 rule and gives someting strange, this excecution I certainly would like to avoid.

推荐答案

原因是你必须逃避 HoldPattern,也许使用 逐字:

The reason is that you have to escape the HoldPattern, perhaps with Verbatim:

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

Out[11]= {HoldPattern[f[1]] :> 1, HoldPattern[f[2]] :> 2}

只有几个头是必需的,而 HoldPattern 就是其中之一,正是因为它通常对模式匹配器来说是不可见的".对于您的 temporary 或其他主管,这不是必需的.请注意,模式 f[_Integer] 被包裹在 HoldPattern 中 - 这次 HoldPattern 用于其直接目的 - 以保护来自评估的模式.请注意,RuleDelayed 也包含在 Verbatim 中 - 这实际上是 Verbatim 的另一种常见情况 - 这是必需的,因为 Cases 有一个涉及规则的语法,我们不希望 Cases 在这里使用这种解释.所以,这是 IMO 一个很好的例子来说明 HoldPatternVerbatim.另请注意,完全可以使用 HoldPattern 实现目标,如下所示:

There are just a few heads for which this is necessary, and HoldPattern is one of them, precisely because it is normally "invisible" to the pattern-matcher. For your temporary, or other heads, this wouldn't be necessary. Note by the way that the pattern f[_Integer] is wrapped in HoldPattern - this time HoldPattern is used for its direct purpose - to protect the pattern from evaluation. Note that RuleDelayed is also wrapped in Verbatim - this is in fact another common case for Verbatim - this is needed because Cases has a syntax involving a rule, and we do not want Cases to use this interpretation here. So, this is IMO an overall very good example to illustrate both HoldPattern and Verbatim.Note also that it is possible to achieve the goal entirely with HoldPattern, like so:

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

Out[14]= {HoldPattern[f[1]]:>1,HoldPattern[f[2]]:>2}

然而,使用 HoldPattern 进行转义(代替 Verbatim)在 IMO 概念上是错误的.

However, using HoldPattern for escaping purposes (in place of Verbatim) is IMO conceptually wrong.

编辑

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

To calrify a little the situation with Cases, here is a simple example where we use the syntax of Cases involving transformation rules. This extended syntax instructs Cases to not only find and collect matching pieces, but also transform them according to the rules, right after they were found, so the resulting list contains the transformed pieces.

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}

但是如果我们需要找到本身就是规则的元素怎么办?如果我们只是试试这个:

But what if we need to find elements that are themselves rules? If we just try this:

In[33]:= Cases[{a:>b,c:>d,e:>f},s_Symbol:>_]
Out[33]= {}

它不起作用,因为 Cases 将第二个参数中的规则解释为使用扩展语法的指令,找到一个符号并将其替换为 _.由于它默认搜索级别 1,而符号在这里是级别 2,因此它什么也没找到.观察:

It doesn't work since Cases interprets the rule in the second argument as an instruction to use extended syntax, find a symbol and replace it with _. Since it searches on level 1 by default, and symbols are on level 2 here, it finds nothing. Observe:

In[34]:= Cases[{a:>b,c:>d,e:>f},s_Symbol:>_,{2}]
Out[34]= {_,_,_,_,_,_}

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

In any case, this is not what we wanted. Therefore, we have to force Cases to consider the second argument as a plain pattern (simple, rather than extended, syntax). There are several ways to do that, but all of them "escape" RuleDelayed (or Rule) in some way:

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}

在所有情况下,我们要么避免使用 Cases 的扩展语法(最后两个示例),要么设法利用它来发挥我们的优势(第一种情况).

In all cases, we either avoid the extended syntax for Cases (last two examples), or manage to use it to our advantage (first case).

这篇关于在 mathematica 中选择特定的符号定义(不是转换规则)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 12:44