模式
模式简介 | 变量个数不确定的函数 |
寻找与模式匹配的表达式 | 可选变量与默认变量 |
模式块的命名 | 定义具有可选变量的函数 |
模式中的表达式类型限制 | 重复模式 |
限制模式 | 逐字模式 |
有多种供选方案的模式 | 常用表达式的模式 |
模式序列 | 举例:定义积分函数 |
有交换性和结合性的函数 |
f[n_] | 变量名为 n 的 f |
f[n_,m_] | 变量名为 n 和 m 的 f |
x^n_ | 指数为 n 的 x 的幂 |
x_^n_ | 任何次幂的表达式 |
a_+b_ | 两个表达式的和 |
{a1_,a2_} | 两个表达式组成的列表 |
f[n_,n_] | 有两个相同 变量的 f |
模式通常用来“解构”函数的变量. 定义 f[list_] 时,就需要用类似于 Part 的函数来选出列表的元素. 但是若知道集合中总是两个元素时,给出定义 f[{x_,y_}] 就很方便. 这就可以用 x 和 y 指代元素. 另外,当 f 的变量不是以两个表达式列表的形式出现时,Wolfram 语言就不会使用你刚定义的函数.
Wolfram 语言的模式代表一类给定结构 的表达式. 当一个表达式的结构与模式的结构相同时,这个表达式就可以用在模式中. 即使数学上完全相同的两个表达式,当它们的结构不同时,也不能用同一个模式来表示.
应该意识到 Wolfram 语言是以结构相等来匹配表达式的,而不是以数学上的相等来匹配表达式的. 可以用 Expand 和 Factor 使 (1+a)^2 和 1+2a+a^2 具有相同的结构. 但正如 "将表达式化为标准形式" 中讨论的,没有一般的方法去判断任意两个数学表达式相等.
另一个例子是模式 x^_ 与表达式 x^2 匹配. 但它与 1 不匹配,尽管 1 可以写为 x^0. "可选变量与默认变量" 将讨论如何给出模式使这种情形匹配. 应该记住在任何情况下,Wolfram 语言将按结构相等进行模式匹配.
另外,Wolfram 语言中的模式只与由 FullForm 给出的表达式的完全形式进行匹配. 因此,例如,1/x 的完全形式是Power[x,-1],它与模式 x_^n_ 匹配,但不能与模式 x_/y_ 匹配,因为 x_/y_ 的完全形式是Times[x_,Power[y_,-1]]. 另外,"可选变量与默认变量" 将讨论用户如何构造对所有情况都匹配的模式.
Cases[list,form] | 给出与 form 匹配的 list 中的元素 |
Count[list,form] | 给出与 form 匹配的 list 中元素的个数 |
Position[list,form,{1}] | 给出与 form 匹配的 list 中的元素的位置 |
Select[list,test] | |
Pick[list,sel,form] | 给出使 sel 的相应元素与 form 匹配的 list 中的元素 |
像 Cases 这样的函数不仅可以用于列表,而且可以用于任何表达式,可以指定项所在的层.
Cases[expr,lhs->rhs] | 在 expr 中寻找与 lhs 匹配的元素,并对其进行变换 |
Cases[expr,lhs->rhs,lev] | 测试指定层 lev 上表达式 expr 的项 |
Count[expr,form,lev] | 给出指定层 lev 上与模式 form 匹配的项数 |
Position[expr,form,lev] | 给出指定层 lev 上与模式 form 匹配的项的位置 |
DeleteCases[expr,form] | 删除表达式 expr 中与 form 匹配的元素 |
DeleteCases[expr,form,lev] | 删除表达式 expr 的指定层 lev 中与 form 匹配的项 |
ReplaceList[expr,lhs->rhs] | 寻找所有 expr 可以与 lhs 匹配的方式 |
在 Wolfram 语言中,不仅可以对一个空位命名,而且可以对模式中的任何部分命名,一般,x:pattern 表示命名为 x 的模式. 在变换规则中,可以将这种机制用到模式的任何部分以便在变换规则的右端使用.
Wolfram 语言中提供了对模式进行限制的一般方法. 这可以通过在模式后面加 /;condition 来实现,此运算符 /; 可读作“斜杠分号”、“每当”或“只要”,其作用是当所指定的 condition 值为 True 时模式才能使用.
可以在变换规则中用 /;,也可以在单个模式中用 /;. 可以将 /;condition 放在 := 定义域或 :> 规则后告诉 Wolfram 语言只有当指定的条件满足时才能使用此定义或规则. 但要注意 /; 不能放在 = 或 -> 规则后,因为这些是立即被处理的(见 "立即定义和延时定义" ).
在定义模式或规则时,可以把 /; 放在不同的位置. 例如,可以将 /; 放在规则的右端,其形式为 lhs:>rhs/;condition,也可以将其放在左端,其形式为 lhs/;condition->rhs. 还可以把它插在表达式 lhs 的中间. 但要注意在指定条件中使用的模式名称必须在该条件涉及的模式中出现,否则在判断条件是否成立的过程中所使用的名称就不一定限制在与模式匹配的表达式值之中,这时 Wolfram 语言会使用一些全局变量,而不是取决于模式匹配的值.
例如,在 f[x_,y_]/;(x+y<2) 的条件中将使用与 f[x_,y_] 匹配的 x 和 y 的值,而在f[x_/;x+y<2,y_] 的条件中将用一个全局变量 y 的值,而不是与模式匹配的 y 值.
IntegerQ[expr] | 整数 |
EvenQ[expr] | 偶数 |
OddQ[expr] | 奇数 |
PrimeQ[expr] | 素数 |
NumberQ[expr] | 任何数 |
NumericQ[expr] | 数字型 |
PolynomialQ[expr,{x1,x2,…}] | 关于 x1, x2, … 的多项式 |
VectorQ[expr] | 表示向量的列表 |
MatrixQ[expr] | 表示矩阵的集合的列表 |
VectorQ[expr,NumericQ]
,
MatrixQ[expr,NumericQ] | |
所有元素都是数字的向量和矩阵 | |
VectorQ[expr,test]
,
MatrixQ[expr,test] | |
对所有元素 test 的函数值都为 True 的向量和矩阵 | |
ArrayQ[expr,d] | 深度与 d 匹配的完全数组 |
SameQ[x,y] 或 x===y | x 与 y 相等 |
UnsameQ[x,y] 或 x=!=y | x 与 y 不等 |
OrderedQ[{a,b,…}] | a、b … 按标准顺序排列 |
MemberQ[expr,form] | form 与表达式 expr 中的一个元素匹配 |
FreeQ[expr,form] | form 与表达式 expr 中的任何元素不匹配 |
MatchQ[expr,form] | expr 与模式 form 匹配 |
ValueQ[expr] | 定义了 expr 的一个值 |
AtomQ[expr] | expr 无任何子表达式 |
pattern?test | 模式与 test 的结果为 True 的表达式匹配 |
Except 可以把模式作为一个变量:
在使用有可选项的模式时,在每个可选项中应该用同名. 当形如 (a[x_] b[x_]) 的模式与表达式匹配时,则必须有一个与 x 对应的表达式. 当 (a[x_] b[y_]) 匹配时,必须有与 x 或 y 对应的表达式,而且不匹配的必须是Sequence[ ].
PatternSequence[p1,p2,…] | 与 p1,p2,… 匹配的变量序列 |
空序列,PatternSequence[],有时对于指定一个可选变量是有用的.
在模式匹配中,涉及到有可结合性和可交换性的函数如 Plus 或 Times 时,Wolfram 语言就测试变量的各种顺序来进行匹配. 有时会有几种形式,Wolfram 语言就与先找到的形式进行匹配. 例如,h[x_+y_,x_+z_] 可以与 h[a+b,a+b] 按 x→a、y→b、z→b 或 x→b、y→a、z→a 进行匹配. Wolfram 语言先找到了情形 x→a、y→b、z→b,故用这种匹配形式.
ReplaceList 显示两种可能的匹配:
正如 "属性" 中讨论的,Wolfram 语言可以给函数赋予一些属性以表明该函数在计算和匹配过程中是被怎样处理的. 例如,对函数赋予了 Orderless 属性后,它就有可交换性或对称性,允许在模式匹配中对变量重新组合.
Orderless | 交换性:如 f[b,c,a] 等价于 f[a,b,c] |
Flat | 结合性:如 f[f[a],b] 等价于 f[a,b] |
OneIdentity | 恒等:如 f[f[a]] 等价于 a |
Attributes[f] | 给出赋予 f 的属性 |
SetAttributes[f,attr] | 给 f 赋予属性 attr |
ClearAttributes[f,attr] | 清除 f 的属性 attr |
在不具有结合性的函数中,模式 x_ 仅与函数的一个变量匹配. 而在具有结合性的函数 f[a,b,c,…] 中,x_ 可以与多个变量的对象如 f[b,c] 匹配. 在 x_ 与具有结合性的函数的一个变量匹配时,就需要弄清楚它是与变量 a 匹配,还是与f[a] 匹配. 如果函数具有属性 OneIdentity 时,Wolfram 语言选择前者的概率更大,否则,它会首先尝试使用后者,然后使用前者.
函数 Plus,Times 和 Dot 都具有属性 OneIdentity,这反映了 Plus[x] 与 x 等价. 但在表示数学对象时,处理没有OneIdentity 属性的可结合的函数常常是方便的.
双空位 __ 表示一个或多个表达式的序列. 三空位 ___ 表示零个或多个表达式序列. 在使用三空位时,很容易导致死循环这类错误. 例如,定义 p[x_,y___]:=p[x] q[y],接下来输入 p[a] 将进入死循环状态,此时,y 将反复地与零元素序列进行匹配. 所以,要尽量地少用三空位.
_ | 单一表达式 |
x_ | 名为 x 的表达式 |
__ | 一个或多个表达式序列 |
x__ | 名为 x 的表达式列 |
x__h | 头部为 h 的表达式列 |
___ | 零个或多个表达式序列 |
x___ | 名为 x 的零个或多个表达式序列 |
x___h | 头部为 h 的零个或多个表达式序列 |
在使用多重空位时,对特定的表达式有不同的匹配方式. 默认情况下,Wolfram 语言总是先将模式中的第一个多空位与变量的最短序列匹配. 可以通过在模式的项周围使用 Longest 或者 Shortest 括起来来改变顺序.
许多枚举类型可以使用具有不同模式类型的 ReplaceList 来实现:
由于 Plus 是一个可结合的函数,模式 x_+y_ 可以与任意项的和匹配. 然而,该模式不能与单项 a 匹配. 但由于模式x_+y_. 中含有一个可选项,故它既可以与任意有限项如 x_ 与 y_ 的和,也可以与单项 x_ 匹配,此时 y 为默认值 0 .
有时不对一个可选变量分配默认值是方便的;这样的变量可以使用 PatternSequence[] 来指定.
pPatternSequence[] | 不具有默认值的可选模式 |
第一种方法就是利用变量的位置,忽略这些变量后就用默认值来代替. 几乎所有用这种方法定义的系统函数都可以忽略相应变量. 例如,函数 Flatten[list,n] 中的第二个变量忽略时用默认值 Infinity 来代替.
定义第二个变量为可选的函数,当该函数被忽略时,其默认值为 Infinity.
Wolfram 语言中定义有可选变量函数的第二种方法是明确给出可选变量的名称,然后可用变量规则对其赋值,对像 Plot 等可选变量很多的函数,这种方法特别方便.
一个函数中可选变量的值可以通过将适当的变换规则放在变量的后面给出. 例如,可用 Joined->True 来指定ListPlot[list,Joined->True] 中可选变量 Joined 的值.
f[x_,OptionsPattern[]]:=value | 具有零个或多个命名的可选变量的函数 |
OptionValue[name] | 函数中命名可选变量值 |
FilterRules[opts,Options[name]] | opts 中的规则被用作函数 name 的选项 |
FilterRules[opts,Except[Options[name]]] | |
opts 中的规则不能用作函数 name 的选项 |
这里改变了 NDSolve 所用的方法和图中的颜色:
x__ 等多空位可以用来定义产生任意表达式序列的模式. 而 Wolfram 语言模式重复运算 .. 和 ... 可以给出某些形式重复任意次的模式. 例如,f[a..] 表示任意形如 f[a],f[a,a],f[a,a,a] 的表达式.
p.. 或 Repeated[p] | 重复一次或多次的模式或表达式 |
Repeated[p,max] | 重复至多 max 次的模式 |
Repeated[p,{min,max}] | 重复次数在 min 和 max 之间的模式 |
Repeated[p,{n}] | 刚好重复 n 次的模式 |
Verbatim[expr] | 必须逐字匹配的表达式 |
n_Integer | 整数 n |
x_Real | 实数 x |
z_Complex | 复数 z |
Complex[x_,y_] | 复数 x+iy |
Complex[x_Integer,y_Integer] | 实部和虚部均为整数的复数 |
(r_Rationalr_Integer) | 有理数或整数 r |
Rational[n_,d_] | 有理数 |
(x_/;NumberQ[x]&&Im[x]==0) | 任何形式的实数 |
(x_/;NumberQ[x]) | 任何数 |
这些表达式有不同的完全形式表明不能用 x_+Iy_ 与复数匹配:
在 "符号计算" 中讨论过,Wolfram 语言将所有的代数表达式表示为标准形式,标准形式的基础是幂乘积的和. 在商中分母转化为负指数,差被转化为负项的和. 定义代数表达式的模式中必须用标准形式,标准形式往往与 Wolfram 语言的输出形式不一致. 但在任何情况下,,可以用 FullForm[expr] 去得到表达式的内部形式.
x_+y_ | 两项或多项的和 |
x_+y_. | 单项或多项的和 |
n_Integer x_ | 有一个整数因子的表达式 |
a_.+b_.x_ | 线性表达式 a+bx |
x_^n_ | xn 其中 n≠0,1 |
x_^n_. | xn 其中 n≠0 |
a_.+b_.x_+c_.x_^2 | 线性项系数非零的二次表达式 |
x_List 或 x:{___} | 一个列表 |
x_List/;VectorQ[x] | 没有子列的向量 |
x_List/;VectorQ[x,NumberQ] | 数值向量 |
x:{___List} 或 x:{{___}...} | 集合的列表 |
x_List/;MatrixQ[x] | 没有子列的矩阵 |
x_List/;MatrixQ[x,NumberQ] | 常数矩阵 |
x:{{_,_}...} | 元素对的集合 |
数学形式
|
Wolfram 语言的定义
|
integrate[y_+z_,x_]:=integrate[y,x]+integrate[z,x] | |
( 独立于 ) | integrate[c_y_,x_]:=c integrate[y,x]/;FreeQ[c,x] |
integrate[c_,x_]:=cx/;FreeQ[c,x] | |
,
| integrate[x_^n_.,x_]:=x^(n+1)/(n+1)/;FreeQ[n,x]&&n!=-1 |
integrate[1/(a_.x_+b_.),x_]:=Log[ax+b]/a/;FreeQ[{a,b},x] | |
integrate[Exp[a_.x_+b_.],x_]:=Exp[ax+b]/a/;FreeQ[{a,b},x] |
Plus 的结合性使线性关系对任意项的和成立:
Wolfram 语言检查乘积的每一项是否满足 FreeQ 条件,从而将其提到积分外: