パターン適用範囲の制限

Wolfram言語は,パターンに制約条件を指定するための一般化された機構を提供している.単に,パターン記述の後に書式/;condition の条件を加えればよい.そうすると,制約条件がTrueになる場合に限り,パターンを適用する.ここで,記号/;はスラッシュ・セミと読み,その意味は「何々の,場合に限り」と解釈する.

pattern/;condition条件が満たされたときのみマッチするパターン
lhs:>rhs/;condition条件が満たされたときのみ適用する変換規則
lhs:=rhs/;condition条件が満たされたときのみ適用する定義

パターンと変換規則の適用範囲の限定

引数nが0より大のときだけ適用する定義を関数facに与える.
In[1]:=
Click for copyable input
facの定義は,引数が正のときにだけ適用される.
In[2]:=
Click for copyable input
Out[2]=
リストから負の要素を検索させる.
In[3]:=
Click for copyable input
Out[3]=

/;は,個々のパターンだけでなく,:=の関数定義式や:>の変換規則にも使える.そのときも,式や規則の末尾に書式/;conditionを使い制約条件を加えることで,特定の条件が満たされるときだけに定義や変換規則が適用されるようにすることができる.ただし,注意点として,この/;条件は,通常,=の定義や,->の変換規則に使ってはならない.「即時的な定義と遅延的な定義」で述べるように,これらの式は直ちに評価されてしまうからである.

この方法でも,引数nが正の値を取るときだけに適用される定義を与えることができる.
In[4]:=
Click for copyable input
引数が正のときだけ階乗関数は評価を行う.
In[5]:=
Click for copyable input
Out[5]=

演算子/;を使い,規則の適用範囲を任意な数学的条件で制限することも可能である.通常の場合,広範な式と構造的にマッチするパターンを使い,数学的な制約条件で式の範囲をずっと小さな集合にできる.

この規則は,v[x_,1-x_]の構造を持つ式にだけ適用される.
In[6]:=
Click for copyable input
この式は規則と同じ形なので規則が適用されることになる.
In[7]:=
Click for copyable input
Out[7]=
この式は,数学的に同じ形を取っているが,構造が違う.このため規則は適用されない.
In[8]:=
Click for copyable input
Out[8]=
この規則は,条件y==1-xが付いているので,w[x_,y_]の形の式ならばどれにでも適用される.
In[9]:=
Click for copyable input
新規則は,この式には適用されない.
In[10]:=
Click for copyable input
Out[10]=

パターンと変換規則を組み合せて設定する際,式によっては,/;の制約条件を加える位置を選択することができる.例えば,規則の右辺に lhs:>rhs/;condition という形式で/;の条件を加えることも,左辺に lhs/;condition->rhs という形式で加えることもできる.さらに,左辺 lhs の内部に条件を挿入することも可能である.ただし,制限事項が1つある.それは,制約条件が付加されたパターンの記述において,すべてのパターンの参照名が明記されている必要がある,という事項である.これがないと,実際に制約条件を評価する際に,必要な参照名がまだパターンマッチングのプロセスに組み込まれていないという状況に陥ってしまい,制約条件の評価が続けられなくなってしまう.そうなると,パターンマッチングから参照したはずのオブジェクトは使えなくなるので,代りに,変数には大域的な値が適用されることになる.

例を見てみよう.f[x_,y_]/;(x+y<2)で示される制約条件は,f[x_,y_]のパターンマッチングから得られる変数xyを必要とする.しかし,f[x_/;x+y<2,y_]における制約条件では,パターンマッチングから取得したyではなく,その大域的な値が適用される.

適切な参照名がパターンに与えられていれば,なるべく小さいパターンを選び,そこに/;の制約条件を適用するようにしておくと検索効率を向上させることができる.その理由は,パターンマッチングはパターン式の先頭から末尾に向かって要素の1つずつに対して行われるので,/;の制約条件が早く見付かれば見付かるほど候補を早く絞り込めるからである.

パターン全部に制約条件/;を適用させるより,x_にだけ適用した方がわずかではあるが,効率が上がる.
In[11]:=
Click for copyable input
Out[11]=
複文型の従属部に制約条件/;を使う場合は丸カッコでくくっておかなければならない.
In[12]:=
Click for copyable input
Out[12]=

