我是一个非常新手的Mathematica用户,尽管有详尽的文档以及讨论该主题的大量StackExchange和StackOverflow问题,但我仍然无法理解它的评估控制、与它相关的所有可能的构造(如Hold
、Unevaluated
等(以及它们的工作方式。因此,对任何可能的重复表示歉意。
我的用例如下:我有一个由数千个规则和模式(DownValues
(定义的函数(比如f
(。我想从f[expr]
(对于某些expr
(的展开表示开始,并获得将单个特定规则应用于f[expr]
的结果。我希望结果也能继续下去。
作为一个特殊的例子,假设我们有以下内容:
In[1]: nat[0] := 0
In[2]: nat[n_] := 1 + nat[n - 1]
In[3]: DownValues[nat]
Out[3]: {HoldPattern[nat[0]] :> 0, HoldPattern[nat[n_]] :> 1 + nat[n - 1]}
In[4]: nat[10]
Out[4]: 10
现在,我想从一个表示为nat[10]
(未赋值!(的表达式开始,并想具体应用第二条规则(HoldPattern[nat[n_]] :> 1 + nat[n - 1]
(来获得1 + nat[9]
形式的表达式。类似地,如果我希望应用第一条规则(HoldPattern[nat[0]] :> 0
(,我希望结果保持其原始形式不变,即nat[10]
。
谢谢你的帮助!
这将有助于您理解Mathematica的运算方法。
Wolfram参考:定义的排序
即Mathematica";查找形式为f[n]的表达式的值,它首先尝试特殊情况f[1],只有当这不适用时,它才会尝试一般情况f[n]">
因此,对于下面的函数,nat[0]
总是先尝试,但当然,它只在参数为0时求值。然后尝试CCD_ 14。
nat[0] := 0
nat[n_] := 1 + nat[n - 1]
对于您关于获得1 + nat[9]
的问题,这里有一种方法
Clear[nat]
nat[0] := 0
nat[n_] := HoldForm[1 + nat[o]] /. o -> n - 1
ans = nat[10]
1+nat[9]
Do[ans = ReleaseHold[ans], 10]
ans
10
替代(更好(
Clear[nat]
nat[0] := 0
nat[n_] := With[{m = n - 1}, HoldForm[1 + nat[m]]]
ans = nat[10]
1+nat[9]
Do[ans = ReleaseHold[ans], 9]
ans
9+(1+nat[0](
请注意,这是10次迭代后的结果。最终的CCD_ 16导致CCD_。
ReleaseHold[ans]
10
如果在上面的演示中使用Hold
而不是HoldForm
,您可能会发现更容易看到发生了什么。
在Mathematica的StackExchange中的一次平行讨论中,我发现了一种相对更直接的方法来处理这个问题:
In[6] rules = DownValues[nat]
Out[6] {HoldPattern[nat[0]] :> 0, HoldPattern[nat[n_]] :> 1 + nat[n - 1]}
In[7] DownValues[nat] = {}
Out[7] {}
In[8] nat[10]
Out[8] nat[10]
In[9] nat[10] /. rules[[1]]
Out[9] nat[10]
In[10] nat[10] /. rules[[2]]
Out[10] 1 + nat[9]