模式、规则和定义中的计算

Mathematica 中模式匹配和计算有重要的关系,首先看到模式匹配是在至少有部分计算出的表达式上进行的,所以与这些表达式匹配的模式也应该进行计算.

计算模式表明它与给出的表达式匹配.
In[1]:=
Click for copyable input
Out[1]=
条件 的右端仅在匹配过程中使用时才计算.
In[2]:=
Click for copyable input
Out[2]=

有时需要保持模式或模式的一部分不计算,这可以用 HoldPattern 包装不需要计算的这一部分. 在模式匹配中,HoldPattern[patt] 等价于 patt,但表达式 patt 保持被计算的形式.

HoldPattern[patt]在模式匹配中等价于 pattpatt 不计算

防止模式被计算.

HoldPattern 的一个应用在于对不需要计算的表达式或保持未被计算的形式的表达式,规定其模式.

HoldPattern 使 不计算,并将它与 操作符左端的 匹配.
In[3]:=
Click for copyable input
Out[3]=

注意,Hold 等函数禁止对表达式进行计算,但它们不影响对有 和其它一些运算的表达式的项的操作.

当其变量不是原子形式时定义 的值.
In[4]:=
Click for copyable input
由这一定义,表达式 等不变.
In[5]:=
Click for copyable input
Out[5]=
而根据 的定义模式 变化.
In[6]:=
Click for copyable input
Out[6]=
需要用 HoldPattern 包装 去禁止它被计算.
In[7]:=
Click for copyable input
Out[7]=

等变换规则的左端通常是立即计算的,其原因是这些规则作用的表达式已经被计算出来了. 的右端也是立即计算出来的,但使用延迟规则 可以使表达式 rhs 不计算.

中,右端立即计算,而在 中,右端不立即计算.
In[8]:=
Click for copyable input
Out[8]=
使用规则的结果是: 的右端放在 Hold 中,没有被计算.
In[9]:=
Click for copyable input
Out[9]=
lhs->rhs计算出 lhsrhs
lhs:>rhs计算 lhs,但不计算 rhs

变换规则的计算.

变换规则的左端常被计算,而定义的左端通常不计算,这个差异的原因在于变换规则一般是将 用到已经计算出来的表达式上,而定义用在计算过程中,且作用于没有完全计算出来的表达式上. 要作用于这些表达式上,定义的左端至少是部分地未被计算.

符号的定义是一个最简单的情况,如 "非标准计算" 中讨论的, 等定义左端的符号未被计算. 如果 x 在前面已经给赋值 y,且 要计算出的话,就会出现 的情形.

此定义中左端的符号没有计算.
In[10]:=
Click for copyable input
Out[10]=
重新定义这一符号.
In[11]:=
Click for copyable input
Out[11]=
如果计算了左端,定义的不是 , 而是 .
In[12]:=
Click for copyable input
Out[12]=
现在看到 的值为 .
In[13]:=
Click for copyable input
Out[13]=

尽管在定义左端出现的单个符号不计算,但复杂的表达式则部分地被计算,在定义左端的表达式 中, args 已被计算.

已计算出 ,故定义的是 .
In[14]:=
Click for copyable input
Out[14]=
这里显示 的值.

通过考察表达式计算过程中定义的使用,就会理解为什么出现在定义左端函数的变量被计算. 如 "计算原理" 节所述,Mathematica 求一个函数的值时,它先计算它的每个变量,然后再查找函数的定义. 于是,当 Mathematica 使用一个函数的定义时,它的变量在此以前计算出来. 这里的例外是有些函数具有其变量不被计算的属性.

symbol=value计算 value ; 不计算 symbol
symbol:=valuesymbolvalue 都不计算
f[args]=valueargs 计算,但左端作为整体不计算
f[HoldPattern[arg]]=valuef[arg] 赋值,但不计算 arg
Evaluate[lhs]=value左端被全部计算出来

定义中的计算.

大部分情况下需要求定义左端函数的变量,但有时也不需要计算出它们,此时可以用 HoldPattern 封装不需要计算的那些项即可.

New to Mathematica? Find your learning path »
Have a question? Ask support »