2 * Introduction to Rules and Patterns::
3 * Functions and Variables for Rules and Patterns::
6 @c -----------------------------------------------------------------------------
7 @node Introduction to Rules and Patterns, Functions and Variables for Rules and Patterns, Rules and Patterns, Rules and Patterns
8 @section Introduction to Rules and Patterns
9 @c -----------------------------------------------------------------------------
11 この節ではユーザー定義のパターンマッチングと整理ルールを記述します。
12 幾分違ったパターンマッチング体系を実装した2つの関数グループがあります。
13 1つのグループは、@code{tellsimp}, @code{tellsimpafter}, @code{defmatch},
14 @code{defrule}, @code{apply1}, @code{applyb1}, @code{apply2}です。
15 他のグループは、@code{let}, @code{letsimp}です。
17 @code{matchdeclare}が宣言したパターン変数を使ってパターンを定義します。
19 @code{tellsimp}と@code{tellsimpafter}が定義するパターンマッチングルールは、
20 Maximaの整理器によって自動的に適用されます。
21 @code{defmatch}, @code{defrule}, @code{let}によって定義されたルールは、
22 明示的に関数をコールすることで適用されます。
24 更に、@code{tellrat}が多項式に適用するルール用メカニズムと、
25 @code{affine}パッケージの可換/非可換代数用メカニズムがあります。
28 @category{Simplification}
29 @category{Rules and patterns}
32 @c end concepts Rules and Patterns
34 @c -----------------------------------------------------------------------------
35 @node Functions and Variables for Rules and Patterns, , Introduction to Rules and Patterns, Rules and Patterns
36 @section Functions and Variables for Rules and Patterns
37 @c -----------------------------------------------------------------------------
39 @c NEEDS CLARIFICATION AND EXAMPLES
41 @c -----------------------------------------------------------------------------
43 @deffn {関数} apply1 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
45 @var{rule_1}を @var{expr}に、失敗するまで繰り返し適用して、
46 それから同じルールを @var{expr}の部分式すべてに左から右へ、
47 部分式すべてで @var{rule_1}が失敗するまで繰り返し適用します。
49 この方法で @var{expr}を変換した結果を @var{expr_2}と呼ぶことにします。
50 次に、 @var{rule_2}を @var{expr_2}の最上部から始めて同じ方法で適用します。
51 @var{rule_n}が最後の部分式上で失敗する時、結果が返されます。
53 @code{maxapplydepth}は、
54 @code{apply1}と @code{apply2}が処理する最も深い部分式の深さです。
56 @code{applyb1}, @code{apply2}, @code{let}も参照してください。
59 @category{Rules and patterns}
63 @c NEEDS CLARIFICATION AND EXAMPLES
65 @c -----------------------------------------------------------------------------
67 @deffn {関数} apply2 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
69 もし@var{rule_1}が与えられた部分式上で失敗したら、
70 @var{rule_2}が繰り返し適用されます、などなど。
71 すべてのルールが与えられた部分式上で失敗した時だけ、
72 ルールの全組が次の部分式に繰り返し適用されます。
74 同じ部分式が最初のルールから再処理されます。
76 @code{maxapplydepth}は、
77 @code{apply1}と@code{apply2}が処理する最も深い部分式の深さです。
79 @code{apply1}と@code{let}も参照してください。
82 @category{Rules and patterns}
86 @c NEEDS CLARIFICATION AND EXAMPLES
88 @c -----------------------------------------------------------------------------
90 @deffn {関数} applyb1 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
96 @var{rule_1}がトップレベルの式で失敗するまで、
97 同じルールを1つ高いレベル(すなわち、より大きな部分式)に適用します。
98 その後、@var{rule_2}が@var{rule_1}の結果に
100 @var{rule_n}がトップレベルの式に適用された後、結果が返されます。
103 @code{apply1}に似ていますが、
104 トップダウンからの代わりにボトムアップから働きます。
106 @code{maxapplyheight}は
107 @code{applyb1}が、あきらめる前に届く
110 @code{apply1}, @code{apply2}, @code{let}も参照してください。
113 @category{Rules and patterns}
117 @c -----------------------------------------------------------------------------
118 @anchor{current_let_rule_package}
119 @defvr {オプション変数} current_let_rule_package
120 デフォルト値: @code{default_let_rule_package}
122 @code{current_let_rule_package}は、
123 もし他のルールパッケージが指定されないなら、
124 (@code{letsimp}など)@code{let}パッケージの関数で使われる
126 @c NEED TO GIVE AN EXPLICIT LIST HERE (NOT "ETC")
127 この変数は、@code{let}コマンドを介して定義された任意の規格パッケージの名前を
131 @code{letsimp (expr, rule_pkg_name)}のようなコールがされたら、
132 ルールパッケージ@code{rule_pkg_name}は
134 @code{current_let_rule_package}の値は変わりません。
137 @category{Rules and patterns}
141 @c -----------------------------------------------------------------------------
142 @anchor{default_let_rule_package}
143 @defvr {オプション変数} default_let_rule_package
144 @c DEFAULT BINDING OF default_let_rule_package IS default_let_rule_package (BOUND TO ITSELF)
145 デフォルト値: @code{default_let_rule_package}
147 @c THIS IS SORT OF CONFUSING. PROBABLY NEED TO GIVE MORE DETAIL HERE
148 @code{default_let_rule_package}は、
150 また、@code{current_let_rule_package}の値を変更することによって、
155 @category{Rules and patterns}
159 @c -----------------------------------------------------------------------------
161 @deffn {関数} defmatch (@var{progname}, @var{pattern}, @var{x_1}, @dots{}, @var{x_n})
162 @deffnx {関数} defmatch (@var{progname}, @var{pattern})
164 @var{pattern}にマッチするか見るために @var{expr}をテストする
165 関数@code{@var{progname}(@var{expr}, @var{x_1}, ..., @var{x_n})}
170 パターン引数 @var{x_1}, ..., @var{x_n}を含む式です。
171 パターン引数は @code{defmatch}の引数として明示的に与えます。
172 一方、@code{matchdeclare}関数がパターン変数を宣言します。
173 @code{matchdeclare}のパターン変数か @code{defmatch}のパターン引数として宣言されていない
176 生成関数@var{progname}の最初の引数はパターンに対してマッチされる式であり、
177 他の引数は、パターンの中のダミー変数@var{x_1}, ..., @var{x_n}に対応する
182 左辺がパターン引数やパターン変数で、右辺がパターン引数や変数がマッチした部分式の
184 パターン変数はそれらがマッチした部分式に割り当てられますが、
187 @var{progname}は @code{false}を返します。
189 リテラルパターン(すなわち、パターン引数もパターン変数も含まないパターン)は、
193 @code{matchdeclare}, @code{defrule}, @code{tellsimp}, @code{tellsimpafter}も
198 @code{a}と@code{b}は@code{x}を含まず、
200 形式@code{a*x + b}かどうか見るために
202 関数@code{linearp(expr, x)}を定義します。
203 パターン引数@code{x}が@code{defmatch}に与えられているので、
206 @c HOW HARD WILL MAXIMA TRY TO COLLECT TERMS AND DO OTHER MUNGEING TO FIT THE PATTERN ??
209 @c matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
211 @c defmatch (linearp, a*x + b, x);
212 @c linearp (3*z + (y + 1)*z + y^2, z);
218 (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
221 (%i2) defmatch (linearp, a*x + b, x);
223 (%i3) linearp (3*z + (y + 1)*z + y^2, z);
225 (%o3) [b = y , a = y + 4, x = z]
235 @code{a}と@code{b}は@code{x}を含まず、
237 形式@code{a*x + b}かどうか見るために
239 関数@code{linearp(expr, x)}を定義します。
240 @code{defmatch}にパターン引数が与えられていないので、
242 他の任意の変数ではなく変数@code{x}に関する線形式にマッチします。
245 @c matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
247 @c defmatch (linearp, a*x + b);
248 @c linearp (3*z + (y + 1)*z + y^2);
249 @c linearp (3*x + (y + 1)*x + y^2);
252 (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
255 (%i2) defmatch (linearp, a*x + b);
257 (%i3) linearp (3*z + (y + 1)*z + y^2);
259 (%i4) linearp (3*x + (y + 1)*x + y^2);
261 (%o4) [b = y , a = y + 4]
266 関数@code{checklimits(expr)}を定義します。
269 @c matchdeclare ([a, f], true);
270 @c constinterval (l, h) := constantp (h - l);
271 @c matchdeclare (b, constinterval (a));
272 @c matchdeclare (x, atom);
274 @c defmatch (checklimits, 'integrate (f, x, a, b));
276 @c 'integrate (sin(t), t, %pi + x, 2*%pi + x);
280 (%i1) matchdeclare ([a, f], true);
282 (%i2) constinterval (l, h) := constantp (h - l);
283 (%o2) constinterval(l, h) := constantp(h - l)
284 (%i3) matchdeclare (b, constinterval (a));
286 (%i4) matchdeclare (x, atom);
290 (%i6) defmatch (checklimits, 'integrate (f, x, a, b));
294 (%i8) 'integrate (sin(t), t, %pi + x, 2*%pi + x);
304 (%i9) checklimits (%);
305 (%o9) [b = x + 2 %pi, a = x + %pi, x = t, f = sin(t)]
309 @category{Rules and patterns}
313 @c NEEDS CLARIFICATION AND EXAMPLES
315 @c -----------------------------------------------------------------------------
317 @deffn {関数} defrule (@var{rulename}, @var{pattern}, @var{replacement})
319 与えられたパターンに関する置き換えルールを定義し、名付けます。
320 もし@var{rulename}と名付けられたルールが
321 (@code{apply1}, @code{applyb1}, @code{apply2}によって)
323 パターンにマッチするすべての部分式はreplacementで置き換えられます。
324 パターンマッチが値を割り当てるreplacementの中の変数すべては
325 その後整理される置き換えの中のそれらの値を割り当てられます。
328 パターンマッチと置き換えの1演算で式を変換する
330 マッチが失敗したら、ルール関数は@code{false}を返します。
333 @category{Rules and patterns}
339 @c -----------------------------------------------------------------------------
341 @deffn {関数} disprule (@var{rulename_1}, ..., @var{rulename_2})
342 @deffnx {関数} disprule (all)
344 @code{defrule}, @code{tellsimp}, @code{tellsimpafter}が返すような、または
345 @code{defmatch}が定義するパターンのような、
346 名前@var{rulename_1}, ..., @var{rulename_n}を持つルールを
348 ルールそれぞれは中間式ラベル(@code{%t})と一緒に表示されます。
350 @code{disprule (all)}は、ルールすべてを表示します。
352 @code{disprule}は引数をクォートします。
354 表示されたルールに対応する中間式ラベルのリストを返します。
356 @code{let}が定義したルールを表示する
357 @code{letrules}も参照してください。
362 @c tellsimpafter (foo (x, y), bar (x) + baz (y));
363 @c tellsimpafter (x + y, special_add (x, y));
364 @c defmatch (quux, mumble (x));
365 @c disprule (foorule1, "+rule1", quux);
369 (%i1) tellsimpafter (foo (x, y), bar (x) + baz (y));
370 (%o1) [foorule1, false]
371 (%i2) tellsimpafter (x + y, special_add (x, y));
372 (%o2) [+rule1, simplus]
373 (%i3) defmatch (quux, mumble (x));
375 (%i4) disprule (foorule1, "+rule1", quux);
376 (%t4) foorule1 : foo(x, y) -> baz(y) + bar(x)
378 (%t5) +rule1 : y + x -> special_add(x, y)
380 (%t6) quux : mumble(x) -> []
382 (%o6) [%t4, %t5, %t6]
384 (%o6) [foorule1 : foo(x, y) -> baz(y) + bar(x),
385 +rule1 : y + x -> special_add(x, y), quux : mumble(x) -> []]
389 @category{Rules and patterns}
390 @category{Display functions}
394 @c -----------------------------------------------------------------------------
396 @deffn {関数} let (@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n})
397 @deffnx {関数} let ([@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n}], @var{package_name})
399 @var{prod}は@var{repl}で置き換えられるような
400 @code{letsimp}のための代入ルールを定義します。
401 @var{prod}は、以下の項の正または負のべきの積です:
405 @code{letsimp}をコールする以前に@code{matchdeclare}関数が
406 述語論理をアトムと関連づけるために使われないなら、
407 @code{letsimp}が文字通りに検索するアトム。
408 この場合、@code{letsimp}はアトムを述語論理を満たす積の任意の項にマッチさせます。
410 @code{sin(x)}, @code{n!}, @code{f(x,y)}などのようなカーネル。
412 述語論理をカーネルの引数に関連づけるために
413 @code{matchdeclare}が使われないなら
414 @code{letsimp}は文字通りのマッチを検索します。
417 正のべきの項は、少なくともそのべきを持つ項だけにマッチするでしょう。
418 一方、負のべきの項は、少なくとも負としてのべきをもつ項だけにマッチするでしょう。
419 @var{prod}の中の負のべきの場合、
420 スイッチ@code{letrat}を@code{true}に設定しなければいけません。
421 @code{letrat}も参照してください。
424 引数のリストが続く@code{let}関数に含まれるなら、
425 @var{arg_i'}が@var{arg_i}にマッチした値である場合、
426 @code{predname (arg_1', ..., arg_n')}が@code{true}に評価される時だけ
427 試験的なマッチ(すなわち、述語論理が省略されたなら受け入れられるもの)
429 @var{arg_i}は、任意のアトム名や
430 @var{prod}の中に現れる任意の核の引数を取り得ます。
431 @var{repl}は、任意の有理式を取り得ます。
432 @c ONLY RATIONAL -- REALLY ??
434 任意のアトムや@var{prod}からの引数が@var{repl}の中に現れるなら、
436 @c SPELL OUT "APPROPRIATE" IN THIS CONTEXT
438 グローバルフラグ@code{letrat}は、
439 @code{letsimp}による商の整理を制御します。
440 @code{letrat}が@code{false}の時、
442 @var{expr}の分子と分母をそれぞれ整理し、章を整理はしません。
443 @code{n!/n}のような代入は@code{(n-1)!}に進み失敗します。
444 @code{letrat}が@code{true}の時、
447 これらの代入関数は、同時にいくつかのルールパッケージを使うことを許します。
449 任意の数の@code{let}ルールを含むことができ、ユーザー定義名で参照されます。
450 コマンド@code{let ([@var{prod}, @var{repl}, @var{predname}, @var{arg_1},
451 ..., @var{arg_n}], @var{package_name})}は、
452 ルール@var{predname}をルールパッケージ@var{package_name}に加えます。
453 コマンド@code{letsimp (@var{expr}, @var{package_name})} は、
454 @var{package_name}の中でルールを適用します。
455 @code{letsimp (@var{expr}, @var{package_name1}, @var{package_name2}, ...)}は、
456 @code{letsimp (%, @var{package_name2})}, @dots{}が続く
457 @code{letsimp (@var{expr}, @var{package_name1})}と同値です。
459 @code{current_let_rule_package}は、
460 現在使われているルールパッケージの名前です。
462 @code{let}コマンドを介して定義された任意のルールパッケージの名前に割れ当てられます。
463 @code{let}パッケージを構成する関数のいずれかがパッケージ名なしでコールされた時はいつでも
464 @code{current_let_rule_package}が指定したパッケージが使われます。
466 @code{letsimp (@var{expr}, @var{rule_pkg_name})}のようなコールがされたら、
467 ルールパッケージ@var{rule_pkg_name}は、
468 その@code{letsimp}コマンドだけで使われ、
469 @code{current_let_rule_package}は変わりません。
471 @code{current_let_rule_package}は@code{default_let_rule_package}をデフォルト値とします。
474 (%i1) matchdeclare ([a, a1, a2], true)$
475 (%i2) oneless (x, y) := is (x = y-1)$
476 (%i3) let (a1*a2!, a1!, oneless, a2, a1);
477 (%o3) a1 a2! --> a1! where oneless(a2, a1)
479 (%i5) let (a1!/a1, (a1-1)!);
481 (%o5) --- --> (a1 - 1)!
483 (%i6) letsimp (n*m!*(n-1)!/m);
485 (%i7) let (sin(a)^2, 1 - cos(a)^2);
487 (%o7) sin (a) --> 1 - cos (a)
488 (%i8) letsimp (sin(x)^4);
490 (%o8) cos (x) - 2 cos (x) + 1
493 @c NEEDS ADDITIONAL EXAMPLES
495 @category{Rules and patterns}
499 @c -----------------------------------------------------------------------------
501 @defvr {オプション変数} letrat
504 @code{letrat}が@code{false}の時、
509 @code{letrat}が@code{true}の時、
513 (%i1) matchdeclare (n, true)$
514 (%i2) let (n!/n, (n-1)!);
516 (%o2) -- --> (n - 1)!
519 (%i4) letsimp (a!/a);
524 (%i6) letsimp (a!/a);
529 @category{Rules and patterns}
535 @c -----------------------------------------------------------------------------
537 @deffn {関数} letrules ()
538 @deffnx {関数} letrules (@var{package_name})
541 @code{letrules ()}は現在のルールパッケージのルールを表示します。
542 @code{letrules (@var{package_name})}は
543 @var{package_name}のルールを表示します。
546 @code{current_let_rule_package}によって指名されます。
548 @code{current_let_rule_package}は@code{default_let_rule_package}がデフォルト値になります。
550 @code{disprule}も参照してください
552 @code{tellsimp}と@code{tellsimpafter}が定義するルールを表示します。
553 @c WHAT ABOUT defmatch AND defrule ??
556 @category{Rules and patterns}
560 @c -----------------------------------------------------------------------------
562 @deffn {関数} letsimp (@var{expr})
563 @deffnx {関数} letsimp (@var{expr}, @var{package_name})
564 @deffnx {関数} letsimp (@var{expr}, @var{package_name_1}, @dots{}, @var{package_name_n})
567 繰り返し、@code{let}が定義する代入ルールを適用します。
569 @code{letsimp (@var{expr})}は
570 @code{current_let_rule_package}からルールを使います。
572 @code{letsimp (@var{expr}, @var{package_name})}は、
573 @code{current_let_rule_package}を変えることなしに
574 @var{package_name}からルールを使います。
576 @code{letsimp (@var{expr}, @var{package_name_1}, ..., @var{package_name_n})}は、
578 @code{letsimp (%, @var{package_name_2})}などが続く
579 @code{letsimp (@var{expr}, @var{package_name_1}}と同値です。
583 @category{Rules and patterns}
587 @c -----------------------------------------------------------------------------
588 @anchor{let_rule_packages}
589 @defvr {オプション変数} let_rule_packages
590 デフォルト値: @code{[default_let_rule_package]}
592 @code{let_rule_packages}は、
593 デフォルトパッケージ@code{default_let_rule_package}に加える
594 ユーザー定義のletルールパッケージすべてのリストです。
597 @category{Rules and patterns}
601 @c -----------------------------------------------------------------------------
602 @anchor{matchdeclare}
603 @deffn {関数} matchdeclare (@var{a_1}, @var{pred_1}, ..., @var{a_n}, @var{pred_n})
605 述語論理 @var{pred_k}を変数 @var{a_k}の変数やリストに関連づけます。
606 なので、 @var{a_k}は述語論理が @code{false}以外の何かを返す式にマッチします。
608 述語論理は関数の名前、ラムダ式、関数コール、最後の引数のないラムダコール、
609 @code{true}または @code{all}です。
610 任意の式が @code{true}や @code{all}にマッチします。
611 もし述語論理が関数コールかラムダコールとして指定されるなら、
612 テストされる式が引数のリストに追加されます;
614 そうでないなら、述語論理は関数名またはラムダ式として指定され、
616 @code{matchdeclare}がコールされた時、述語論理関数は定義されている必要はありません;
617 述語論理はマッチが試みられるまで評価されません。
620 @code{true}か @code{false}はもちろん、ブーリアン式を返すかもしれません。
621 ブーリアン式は、構成されたルール関数内で @code{is}によって評価されるので、
622 述語論理内部で @code{is}をコールする必要はありません。
626 例外は足し算 @code{+}や掛け算 @code{*}のオペランドのマッチ変数です。
628 他のn項演算子(組み込みもユーザー定義も)は通常の関数のように扱われます。
629 @c WOULD BE GREAT TO EXTEND PART+/PART* PROCESSING TO ALL N-ARY OPERATORS
632 マッチ変数はマッチ述語論理を満たす唯一の式か、
633 そんな式の(それぞれ)和または積に割り当てられます。
634 そんな多項マッチングはどん欲(greedy)です:
635 述語論理群はそれらの関連変数がマッチパターンの中で現れる順に評価され、
636 複数の述語論理を満たす項は、それが満たす最初の述語論理によってマッチされます。
639 和や積のオペランドすべてに対してテストされます。
641 もし(それぞれ)0か1がマッチ述語論理を満たし、かつ、
643 0か1が述語論理の関連マッチ変数に割り当てられます。
645 足し算と掛け算パターンを処理するアルゴリズムは、
646 (例えば、「任意のものにマッチする」変数が現れるパターンのように)
647 マッチパターンの中やマッチされる式の中の項の順序付けに依存したいくつかのマッチ結果をもたらします。
648 しかしながら、もしマッチ述語論理すべてが相互に排他的なら、
649 1つのマッチ述語論理はべつのものがマッチした項を受け入れられないので、
652 変数 @var{a}を引数として @code{matchdeclare}をコールすると、
654 @var{a}に関する @code{matchdeclare}プロパティが変わります:
655 ルールが定義された時、直近の @code{matchdeclare}だけが効果を持ちます。
656 (@code{matchdeclare}か @code{remove}を介した)
657 @code{matchdeclare}プロパティへの後の変更は、存在するルールに影響しません。
659 @code{propvars (matchdeclare)}は
660 @code{matchdeclare}プロパティを持つ変数すべてのリストを返します。
661 @code{printprops (@var{a}, matchdeclare)}は、
662 変数 @code{a}に関する述語論理を返します。
663 @code{printprops (all, matchdeclare)}は、
664 すべての @code{matchdeclare}変数に関する述語論理のリストを返します。
665 @code{remove (@var{a}, matchdeclare)}は、
666 @var{a}から @code{matchdeclare}プロパティを削除します。
668 関数 @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{tellsimpafter}, @code{let}は、パターンに対して式をテストするルールを構成します。
670 @code{matchdeclare}は引数をクォートします。
671 @code{matchdeclare}はいつも @code{done}を返します。
675 述語論理は、関数名か、ラムダ式か、最後の引数がない関数コールかラムダコールか、
676 @code{true}か @code{all}です。
679 @c matchdeclare (aa, integerp);
680 @c matchdeclare (bb, lambda ([x], x > 0));
681 @c matchdeclare (cc, freeof (%e, %pi, %i));
682 @c matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
683 @c matchdeclare (ee, true);
684 @c matchdeclare (ff, all);
687 (%i1) matchdeclare (aa, integerp);
689 (%i2) matchdeclare (bb, lambda ([x], x > 0));
691 (%i3) matchdeclare (cc, freeof (%e, %pi, %i));
693 (%i4) matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
695 (%i5) matchdeclare (ee, true);
697 (%i6) matchdeclare (ff, all);
705 @c matchdeclare (aa, integerp, bb, atom);
706 @c defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
710 (%i1) matchdeclare (aa, integerp, bb, atom);
712 (%i2) defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
714 (%o2) r1 : bb -> [integer = aa, atom = bb]
716 (%o3) [integer = 8, atom = %pi]
720 マッチ変数は、マッチ述語論理を満たす1つの式か、
721 そんな式の(それぞれ)和か積に割り当てられるかもしれません。
724 @c matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
725 @c defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
727 @c r1 (8 + a*b + sin(x));
728 @c defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
730 @c r2 (8 * (a + b) * sin(x));
733 (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
735 (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
737 bb + aa partitions `sum'
738 (%o2) r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
739 (%i3) r1 (8 + a*b + sin(x));
740 (%o3) [all atoms = 8, all nonatoms = sin(x) + a b]
741 (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
743 bb aa partitions `product'
744 (%o4) r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
745 (%i5) r2 (8 * (a + b) * sin(x));
746 (%o5) [all atoms = 8, all nonatoms = (b + a) sin(x)]
749 @code{+}と @code{*}の引数をマッチする時、
750 もしマッチ述語論理すべてが相互に排他的なら、
751 1つのマッチ述語論理は別のものがマッチした項を受け入れられないので、
755 @c matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
756 @c defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
758 @c r1 (8 + a*b + %pi + sin(x) - c + 2^n);
759 @c defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
761 @c r2 (8 * (a + b) * %pi * sin(x) / c * 2^n);
764 (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
766 (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
768 bb + aa partitions `sum'
769 (%o2) r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
770 (%i3) r1 (8 + a*b + %pi + sin(x) - c + 2^n);
772 (%o3) [all atoms = %pi + 8, all nonatoms = sin(x) + 2 - c + a b]
773 (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
775 bb aa partitions `product'
776 (%o4) r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
777 (%i5) r2 (8 * (a + b) * %pi * sin(x) / c * 2^n);
780 (%o5) [all atoms = 8 %pi, all nonatoms = -----------------]
784 関数 @code{propvars}と @code{printprops}はマッチ変数についての情報を返します。
787 @c matchdeclare ([aa, bb, cc], atom, [dd, ee], integerp);
788 @c matchdeclare (ff, floatnump, gg, lambda ([x], x > 100));
789 @c propvars (matchdeclare);
790 @c printprops (ee, matchdeclare);
791 @c printprops (gg, matchdeclare);
792 @c printprops (all, matchdeclare);
795 (%i1) matchdeclare ([aa, bb, cc], atom, [dd, ee], integerp);
797 (%i2) matchdeclare (ff, floatnump, gg, lambda ([x], x > 100));
799 (%i3) propvars (matchdeclare);
800 (%o3) [aa, bb, cc, dd, ee, ff, gg]
801 (%i4) printprops (ee, matchdeclare);
803 (%i5) printprops (gg, matchdeclare);
804 (%o5) [lambda([x], x > 100, gg)]
805 (%i6) printprops (all, matchdeclare);
806 (%o6) [lambda([x], x > 100, gg), floatnump(ff), integerp(ee),
807 integerp(dd), atom(cc), atom(bb), atom(aa)]
811 @category{Rules and patterns}
812 @category{Declarations and inferences}
818 @c -----------------------------------------------------------------------------
819 @anchor{maxapplydepth}
820 @defvr {オプション変数} maxapplydepth
823 @code{maxapplydepth}は
824 @code{apply1}と @code{apply2}が探索する
828 @category{Function application}
834 @c -----------------------------------------------------------------------------
835 @anchor{maxapplyheight}
836 @defvr {オプション変数} maxapplyheight
839 @code{maxapplyheight}は
840 @code{applyb1}があきらめる前に到達する
844 @category{Function application}
848 @c NEEDS CLARIFICATION AND EXAMPLES
850 @c -----------------------------------------------------------------------------
852 @deffn {関数} remlet (@var{prod}, @var{name})
853 @deffnx {関数} remlet ()
854 @deffnx {関数} remlet (all)
855 @deffnx {関数} remlet (all, @var{name})
857 @code{let}関数で直近に定義された
858 代入ルール@var{prod} --> replを削除します。
859 もし名前が供給されるなら、ルールはルールパッケージ名から削除されます。
861 @code{remlet()}や@code{remlet(all)}は
862 現在のルールパッケージから代入ルールすべてを削除します。
863 もし例えば、@code{remlet (all, @var{name})}にように、ルールパッケージ名が供給されるなら、
864 ルールパッケージ@var{name}も削除されます。
867 @code{remlet}はコールされる必要はなく、
868 @code{let}関数と新しい置き換え かつ/または述語論理名で、文字通りに同じ積を使って代入を再定義だけです。
869 さて、@code{remlet (@var{prod})}がコールされると、
872 @code{remrule}も参照してください。
873 @code{tellsimp}や@code{tellsimpafter}で定義されたルールを削除します。
876 @category{Rules and patterns}
880 @c -----------------------------------------------------------------------------
882 @deffn {関数} remrule (@var{op}, @var{rulename})
883 @deffnx {関数} remrule (@var{op}, all)
885 @code{tellsimp}や@code{tellsimpafter}で定義されたルールを削除します。
887 @code{remrule (@var{op}, @var{rulename})}は、
892 (@code{infix}, @code{prefix}, などで定義されたような)ユーザー定義演算子の時、
893 @var{op}と@var{rulename}はダブルクォートマークでくくられないといけません。
895 @code{remrule (@var{op}, all)}は
896 演算子@var{op}に関するルールすべてを削除します。
898 @code{remlet}も参照してください。
899 @code{let}で定義されたルールを削除します。
904 @c tellsimp (foo (aa, bb), bb - aa);
905 @c tellsimpafter (aa + bb, special_add (aa, bb));
907 @c tellsimp (aa @@ bb, bb/aa);
908 @c tellsimpafter (quux (%pi, %e), %pi - %e);
909 @c tellsimpafter (quux (%e, %pi), %pi + %e);
910 @c [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
912 @c remrule (foo, foorule1);
913 @c remrule ("+", ?\+rule1);
914 @c remrule ("@@", ?\@\@rule1);
915 @c remrule (quux, all);
916 @c [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
920 (%i1) tellsimp (foo (aa, bb), bb - aa);
921 (%o1) [foorule1, false]
922 (%i2) tellsimpafter (aa + bb, special_add (aa, bb));
923 (%o2) [+rule1, simplus]
924 (%i3) infix ("@@@@");
926 (%i4) tellsimp (aa @@@@ bb, bb/aa);
927 (%o4) [@@@@rule1, false]
928 (%i5) tellsimpafter (quux (%pi, %e), %pi - %e);
929 (%o5) [quuxrule1, false]
930 (%i6) tellsimpafter (quux (%e, %pi), %pi + %e);
931 (%o6) [quuxrule2, quuxrule1, false]
932 (%i7) [foo (aa, bb), aa + bb, aa @@@@ bb, quux (%pi, %e),
935 (%o7) [bb - aa, special_add(aa, bb), --, %pi - %e, %pi + %e]
937 (%i8) remrule (foo, foorule1);
939 (%i9) remrule ("+", ?\+rule1);
941 (%i10) remrule ("@@@@", ?\@@\@@rule1);
943 (%i11) remrule (quux, all);
945 (%i12) [foo (aa, bb), aa + bb, aa @@@@ bb, quux (%pi, %e),
947 (%o12) [foo(aa, bb), bb + aa, aa @@@@ bb, quux(%pi, %e),
952 @category{Rules and patterns}
956 @c NEEDS EXPANSION OR MAYBE JUST APPROPRIATE REFS TO tellsimpafter
958 @c -----------------------------------------------------------------------------
960 @deffn {関数} tellsimp (@var{pattern}, @var{replacement})
962 @code{tellsimpafter}に似ていますが、
966 整理器が働く前に式を変更することが重要な時
967 例えば、整理器が式について何か「知っている」が、それが返すものが好みでないなら、
968 @code{tellsimp}が使われます。
969 もし整理器が式の主演算子について何かを「知っている」が、単に十分でないなら、
970 たぶん@code{tellsimpafter}を使いたいでしょう。
972 パターンは和、積、変数1つ、または、数は取れません。
975 @code{defrule}, @code{defmatch}, @code{tellsimp}, @code{tellsimpafter}で
981 (%i1) matchdeclare (x, freeof (%i));
984 (%i3) tellsimp (sin(%i*x), %i*sinh(x));
985 (%o3) [sinrule1, simp-%sin]
986 (%i4) trigexpand (sin (%i*y + x));
987 (%o4) sin(x) cos(%i y) + %i cos(x) sinh(y)
993 (%i7) ev (tellsimp (0^0, 1), simp: false);
994 (%o7) [^rule1, simpexpt]
997 (%i9) remrule ("^", %th(2)[1]);
999 (%i10) tellsimp (sin(x)^2, 1 - cos(x)^2);
1000 (%o10) [^rule2, simpexpt]
1001 (%i11) (1 + sin(x))^2;
1006 (%o12) 2 sin(x) - cos (x) + 2
1010 (%i14) kill (rules);
1012 (%i15) matchdeclare (a, true);
1014 (%i16) tellsimp (sin(a)^2, 1 - cos(a)^2);
1015 (%o16) [^rule3, simpexpt]
1022 @category{Rules and patterns}
1026 @c -----------------------------------------------------------------------------
1027 @anchor{tellsimpafter}
1028 @deffn {関数} tellsimpafter (@var{pattern}, @var{replacement})
1030 組み込み整理ルールの後、適Maxima整理器が適用する
1033 (@code{matchdeclare}で宣言された)
1034 パターン変数や他のアトムや演算子から成る、
1035 パターンマッチングの目的でリテラルと考えられる式です。
1037 @var{pattern}にマッチする実際の式に代入されます;
1038 @var{replacement}の中のパターン変数は
1039 実際の式の中でマッチした値に割り当てられます。
1042 主演算子がパターン変数でない任意の非アトム式を取り得ます;
1043 整理ルールは主演算子に関連付けられます。
1044 (以下で記述する1つの例外がありますが、)関数、リスト、配列の名前が、
1045 (パターン変数でなく)ただリテラルとして、
1046 主演算子として@var{pattern}の中で現れることができます;
1049 もし@code{aa}や@code{bb}がパターン変数なら
1050 @code{aa(x)}や@code{bb[y]}のような式を除外します。
1051 パターン変数である関数、リスト、配列の名前は、
1052 @var{pattern}の中で、主演算子以外の演算子として現れることができます。
1054 上の関数名に関するルールに1つ例外があります。
1055 @code{aa[x](y)}のような式の中の添字付き関数の名前は
1056 主演算子が@code{aa}でなくLispアトム@code{mqapply}だから、
1058 これは、添字付き関数を含む式の表現の結果です。
1060 @c LET'S NOT GO INTO DETAILS ABOUT MAIN OPERATORS HERE; BUT PRESERVE THIS FOR REFERENCE
1061 @c The main operator of an expression @code{expr} is @code{caar $expr}.
1062 @c For most kinds of expressions,
1063 @c the main operator is the operator returned by @code{op (@var{pattern})};
1064 @c the sole exception is the operator @code{mqapply},
1065 @c which appears in indexed function expressions (e.g., @code{foo[i](x)}).
1067 @c NEED TO REVIEW THIS PARAGRAPH FOR ACCURACY
1068 (もしクォートやフラグ@code{noeval}を通して抑制されないなら)
1071 @code{tellsimpafter}で確立されたルールは、
1072 組み込みルールの後、それらが定義された順に適用されます。
1073 ルールはボトムアップに適用されます。すなわち、
1074 式全体への適用の前に、最初、部分式に適用されます。
1075 @c NO IT IS MORE COMPLICATED THAN THIS, ALTHOUGH IN SOME CIRCUMSTANCE IT APPEARS TO BE THE CASE:
1076 @c For a given expression, at most one rule per operator is applied.
1077 ルールすべてが適用されることを保証するために、
1078 (例えば、クォートクォート演算子@code{'@w{}'}やフラグ@code{infeval}を介して)
1079 結果を繰り返し整理する必要があるかもしれません。
1081 パターン変数は、整理ルールの中でローカル変数として扱われます。
1082 一旦ルールが定義されると、パターン変数の値は、
1083 ルールに影響せず、ルールによって影響されません。
1084 成功したルールマッチの結果となるパターン変数への割り当ては、
1085 パターン変数の現在の割り当て(またはその欠落)に影響しません。
1086 しかしながら、Maximaの中のアトムすべてで、
1087 (@code{put}や関連関数で定義された)パターン変数のプロパティはグローバルです。
1089 @code{tellsimpafter}によって構成されたルールは、
1090 @var{pattern}の主演算子に由来します。
1092 @code{infix}, @code{prefix}, @code{postfix}, @code{matchfix}, @code{nofix}で
1093 定義されたユーザー定義演算子に関するルールは、
1095 @c SLIGHTLY TOO MUCH DETAIL
1096 @c (that is, the name is written with a leading question mark @code{?} in Maxima).
1097 他の関数に関するルールは、Maxima識別子である名前を持ちます。
1098 @c SLIGHTLY TOO MUCH DETAIL
1099 @c (that is, the name begins with dollar sign @code{$}).
1101 名詞と動詞形の扱いは少し混乱しています。
1103 もしルールが名詞(または動詞)形に関して定義されて、
1104 対応する動詞(または名詞)形に関するルールが既に存在しているなら、
1105 新しく定義されたルールは両方の形式(名詞と動詞)に適用されます。
1106 もし対応する動詞(名詞)形に関するルールが存在しないなら、
1107 新しく定義されたルールは名詞(または動詞)形にだけ適用されます。
1109 @code{tellsimpafter}で構成されたルールは通常のLisp関数です。
1110 もしルール名が@code{$foorule1}なら、
1111 構成子@code{:lisp (trace $foorule1)}は関数をトレースし、
1112 @code{:lisp (symbol-function '$foorule1)}は定義を表示します。
1114 @code{tellsimpafter}は引数をクォートします。
1115 @code{tellsimpafter}は
1117 @var{pattern}の主演算子に関する
1119 @c WHAT IS simpfoo THAT SOMETIMES APPEARS, AND WHY DOES false SOMETIMES APPEAR IN RETURN VALUE ??
1121 @code{matchdeclare}, @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{let}, @code{kill}, @code{remrule}, @code{clear_rules}も参照してください。
1126 主演算子がパターン変数でない任意の非アトム式を取り得ます。
1129 @c matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
1130 @c tellsimpafter (sin (ll), map (sin, ll));
1131 @c sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
1132 @c tellsimpafter (ll^mm, map ("^", ll, mm));
1133 @c [a, b, c]^[1, 2, 3];
1134 @c tellsimpafter (foo (aa (xx)), aa (foo (xx)));
1135 @c foo (bar (u - v));
1138 (%i1) matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
1139 (%i2) tellsimpafter (sin (ll), map (sin, ll));
1140 (%o2) [sinrule1, simp-%sin]
1141 (%i3) sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
1143 (%o3) [-, -------, -------, 1, 0]
1145 (%i4) tellsimpafter (ll^mm, map ("^", ll, mm));
1146 (%o4) [^rule1, simpexpt]
1147 (%i5) [a, b, c]^[1, 2, 3];
1150 (%i6) tellsimpafter (foo (aa (xx)), aa (foo (xx)));
1151 (%o6) [foorule1, false]
1152 (%i7) foo (bar (u - v));
1153 (%o7) bar(foo(u - v))
1156 ルールはそれらが定義された順に適用されます。
1157 もし2つのルールが式にマッチできるなら、
1161 @c matchdeclare (aa, integerp);
1162 @c tellsimpafter (foo (aa), bar_1 (aa));
1163 @c tellsimpafter (foo (aa), bar_2 (aa));
1167 (%i1) matchdeclare (aa, integerp);
1169 (%i2) tellsimpafter (foo (aa), bar_1 (aa));
1170 (%o2) [foorule1, false]
1171 (%i3) tellsimpafter (foo (aa), bar_2 (aa));
1172 (%o3) [foorule2, foorule1, false]
1177 整理ルールの中で、パターン変数はローカル変数として扱われます。
1178 (@code{defmatch}と比較してください。
1179 パターン変数をグローバル変数として扱います。)
1182 @c matchdeclare (aa, integerp, bb, atom);
1183 @c tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1189 (%i1) matchdeclare (aa, integerp, bb, atom);
1191 (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1192 (%o2) [foorule1, false]
1196 (%o4) bar(aa = 42, bb = %e)
1202 パターン変数のプロパティは、たとえ値がローカルでも、
1205 @code{define_variable}を介して宣言されます。
1206 Maximaの至る所で、これはアトム@code{bb}のプロパティです。
1209 @c matchdeclare (aa, integerp, bb, atom);
1210 @c tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1212 @c define_variable (bb, true, boolean);
1216 (%i1) matchdeclare (aa, integerp, bb, atom);
1218 (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1219 (%o2) [foorule1, false]
1221 (%o3) bar(aa = 42, bb = %e)
1222 (%i4) define_variable (bb, true, boolean);
1225 Error: bb was declared mode boolean, has value: %e
1226 -- an error. Quitting. To debug this try debugmode(true);
1230 組み込みやユーザー定義の演算子に関するルール名はLisp識別子で、
1231 一方、他の関数に関する名前はMaxima識別子です。
1234 @c tellsimpafter (foo (%pi + %e), 3*%pi);
1235 @c tellsimpafter (foo (%pi * %e), 17*%e);
1236 @c tellsimpafter (foo (%i ^ %e), -42*%i);
1237 @c tellsimpafter (foo (9) + foo (13), quux (22));
1238 @c tellsimpafter (foo (9) * foo (13), blurf (22));
1239 @c tellsimpafter (foo (9) ^ foo (13), mumble (22));
1241 @c foorule_name: first (%o1);
1242 @c plusrule_name: first (%o4);
1243 @c remrule (foo, foorule1);
1244 @c remrule ("^", ?\^rule1);
1248 (%i1) tellsimpafter (foo (%pi + %e), 3*%pi);
1249 (%o1) [foorule1, false]
1250 (%i2) tellsimpafter (foo (%pi * %e), 17*%e);
1251 (%o2) [foorule2, foorule1, false]
1252 (%i3) tellsimpafter (foo (%i ^ %e), -42*%i);
1253 (%o3) [foorule3, foorule2, foorule1, false]
1254 (%i4) tellsimpafter (foo (9) + foo (13), quux (22));
1255 (%o4) [+rule1, simplus]
1256 (%i5) tellsimpafter (foo (9) * foo (13), blurf (22));
1257 (%o5) [*rule1, simptimes]
1258 (%i6) tellsimpafter (foo (9) ^ foo (13), mumble (22));
1259 (%o6) [^rule1, simpexpt]
1261 (%o7) [foorule1, foorule2, foorule3, +rule1, *rule1, ^rule1]
1262 (%i8) foorule_name: first (%o1);
1264 (%i9) plusrule_name: first (%o4);
1266 (%i10) remrule (foo, foorule1);
1268 (%i11) remrule ("^", ?\^rule1);
1271 (%o12) [foorule2, foorule3, +rule1, *rule1]
1277 @c gt (i, j) := integerp(j) and i < j;
1278 @c matchdeclare (i, integerp, j, gt(i));
1279 @c tellsimpafter (s[i]^^2, 1);
1280 @c tellsimpafter (s[i] . s[j], -s[j] . s[i]);
1281 @c s[1] . (s[1] + s[2]);
1283 @c factor (expand (sum (s[i], i, 0, 9)^^5));
1286 (%i1) gt (i, j) := integerp(j) and i < j;
1287 (%o1) gt(i, j) := integerp(j) and i < j
1288 (%i2) matchdeclare (i, integerp, j, gt(i));
1290 (%i3) tellsimpafter (s[i]^^2, 1);
1291 (%o3) [^^rule1, simpncexpt]
1292 (%i4) tellsimpafter (s[i] . s[j], -s[j] . s[i]);
1293 (%o4) [.rule1, simpnct]
1294 (%i5) s[1] . (s[1] + s[2]);
1300 (%i7) factor (expand (sum (s[i], i, 0, 9)^^5));
1301 (%o7) 100 (s + s + s + s + s + s + s + s + s + s )
1306 @category{Rules and patterns}
1310 @c -----------------------------------------------------------------------------
1311 @anchor{clear_rules}
1312 @deffn {関数} clear_rules ()
1314 @code{kill (rules)}を実行し、
1315 足し算@code{+}, 掛け算@code{*}, べき@code{^}に関して
1319 @category{Rules and patterns}