patmatch - パターンの適合
使い方
patmatch(expr, pattern)
patmatch(expr, pattern, 's')
パラメータ
expr - パターンに適合するかどうかを調べる式
pattern - 適合すべきパターン
's' - オプションの名前
|
説明
|
|
•
|
patmatch 関数は、expr が pattern に適合していれば true を返し、そうでなければ false を返します。patmatch が成功すると、s に subs(s, pattern) = expr を満たす代入集合が割り当てられます。
|
•
|
パターンは式で、:: を使って型宣言された変数を含んでいます。たとえば、a::radnum は a は radnum 型の式に適合されることを意味します。たとえば、a::realcons+x という和の中では a は 0 になり得るし、a::realcons*x という積の中では a は 1 になりえます(0 にはなりません)。この振る舞いを阻止するには、型を囲んで nonunit という特別なキーワードを使います。たとえば、a::nonunit(realcons)*x に x は適合しません。
|
•
|
重複するパターン: 式が 1 つのパターンに異なる方法で適合することもあります。たとえば、2+Pi を a::integer+b::realcons に当てはめてみると、a=0,b=2+Pi とも a=2, b=Pi とも解釈できます。パターンに重複がないようにするのはユーザの責任です。
|
•
|
可換性に関する注意。パターン・マッチャーは可換な演算 + と * に対応します。a::realcons*x+b::algebraic というパターンが与えられると、初めに realcons *x の形の項を探し、その後で、残りの項の和を b とします。
|
•
|
追加条件のあるパターンを表現するために、conditional という特別なキーワードが用意されています。これはそのパターンに関する条件を追加してテーブルの中のパターンをプログラミングするために使います。その構文は conditional(pattern,condition) と conditional(pattern=right-hand side, condition) で table や define における規則と同じです。たとえば、int(a::algebraic,x::name)=a*x,'type(a,freeof(x)') のようなパターンを表すことに使えます。これは int(a::freeof(x),x::name) と同じではありません。なぜなら、パターン・マッチャーが a を見つけた時点では、x はまだ何なのかわからないからです。その条件は未評価のままであるか、不活性形式でなければならないことに注意しましょう。たとえば、_type(a,.freeof(x)) のように各名前の前に `_` を置きます。また、`=` や `<>` を使うことはできません。
|
•
|
線形パターンや他のパターンとの適合: a::nonunit(algebraic)+b::nonunit(algebraic) というパターンには2個以上の項をも含む和が適合します。(これは * の場合も同様です。) a::nonunit(algebraic)+b::algebraic には1つの項だけからなる式と複数の項を含む和が適合します。なお、define では、linear と multilinear というより効果的なコードを生成するキーワードが用意されています。x^::nonunit(integer) には x の整数ベキが適合しますが、x は適合しません。
|
|
|
例
|
|
>
|
patmatch(x,a::realcons*x+b::realcons,'la');la;
|
| (2.1) |
>
|
patmatch(sqrt(3)*x-ln(4)*Pi/5-exp(1),a::realcons*x+b::realcons,'la');la;
|
| (2.2) |
>
|
patmatch(exp(1/2*Pi),exp(n::radnum*Pi),'la');la;
|
| (2.3) |
条件付きのパターンの例
>
|
patmatch(2*x+5,conditional(a::integer*x+b::integer,a^2<b),'la');la;
|
| (2.4) |
>
|
patmatch(2*x+2,conditional(a::integer*x+b::integer,a^2<b),'la');
|
| (2.5) |
>
|
patmatch(11*x+6,conditional(a::integer*x+b::integer,a>b and _type(a,prime) and not a<0),'la');
|
| (2.6) |
nonunit を使った例
>
|
patmatch(x^2,x^n::nonunit(integer),'la');la;
|
| (2.7) |
>
|
patmatch(x,x^n::nonunit(integer),'la');
|
| (2.8) |
可換性に関する例
>
|
patmatch(f(x,y,x+y),f(a::name,b::name,a::name+b::name),'la');la;
|
| (2.9) |
>
|
patmatch(f(y,x,x+y),f(a::name,b::name,a::name+b::name),'la');la;
|
| (2.10) |
和における適合の例
>
|
patmatch(a+b+c,A::nonunit(algebraic)+B::nonunit(algebraic),'la');la;
|
| (2.11) |
>
|
patmatch(a,A::nonunit(algebraic)+B::nonunit(algebraic),'la');
|
| (2.12) |
>
|
patmatch(a+exp(x)-Pi,A::nonunit(algebraic)+B::nonunit(algebraic),'la');la;
|
| (2.13) |
>
|
patmatch(a+exp(x)-Pi,A::nonunit(algebraic)+B::algebraic,'la');la;
|
| (2.14) |
>
|
patmatch(a,A::nonunit(algebraic)+B::algebraic,'la');la;
|
| (2.15) |
|
|