/;を使いパターンと変換規則を設けるときは,特定の性質や型を持つ数や式に限って適用可能になるようにするのが普通である.Wolfram言語には式の性質を識別するための組込み関数が用意されているので,それらを使い判定作業を行うとよい.組込み関数には,英語の「質問」を意味する単語「Question」から取ったローマ字Qで終る名前が付いているので分かりやすいだろう.

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 と同じである完全配列

数の型や数学的な性質を調べるための判定関数

この規則は,数の型を持つリスト要素だけに適用される.
In[13]:=
Click for copyable input
Out[13]=
この定義は,要素を整数とするベクトルについてだけ適用される.
In[14]:=
Click for copyable input
この定義は,この場合,最初のケースにだけ適用される.
In[15]:=
Click for copyable input
Out[15]=

名前の最後にQの付いたWolfram言語のプロパティ判定関数のすべてについて言える注意点として,判定する式の型や式の性質が確定していない場合,判定関数はFalseを返す,ということがある.

4561は整数なので,Trueが返される.
In[16]:=
Click for copyable input
Out[16]=
xは未知数なので型は未定である.このため,Falseが返される.
In[17]:=
Click for copyable input
Out[17]=

IntegerQ[x]のような関数は,x が明示的な整数かどうかを判定する.x in Integersのような推定の場合,RefineSimplifyあるいは関連関数を使って,記号変数 x についての推測をすることができる.

SameQ[x,y] または x===yxy は等しい
UnsameQ[x,y] または x=!=yxy は等しくない
OrderedQ[{a,b,}]標準的な並び順でリスト要素 a, b, が配置されているかどうかを判定する
MemberQ[expr,form]expr の要素に form にマッチするものがあるかどうか
FreeQ[expr,form]expr の要素に form がないかどうか
MatchQ[expr,form]expr がパターン form にマッチするかどうか
ValueQ[expr]expr に特定値が定義されているかどうか
AtomQ[expr]expr が部分式を持たない最小単位のものかどうか

式の構成上の性質を調べるための判定関数

二重イコール(==)の式は,シンボル的な形のまま維持される.三重イコール(===)は,両辺の式が明らかに等しくなければFalseを返す.
In[18]:=
Click for copyable input
Out[18]=
nは,リスト{x,x^n}の「メンバー」ではない.
In[19]:=
Click for copyable input
Out[19]=
しかし,式nは,{x,x^n}には現れる.
In[20]:=
Click for copyable input
Out[20]=
FreeQを使い,hに関する「線形性」規則を定義することができる.
In[21]:=
Click for copyable input
xが不在な項はhの項から引き抜かれてしまう.
In[22]:=
Click for copyable input
Out[22]=
pattern?test判定 test の判定結果をTrueとする式だけにパターンを適用する

パターン適用範囲のもうひとつの限定法

条件構築 pattern/;condition を使うことで,パターン名を含む条件を評価させ,適合するものがあるかどうかを判定させることができる.これに対して,条件構築 pattern?test を使うと,任意関数 testpattern によりマッチングされた式全体に適用され,適合するものがあるかどうかが判定される.場合によっては,/;の代りに?を使った方がよりコンパクトな形の定義にすることができる.

この定義では,x_により抽出される前にNumberQで型が数かどうかを判定される.
In[23]:=
Click for copyable input
この定義は,pが数的な引数を持つときだけに適用される.
In[24]:=
Click for copyable input
Out[24]=
さらに複雑な定義を使う.純関数を丸カッコでくくることを忘れないように注意.
In[25]:=
Click for copyable input
この定義は,特定のケースにしか適用されない.
In[26]:=
Click for copyable input
Out[26]=
Except[c]c 以外のすべての式にマッチするパターン
Except[c,patt]patt にはマッチするが c にはマッチしないパターン

例外を含むパターン

これは0以外のすべての要素を与える.
In[27]:=
Click for copyable input
Out[27]=
Exceptはパターンを引数として取ることができる.
In[28]:=
Click for copyable input
Out[28]=
これで,0以外の整数を拾う.
In[29]:=
Click for copyable input
Out[29]=

Except[c]は,c 以外の「あらゆるもの」にマッチする,ある意味できわめて一般的なパターンである.場合によっては,patt にマッチする式から始めて,次に c にマッチする式を除外するExcept[c,patt]を使わなければならないこともあるだろう.