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} @category{Rules and patterns}
31 @c end concepts Rules and Patterns
33 @c -----------------------------------------------------------------------------
34 @node Functions and Variables for Rules and Patterns, , Introduction to Rules and Patterns, Rules and Patterns
35 @section Functions and Variables for Rules and Patterns
36 @c -----------------------------------------------------------------------------
38 @c NEEDS CLARIFICATION AND EXAMPLES
40 @c -----------------------------------------------------------------------------
42 @deffn {関数} apply1 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
44 @var{rule_1}を @var{expr}に、失敗するまで繰り返し適用して、
45 それから同じルールを @var{expr}の部分式すべてに左から右へ、
46 部分式すべてで @var{rule_1}が失敗するまで繰り返し適用します。
48 この方法で @var{expr}を変換した結果を @var{expr_2}と呼ぶことにします。
49 次に、 @var{rule_2}を @var{expr_2}の最上部から始めて同じ方法で適用します。
50 @var{rule_n}が最後の部分式上で失敗する時、結果が返されます。
52 @code{maxapplydepth}は、
53 @code{apply1}と @code{apply2}が処理する最も深い部分式の深さです。
55 @code{applyb1}, @code{apply2}, @code{let}も参照してください。
58 @category{Rules and patterns}
62 @c NEEDS CLARIFICATION AND EXAMPLES
64 @c -----------------------------------------------------------------------------
66 @deffn {関数} apply2 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
68 もし@var{rule_1}が与えられた部分式上で失敗したら、
69 @var{rule_2}が繰り返し適用されます、などなど。
70 すべてのルールが与えられた部分式上で失敗した時だけ、
71 ルールの全組が次の部分式に繰り返し適用されます。
73 同じ部分式が最初のルールから再処理されます。
75 @code{maxapplydepth}は、
76 @code{apply1}と@code{apply2}が処理する最も深い部分式の深さです。
78 @code{apply1}と@code{let}も参照してください。
81 @category{Rules and patterns}
85 @c NEEDS CLARIFICATION AND EXAMPLES
87 @c -----------------------------------------------------------------------------
89 @deffn {関数} applyb1 (@var{expr}, @var{rule_1}, ..., @var{rule_n})
95 @var{rule_1}がトップレベルの式で失敗するまで、
96 同じルールを1つ高いレベル(すなわち、より大きな部分式)に適用します。
97 その後、@var{rule_2}が@var{rule_1}の結果に
99 @var{rule_n}がトップレベルの式に適用された後、結果が返されます。
102 @code{apply1}に似ていますが、
103 トップダウンからの代わりにボトムアップから働きます。
105 @code{maxapplyheight}は
106 @code{applyb1}が、あきらめる前に届く
109 @code{apply1}, @code{apply2}, @code{let}も参照してください。
112 @category{Rules and patterns}
116 @c -----------------------------------------------------------------------------
117 @anchor{current_let_rule_package}
118 @defvr {オプション変数} current_let_rule_package
119 デフォルト値: @code{default_let_rule_package}
121 @code{current_let_rule_package}は、
122 もし他のルールパッケージが指定されないなら、
123 (@code{letsimp}など)@code{let}パッケージの関数で使われる
125 @c NEED TO GIVE AN EXPLICIT LIST HERE (NOT "ETC")
126 この変数は、@code{let}コマンドを介して定義された任意の規格パッケージの名前を
130 @code{letsimp (expr, rule_pkg_name)}のようなコールがされたら、
131 ルールパッケージ@code{rule_pkg_name}は
133 @code{current_let_rule_package}の値は変わりません。
136 @category{Rules and patterns}
140 @c -----------------------------------------------------------------------------
141 @anchor{default_let_rule_package}
142 @defvr {オプション変数} default_let_rule_package
143 @c DEFAULT BINDING OF default_let_rule_package IS default_let_rule_package (BOUND TO ITSELF)
144 デフォルト値: @code{default_let_rule_package}
146 @c THIS IS SORT OF CONFUSING. PROBABLY NEED TO GIVE MORE DETAIL HERE
147 @code{default_let_rule_package}は、
149 また、@code{current_let_rule_package}の値を変更することによって、
154 @category{Rules and patterns}
158 @c -----------------------------------------------------------------------------
160 @deffn {関数} defmatch (@var{progname}, @var{pattern}, @var{x_1}, @dots{}, @var{x_n})
161 @deffnx {関数} defmatch (@var{progname}, @var{pattern})
163 @var{pattern}にマッチするか見るために @var{expr}をテストする
164 関数@code{@var{progname}(@var{expr}, @var{x_1}, ..., @var{x_n})}
169 パターン引数 @var{x_1}, ..., @var{x_n}を含む式です。
170 パターン引数は @code{defmatch}の引数として明示的に与えます。
171 一方、@code{matchdeclare}関数がパターン変数を宣言します。
172 @code{matchdeclare}のパターン変数か @code{defmatch}のパターン引数として宣言されていない
175 生成関数@var{progname}の最初の引数はパターンに対してマッチされる式であり、
176 他の引数は、パターンの中のダミー変数@var{x_1}, ..., @var{x_n}に対応する
181 左辺がパターン引数やパターン変数で、右辺がパターン引数や変数がマッチした部分式の
183 パターン変数はそれらがマッチした部分式に割り当てられますが、
186 @var{progname}は @code{false}を返します。
188 リテラルパターン(すなわち、パターン引数もパターン変数も含まないパターン)は、
192 @code{matchdeclare}, @code{defrule}, @code{tellsimp}, @code{tellsimpafter}も
197 @code{a}と@code{b}は@code{x}を含まず、
199 形式@code{a*x + b}かどうか見るために
201 関数@code{linearp(expr, x)}を定義します。
202 パターン引数@code{x}が@code{defmatch}に与えられているので、
205 @c HOW HARD WILL MAXIMA TRY TO COLLECT TERMS AND DO OTHER MUNGEING TO FIT THE PATTERN ??
208 @c matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
210 @c defmatch (linearp, a*x + b, x);
211 @c linearp (3*z + (y + 1)*z + y^2, z);
217 (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
220 (%i2) defmatch (linearp, a*x + b, x);
222 (%i3) linearp (3*z + (y + 1)*z + y^2, z);
224 (%o3) [b = y , a = y + 4, x = z]
234 @code{a}と@code{b}は@code{x}を含まず、
236 形式@code{a*x + b}かどうか見るために
238 関数@code{linearp(expr, x)}を定義します。
239 @code{defmatch}にパターン引数が与えられていないので、
241 他の任意の変数ではなく変数@code{x}に関する線形式にマッチします。
244 @c matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
246 @c defmatch (linearp, a*x + b);
247 @c linearp (3*z + (y + 1)*z + y^2);
248 @c linearp (3*x + (y + 1)*x + y^2);
251 (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
254 (%i2) defmatch (linearp, a*x + b);
256 (%i3) linearp (3*z + (y + 1)*z + y^2);
258 (%i4) linearp (3*x + (y + 1)*x + y^2);
260 (%o4) [b = y , a = y + 4]
265 関数@code{checklimits(expr)}を定義します。
268 @c matchdeclare ([a, f], true);
269 @c constinterval (l, h) := constantp (h - l);
270 @c matchdeclare (b, constinterval (a));
271 @c matchdeclare (x, atom);
273 @c defmatch (checklimits, 'integrate (f, x, a, b));
275 @c 'integrate (sin(t), t, %pi + x, 2*%pi + x);
279 (%i1) matchdeclare ([a, f], true);
281 (%i2) constinterval (l, h) := constantp (h - l);
282 (%o2) constinterval(l, h) := constantp(h - l)
283 (%i3) matchdeclare (b, constinterval (a));
285 (%i4) matchdeclare (x, atom);
289 (%i6) defmatch (checklimits, 'integrate (f, x, a, b));
293 (%i8) 'integrate (sin(t), t, %pi + x, 2*%pi + x);
303 (%i9) checklimits (%);
304 (%o9) [b = x + 2 %pi, a = x + %pi, x = t, f = sin(t)]
308 @category{Rules and patterns}
312 @c NEEDS CLARIFICATION AND EXAMPLES
314 @c -----------------------------------------------------------------------------
316 @deffn {関数} defrule (@var{rulename}, @var{pattern}, @var{replacement})
318 与えられたパターンに関する置き換えルールを定義し、名付けます。
319 もし@var{rulename}と名付けられたルールが
320 (@code{apply1}, @code{applyb1}, @code{apply2}によって)
322 パターンにマッチするすべての部分式はreplacementで置き換えられます。
323 パターンマッチが値を割り当てるreplacementの中の変数すべては
324 その後整理される置き換えの中のそれらの値を割り当てられます。
327 パターンマッチと置き換えの1演算で式を変換する
329 マッチが失敗したら、ルール関数は@code{false}を返します。
332 @category{Rules and patterns}
338 @c -----------------------------------------------------------------------------
340 @deffn {関数} disprule (@var{rulename_1}, ..., @var{rulename_2})
341 @deffnx {関数} disprule (all)
343 @code{defrule}, @code{tellsimp}, @code{tellsimpafter}が返すような、または
344 @code{defmatch}が定義するパターンのような、
345 名前@var{rulename_1}, ..., @var{rulename_n}を持つルールを
347 ルールそれぞれは中間式ラベル(@code{%t})と一緒に表示されます。
349 @code{disprule (all)}は、ルールすべてを表示します。
351 @code{disprule}は引数をクォートします。
353 表示されたルールに対応する中間式ラベルのリストを返します。
355 @code{let}が定義したルールを表示する
356 @code{letrules}も参照してください。
361 @c tellsimpafter (foo (x, y), bar (x) + baz (y));
362 @c tellsimpafter (x + y, special_add (x, y));
363 @c defmatch (quux, mumble (x));
364 @c disprule (foorule1, "+rule1", quux);
368 (%i1) tellsimpafter (foo (x, y), bar (x) + baz (y));
369 (%o1) [foorule1, false]
370 (%i2) tellsimpafter (x + y, special_add (x, y));
371 (%o2) [+rule1, simplus]
372 (%i3) defmatch (quux, mumble (x));
374 (%i4) disprule (foorule1, "+rule1", quux);
375 (%t4) foorule1 : foo(x, y) -> baz(y) + bar(x)
377 (%t5) +rule1 : y + x -> special_add(x, y)
379 (%t6) quux : mumble(x) -> []
381 (%o6) [%t4, %t5, %t6]
383 (%o6) [foorule1 : foo(x, y) -> baz(y) + bar(x),
384 +rule1 : y + x -> special_add(x, y), quux : mumble(x) -> []]
388 @category{Rules and patterns} @category{Display functions}
392 @c -----------------------------------------------------------------------------
394 @deffn {関数} let (@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n})
395 @deffnx {関数} let ([@var{prod}, @var{repl}, @var{predname}, @var{arg_1}, ..., @var{arg_n}], @var{package_name})
397 @var{prod}は@var{repl}で置き換えられるような
398 @code{letsimp}のための代入ルールを定義します。
399 @var{prod}は、以下の項の正または負のべきの積です:
403 @code{letsimp}をコールする以前に@code{matchdeclare}関数が
404 述語論理をアトムと関連づけるために使われないなら、
405 @code{letsimp}が文字通りに検索するアトム。
406 この場合、@code{letsimp}はアトムを述語論理を満たす積の任意の項にマッチさせます。
408 @code{sin(x)}, @code{n!}, @code{f(x,y)}などのようなカーネル。
410 述語論理をカーネルの引数に関連づけるために
411 @code{matchdeclare}が使われないなら
412 @code{letsimp}は文字通りのマッチを検索します。
415 正のべきの項は、少なくともそのべきを持つ項だけにマッチするでしょう。
416 一方、負のべきの項は、少なくとも負としてのべきをもつ項だけにマッチするでしょう。
417 @var{prod}の中の負のべきの場合、
418 スイッチ@code{letrat}を@code{true}に設定しなければいけません。
419 @code{letrat}も参照してください。
422 引数のリストが続く@code{let}関数に含まれるなら、
423 @var{arg_i'}が@var{arg_i}にマッチした値である場合、
424 @code{predname (arg_1', ..., arg_n')}が@code{true}に評価される時だけ
425 試験的なマッチ(すなわち、述語論理が省略されたなら受け入れられるもの)
427 @var{arg_i}は、任意のアトム名や
428 @var{prod}の中に現れる任意の核の引数を取り得ます。
429 @var{repl}は、任意の有理式を取り得ます。
430 @c ONLY RATIONAL -- REALLY ??
432 任意のアトムや@var{prod}からの引数が@var{repl}の中に現れるなら、
434 @c SPELL OUT "APPROPRIATE" IN THIS CONTEXT
436 グローバルフラグ@code{letrat}は、
437 @code{letsimp}による商の整理を制御します。
438 @code{letrat}が@code{false}の時、
440 @var{expr}の分子と分母をそれぞれ整理し、章を整理はしません。
441 @code{n!/n}のような代入は@code{(n-1)!}に進み失敗します。
442 @code{letrat}が@code{true}の時、
445 これらの代入関数は、同時にいくつかのルールパッケージを使うことを許します。
447 任意の数の@code{let}ルールを含むことができ、ユーザー定義名で参照されます。
448 コマンド@code{let ([@var{prod}, @var{repl}, @var{predname}, @var{arg_1},
449 ..., @var{arg_n}], @var{package_name})}は、
450 ルール@var{predname}をルールパッケージ@var{package_name}に加えます。
451 コマンド@code{letsimp (@var{expr}, @var{package_name})} は、
452 @var{package_name}の中でルールを適用します。
453 @code{letsimp (@var{expr}, @var{package_name1}, @var{package_name2}, ...)}は、
454 @code{letsimp (%, @var{package_name2})}, @dots{}が続く
455 @code{letsimp (@var{expr}, @var{package_name1})}と同値です。
457 @code{current_let_rule_package}は、
458 現在使われているルールパッケージの名前です。
460 @code{let}コマンドを介して定義された任意のルールパッケージの名前に割れ当てられます。
461 @code{let}パッケージを構成する関数のいずれかがパッケージ名なしでコールされた時はいつでも
462 @code{current_let_rule_package}が指定したパッケージが使われます。
464 @code{letsimp (@var{expr}, @var{rule_pkg_name})}のようなコールがされたら、
465 ルールパッケージ@var{rule_pkg_name}は、
466 その@code{letsimp}コマンドだけで使われ、
467 @code{current_let_rule_package}は変わりません。
469 @code{current_let_rule_package}は@code{default_let_rule_package}をデフォルト値とします。
472 (%i1) matchdeclare ([a, a1, a2], true)$
473 (%i2) oneless (x, y) := is (x = y-1)$
474 (%i3) let (a1*a2!, a1!, oneless, a2, a1);
475 (%o3) a1 a2! --> a1! where oneless(a2, a1)
477 (%i5) let (a1!/a1, (a1-1)!);
479 (%o5) --- --> (a1 - 1)!
481 (%i6) letsimp (n*m!*(n-1)!/m);
483 (%i7) let (sin(a)^2, 1 - cos(a)^2);
485 (%o7) sin (a) --> 1 - cos (a)
486 (%i8) letsimp (sin(x)^4);
488 (%o8) cos (x) - 2 cos (x) + 1
491 @c NEEDS ADDITIONAL EXAMPLES
493 @category{Rules and patterns}
497 @c -----------------------------------------------------------------------------
499 @defvr {オプション変数} letrat
502 @code{letrat}が@code{false}の時、
507 @code{letrat}が@code{true}の時、
511 (%i1) matchdeclare (n, true)$
512 (%i2) let (n!/n, (n-1)!);
514 (%o2) -- --> (n - 1)!
517 (%i4) letsimp (a!/a);
522 (%i6) letsimp (a!/a);
527 @category{Rules and patterns}
533 @c -----------------------------------------------------------------------------
535 @deffn {関数} letrules ()
536 @deffnx {関数} letrules (@var{package_name})
539 @code{letrules ()}は現在のルールパッケージのルールを表示します。
540 @code{letrules (@var{package_name})}は
541 @var{package_name}のルールを表示します。
544 @code{current_let_rule_package}によって指名されます。
546 @code{current_let_rule_package}は@code{default_let_rule_package}がデフォルト値になります。
548 @code{disprule}も参照してください
550 @code{tellsimp}と@code{tellsimpafter}が定義するルールを表示します。
551 @c WHAT ABOUT defmatch AND defrule ??
554 @category{Rules and patterns}
558 @c -----------------------------------------------------------------------------
560 @deffn {関数} letsimp (@var{expr})
561 @deffnx {関数} letsimp (@var{expr}, @var{package_name})
562 @deffnx {関数} letsimp (@var{expr}, @var{package_name_1}, @dots{}, @var{package_name_n})
565 繰り返し、@code{let}が定義する代入ルールを適用します。
567 @code{letsimp (@var{expr})}は
568 @code{current_let_rule_package}からルールを使います。
570 @code{letsimp (@var{expr}, @var{package_name})}は、
571 @code{current_let_rule_package}を変えることなしに
572 @var{package_name}からルールを使います。
574 @code{letsimp (@var{expr}, @var{package_name_1}, ..., @var{package_name_n})}は、
576 @code{letsimp (%, @var{package_name_2})}などが続く
577 @code{letsimp (@var{expr}, @var{package_name_1}}と同値です。
581 @category{Rules and patterns}
585 @c -----------------------------------------------------------------------------
586 @anchor{let_rule_packages}
587 @defvr {オプション変数} let_rule_packages
588 デフォルト値: @code{[default_let_rule_package]}
590 @code{let_rule_packages}は、
591 デフォルトパッケージ@code{default_let_rule_package}に加える
592 ユーザー定義のletルールパッケージすべてのリストです。
595 @category{Rules and patterns}
599 @c -----------------------------------------------------------------------------
600 @anchor{matchdeclare}
601 @deffn {関数} matchdeclare (@var{a_1}, @var{pred_1}, ..., @var{a_n}, @var{pred_n})
603 述語論理 @var{pred_k}を変数 @var{a_k}の変数やリストに関連づけます。
604 なので、 @var{a_k}は述語論理が @code{false}以外の何かを返す式にマッチします。
606 述語論理は関数の名前、ラムダ式、関数コール、最後の引数のないラムダコール、
607 @code{true}または @code{all}です。
608 任意の式が @code{true}や @code{all}にマッチします。
609 もし述語論理が関数コールかラムダコールとして指定されるなら、
610 テストされる式が引数のリストに追加されます;
612 そうでないなら、述語論理は関数名またはラムダ式として指定され、
614 @code{matchdeclare}がコールされた時、述語論理関数は定義されている必要はありません;
615 述語論理はマッチが試みられるまで評価されません。
618 @code{true}か @code{false}はもちろん、ブーリアン式を返すかもしれません。
619 ブーリアン式は、構成されたルール関数内で @code{is}によって評価されるので、
620 述語論理内部で @code{is}をコールする必要はありません。
624 例外は足し算 @code{+}や掛け算 @code{*}のオペランドのマッチ変数です。
626 他のn項演算子(組み込みもユーザー定義も)は通常の関数のように扱われます。
627 @c WOULD BE GREAT TO EXTEND PART+/PART* PROCESSING TO ALL N-ARY OPERATORS
630 マッチ変数はマッチ述語論理を満たす唯一の式か、
631 そんな式の(それぞれ)和または積に割り当てられます。
632 そんな多項マッチングはどん欲(greedy)です:
633 述語論理群はそれらの関連変数がマッチパターンの中で現れる順に評価され、
634 複数の述語論理を満たす項は、それが満たす最初の述語論理によってマッチされます。
637 和や積のオペランドすべてに対してテストされます。
639 もし(それぞれ)0か1がマッチ述語論理を満たし、かつ、
641 0か1が述語論理の関連マッチ変数に割り当てられます。
643 足し算と掛け算パターンを処理するアルゴリズムは、
644 (例えば、「任意のものにマッチする」変数が現れるパターンのように)
645 マッチパターンの中やマッチされる式の中の項の順序付けに依存したいくつかのマッチ結果をもたらします。
646 しかしながら、もしマッチ述語論理すべてが相互に排他的なら、
647 1つのマッチ述語論理はべつのものがマッチした項を受け入れられないので、
650 変数 @var{a}を引数として @code{matchdeclare}をコールすると、
652 @var{a}に関する @code{matchdeclare}プロパティが変わります:
653 ルールが定義された時、直近の @code{matchdeclare}だけが効果を持ちます。
654 (@code{matchdeclare}か @code{remove}を介した)
655 @code{matchdeclare}プロパティへの後の変更は、存在するルールに影響しません。
657 @code{propvars (matchdeclare)}は
658 @code{matchdeclare}プロパティを持つ変数すべてのリストを返します。
659 @code{printprops (@var{a}, matchdeclare)}は、
660 変数 @code{a}に関する述語論理を返します。
661 @code{printprops (all, matchdeclare)}は、
662 すべての @code{matchdeclare}変数に関する述語論理のリストを返します。
663 @code{remove (@var{a}, matchdeclare)}は、
664 @var{a}から @code{matchdeclare}プロパティを削除します。
666 関数 @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{tellsimpafter}, @code{let}は、パターンに対して式をテストするルールを構成します。
668 @code{matchdeclare}は引数をクォートします。
669 @code{matchdeclare}はいつも @code{done}を返します。
673 述語論理は、関数名か、ラムダ式か、最後の引数がない関数コールかラムダコールか、
674 @code{true}か @code{all}です。
677 @c matchdeclare (aa, integerp);
678 @c matchdeclare (bb, lambda ([x], x > 0));
679 @c matchdeclare (cc, freeof (%e, %pi, %i));
680 @c matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
681 @c matchdeclare (ee, true);
682 @c matchdeclare (ff, all);
685 (%i1) matchdeclare (aa, integerp);
687 (%i2) matchdeclare (bb, lambda ([x], x > 0));
689 (%i3) matchdeclare (cc, freeof (%e, %pi, %i));
691 (%i4) matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
693 (%i5) matchdeclare (ee, true);
695 (%i6) matchdeclare (ff, all);
703 @c matchdeclare (aa, integerp, bb, atom);
704 @c defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
708 (%i1) matchdeclare (aa, integerp, bb, atom);
710 (%i2) defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
712 (%o2) r1 : bb -> [integer = aa, atom = bb]
714 (%o3) [integer = 8, atom = %pi]
718 マッチ変数は、マッチ述語論理を満たす1つの式か、
719 そんな式の(それぞれ)和か積に割り当てられるかもしれません。
722 @c matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
723 @c defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
725 @c r1 (8 + a*b + sin(x));
726 @c defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
728 @c r2 (8 * (a + b) * sin(x));
731 (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
733 (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
735 bb + aa partitions `sum'
736 (%o2) r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
737 (%i3) r1 (8 + a*b + sin(x));
738 (%o3) [all atoms = 8, all nonatoms = sin(x) + a b]
739 (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
741 bb aa partitions `product'
742 (%o4) r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
743 (%i5) r2 (8 * (a + b) * sin(x));
744 (%o5) [all atoms = 8, all nonatoms = (b + a) sin(x)]
747 @code{+}と @code{*}の引数をマッチする時、
748 もしマッチ述語論理すべてが相互に排他的なら、
749 1つのマッチ述語論理は別のものがマッチした項を受け入れられないので、
753 @c matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
754 @c defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
756 @c r1 (8 + a*b + %pi + sin(x) - c + 2^n);
757 @c defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
759 @c r2 (8 * (a + b) * %pi * sin(x) / c * 2^n);
762 (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
764 (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
766 bb + aa partitions `sum'
767 (%o2) r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
768 (%i3) r1 (8 + a*b + %pi + sin(x) - c + 2^n);
770 (%o3) [all atoms = %pi + 8, all nonatoms = sin(x) + 2 - c + a b]
771 (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
773 bb aa partitions `product'
774 (%o4) r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
775 (%i5) r2 (8 * (a + b) * %pi * sin(x) / c * 2^n);
778 (%o5) [all atoms = 8 %pi, all nonatoms = -----------------]
782 関数 @code{propvars}と @code{printprops}はマッチ変数についての情報を返します。
785 @c matchdeclare ([aa, bb, cc], atom, [dd, ee], integerp);
786 @c matchdeclare (ff, floatnump, gg, lambda ([x], x > 100));
787 @c propvars (matchdeclare);
788 @c printprops (ee, matchdeclare);
789 @c printprops (gg, matchdeclare);
790 @c printprops (all, matchdeclare);
793 (%i1) matchdeclare ([aa, bb, cc], atom, [dd, ee], integerp);
795 (%i2) matchdeclare (ff, floatnump, gg, lambda ([x], x > 100));
797 (%i3) propvars (matchdeclare);
798 (%o3) [aa, bb, cc, dd, ee, ff, gg]
799 (%i4) printprops (ee, matchdeclare);
801 (%i5) printprops (gg, matchdeclare);
802 (%o5) [lambda([x], x > 100, gg)]
803 (%i6) printprops (all, matchdeclare);
804 (%o6) [lambda([x], x > 100, gg), floatnump(ff), integerp(ee),
805 integerp(dd), atom(cc), atom(bb), atom(aa)]
809 @category{Rules and patterns} @category{Declarations and inferences}
815 @c -----------------------------------------------------------------------------
816 @anchor{maxapplydepth}
817 @defvr {オプション変数} maxapplydepth
820 @code{maxapplydepth}は
821 @code{apply1}と @code{apply2}が探索する
825 @category{Function application}
831 @c -----------------------------------------------------------------------------
832 @anchor{maxapplyheight}
833 @defvr {オプション変数} maxapplyheight
836 @code{maxapplyheight}は
837 @code{applyb1}があきらめる前に到達する
841 @category{Function application}
845 @c NEEDS CLARIFICATION AND EXAMPLES
847 @c -----------------------------------------------------------------------------
849 @deffn {関数} remlet (@var{prod}, @var{name})
850 @deffnx {関数} remlet ()
851 @deffnx {関数} remlet (all)
852 @deffnx {関数} remlet (all, @var{name})
854 @code{let}関数で直近に定義された
855 代入ルール@var{prod} --> replを削除します。
856 もし名前が供給されるなら、ルールはルールパッケージ名から削除されます。
858 @code{remlet()}や@code{remlet(all)}は
859 現在のルールパッケージから代入ルールすべてを削除します。
860 もし例えば、@code{remlet (all, @var{name})}にように、ルールパッケージ名が供給されるなら、
861 ルールパッケージ@var{name}も削除されます。
864 @code{remlet}はコールされる必要はなく、
865 @code{let}関数と新しい置き換え かつ/または述語論理名で、文字通りに同じ積を使って代入を再定義だけです。
866 さて、@code{remlet (@var{prod})}がコールされると、
869 @code{remrule}も参照してください。
870 @code{tellsimp}や@code{tellsimpafter}で定義されたルールを削除します。
873 @category{Rules and patterns}
877 @c -----------------------------------------------------------------------------
879 @deffn {関数} remrule (@var{op}, @var{rulename})
880 @deffnx {関数} remrule (@var{op}, all)
882 @code{tellsimp}や@code{tellsimpafter}で定義されたルールを削除します。
884 @code{remrule (@var{op}, @var{rulename})}は、
889 (@code{infix}, @code{prefix}, などで定義されたような)ユーザー定義演算子の時、
890 @var{op}と@var{rulename}はダブルクォートマークでくくられないといけません。
892 @code{remrule (@var{op}, all)}は
893 演算子@var{op}に関するルールすべてを削除します。
895 @code{remlet}も参照してください。
896 @code{let}で定義されたルールを削除します。
901 @c tellsimp (foo (aa, bb), bb - aa);
902 @c tellsimpafter (aa + bb, special_add (aa, bb));
904 @c tellsimp (aa @@ bb, bb/aa);
905 @c tellsimpafter (quux (%pi, %e), %pi - %e);
906 @c tellsimpafter (quux (%e, %pi), %pi + %e);
907 @c [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
909 @c remrule (foo, foorule1);
910 @c remrule ("+", ?\+rule1);
911 @c remrule ("@@", ?\@\@rule1);
912 @c remrule (quux, all);
913 @c [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
917 (%i1) tellsimp (foo (aa, bb), bb - aa);
918 (%o1) [foorule1, false]
919 (%i2) tellsimpafter (aa + bb, special_add (aa, bb));
920 (%o2) [+rule1, simplus]
921 (%i3) infix ("@@@@");
923 (%i4) tellsimp (aa @@@@ bb, bb/aa);
924 (%o4) [@@@@rule1, false]
925 (%i5) tellsimpafter (quux (%pi, %e), %pi - %e);
926 (%o5) [quuxrule1, false]
927 (%i6) tellsimpafter (quux (%e, %pi), %pi + %e);
928 (%o6) [quuxrule2, quuxrule1, false]
929 (%i7) [foo (aa, bb), aa + bb, aa @@@@ bb, quux (%pi, %e),
932 (%o7) [bb - aa, special_add(aa, bb), --, %pi - %e, %pi + %e]
934 (%i8) remrule (foo, foorule1);
936 (%i9) remrule ("+", ?\+rule1);
938 (%i10) remrule ("@@@@", ?\@@\@@rule1);
940 (%i11) remrule (quux, all);
942 (%i12) [foo (aa, bb), aa + bb, aa @@@@ bb, quux (%pi, %e),
944 (%o12) [foo(aa, bb), bb + aa, aa @@@@ bb, quux(%pi, %e),
949 @category{Rules and patterns}
953 @c NEEDS EXPANSION OR MAYBE JUST APPROPRIATE REFS TO tellsimpafter
955 @c -----------------------------------------------------------------------------
957 @deffn {関数} tellsimp (@var{pattern}, @var{replacement})
959 @code{tellsimpafter}に似ていますが、
963 整理器が働く前に式を変更することが重要な時
964 例えば、整理器が式について何か「知っている」が、それが返すものが好みでないなら、
965 @code{tellsimp}が使われます。
966 もし整理器が式の主演算子について何かを「知っている」が、単に十分でないなら、
967 たぶん@code{tellsimpafter}を使いたいでしょう。
969 パターンは和、積、変数1つ、または、数は取れません。
972 @code{defrule}, @code{defmatch}, @code{tellsimp}, @code{tellsimpafter}で
978 (%i1) matchdeclare (x, freeof (%i));
981 (%i3) tellsimp (sin(%i*x), %i*sinh(x));
982 (%o3) [sinrule1, simp-%sin]
983 (%i4) trigexpand (sin (%i*y + x));
984 (%o4) sin(x) cos(%i y) + %i cos(x) sinh(y)
990 (%i7) ev (tellsimp (0^0, 1), simp: false);
991 (%o7) [^rule1, simpexpt]
994 (%i9) remrule ("^", %th(2)[1]);
996 (%i10) tellsimp (sin(x)^2, 1 - cos(x)^2);
997 (%o10) [^rule2, simpexpt]
998 (%i11) (1 + sin(x))^2;
1003 (%o12) 2 sin(x) - cos (x) + 2
1007 (%i14) kill (rules);
1009 (%i15) matchdeclare (a, true);
1011 (%i16) tellsimp (sin(a)^2, 1 - cos(a)^2);
1012 (%o16) [^rule3, simpexpt]
1019 @category{Rules and patterns}
1023 @c -----------------------------------------------------------------------------
1024 @anchor{tellsimpafter}
1025 @deffn {関数} tellsimpafter (@var{pattern}, @var{replacement})
1027 組み込み整理ルールの後、適Maxima整理器が適用する
1030 (@code{matchdeclare}で宣言された)
1031 パターン変数や他のアトムや演算子から成る、
1032 パターンマッチングの目的でリテラルと考えられる式です。
1034 @var{pattern}にマッチする実際の式に代入されます;
1035 @var{replacement}の中のパターン変数は
1036 実際の式の中でマッチした値に割り当てられます。
1039 主演算子がパターン変数でない任意の非アトム式を取り得ます;
1040 整理ルールは主演算子に関連付けられます。
1041 (以下で記述する1つの例外がありますが、)関数、リスト、配列の名前が、
1042 (パターン変数でなく)ただリテラルとして、
1043 主演算子として@var{pattern}の中で現れることができます;
1046 もし@code{aa}や@code{bb}がパターン変数なら
1047 @code{aa(x)}や@code{bb[y]}のような式を除外します。
1048 パターン変数である関数、リスト、配列の名前は、
1049 @var{pattern}の中で、主演算子以外の演算子として現れることができます。
1051 上の関数名に関するルールに1つ例外があります。
1052 @code{aa[x](y)}のような式の中の添字付き関数の名前は
1053 主演算子が@code{aa}でなくLispアトム@code{mqapply}だから、
1055 これは、添字付き関数を含む式の表現の結果です。
1057 @c LET'S NOT GO INTO DETAILS ABOUT MAIN OPERATORS HERE; BUT PRESERVE THIS FOR REFERENCE
1058 @c The main operator of an expression @code{expr} is @code{caar $expr}.
1059 @c For most kinds of expressions,
1060 @c the main operator is the operator returned by @code{op (@var{pattern})};
1061 @c the sole exception is the operator @code{mqapply},
1062 @c which appears in indexed function expressions (e.g., @code{foo[i](x)}).
1064 @c NEED TO REVIEW THIS PARAGRAPH FOR ACCURACY
1065 (もしクォートやフラグ@code{noeval}を通して抑制されないなら)
1068 @code{tellsimpafter}で確立されたルールは、
1069 組み込みルールの後、それらが定義された順に適用されます。
1070 ルールはボトムアップに適用されます。すなわち、
1071 式全体への適用の前に、最初、部分式に適用されます。
1072 @c NO IT IS MORE COMPLICATED THAN THIS, ALTHOUGH IN SOME CIRCUMSTANCE IT APPEARS TO BE THE CASE:
1073 @c For a given expression, at most one rule per operator is applied.
1074 ルールすべてが適用されることを保証するために、
1075 (例えば、クォートクォート演算子@code{'@w{}'}やフラグ@code{infeval}を介して)
1076 結果を繰り返し整理する必要があるかもしれません。
1078 パターン変数は、整理ルールの中でローカル変数として扱われます。
1079 一旦ルールが定義されると、パターン変数の値は、
1080 ルールに影響せず、ルールによって影響されません。
1081 成功したルールマッチの結果となるパターン変数への割り当ては、
1082 パターン変数の現在の割り当て(またはその欠落)に影響しません。
1083 しかしながら、Maximaの中のアトムすべてで、
1084 (@code{put}や関連関数で定義された)パターン変数のプロパティはグローバルです。
1086 @code{tellsimpafter}によって構成されたルールは、
1087 @var{pattern}の主演算子に由来します。
1089 @code{infix}, @code{prefix}, @code{postfix}, @code{matchfix}, @code{nofix}で
1090 定義されたユーザー定義演算子に関するルールは、
1092 @c SLIGHTLY TOO MUCH DETAIL
1093 @c (that is, the name is written with a leading question mark @code{?} in Maxima).
1094 他の関数に関するルールは、Maxima識別子である名前を持ちます。
1095 @c SLIGHTLY TOO MUCH DETAIL
1096 @c (that is, the name begins with dollar sign @code{$}).
1098 名詞と動詞形の扱いは少し混乱しています。
1100 もしルールが名詞(または動詞)形に関して定義されて、
1101 対応する動詞(または名詞)形に関するルールが既に存在しているなら、
1102 新しく定義されたルールは両方の形式(名詞と動詞)に適用されます。
1103 もし対応する動詞(名詞)形に関するルールが存在しないなら、
1104 新しく定義されたルールは名詞(または動詞)形にだけ適用されます。
1106 @code{tellsimpafter}で構成されたルールは通常のLisp関数です。
1107 もしルール名が@code{$foorule1}なら、
1108 構成子@code{:lisp (trace $foorule1)}は関数をトレースし、
1109 @code{:lisp (symbol-function '$foorule1)}は定義を表示します。
1111 @code{tellsimpafter}は引数をクォートします。
1112 @code{tellsimpafter}は
1114 @var{pattern}の主演算子に関する
1116 @c WHAT IS simpfoo THAT SOMETIMES APPEARS, AND WHY DOES false SOMETIMES APPEAR IN RETURN VALUE ??
1118 @code{matchdeclare}, @code{defmatch}, @code{defrule}, @code{tellsimp}, @code{let}, @code{kill}, @code{remrule}, @code{clear_rules}も参照してください。
1123 主演算子がパターン変数でない任意の非アトム式を取り得ます。
1126 @c matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
1127 @c tellsimpafter (sin (ll), map (sin, ll));
1128 @c sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
1129 @c tellsimpafter (ll^mm, map ("^", ll, mm));
1130 @c [a, b, c]^[1, 2, 3];
1131 @c tellsimpafter (foo (aa (xx)), aa (foo (xx)));
1132 @c foo (bar (u - v));
1135 (%i1) matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
1136 (%i2) tellsimpafter (sin (ll), map (sin, ll));
1137 (%o2) [sinrule1, simp-%sin]
1138 (%i3) sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
1140 (%o3) [-, -------, -------, 1, 0]
1142 (%i4) tellsimpafter (ll^mm, map ("^", ll, mm));
1143 (%o4) [^rule1, simpexpt]
1144 (%i5) [a, b, c]^[1, 2, 3];
1147 (%i6) tellsimpafter (foo (aa (xx)), aa (foo (xx)));
1148 (%o6) [foorule1, false]
1149 (%i7) foo (bar (u - v));
1150 (%o7) bar(foo(u - v))
1153 ルールはそれらが定義された順に適用されます。
1154 もし2つのルールが式にマッチできるなら、
1158 @c matchdeclare (aa, integerp);
1159 @c tellsimpafter (foo (aa), bar_1 (aa));
1160 @c tellsimpafter (foo (aa), bar_2 (aa));
1164 (%i1) matchdeclare (aa, integerp);
1166 (%i2) tellsimpafter (foo (aa), bar_1 (aa));
1167 (%o2) [foorule1, false]
1168 (%i3) tellsimpafter (foo (aa), bar_2 (aa));
1169 (%o3) [foorule2, foorule1, false]
1174 整理ルールの中で、パターン変数はローカル変数として扱われます。
1175 (@code{defmatch}と比較してください。
1176 パターン変数をグローバル変数として扱います。)
1179 @c matchdeclare (aa, integerp, bb, atom);
1180 @c tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1186 (%i1) matchdeclare (aa, integerp, bb, atom);
1188 (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1189 (%o2) [foorule1, false]
1193 (%o4) bar(aa = 42, bb = %e)
1199 パターン変数のプロパティは、たとえ値がローカルでも、
1202 @code{define_variable}を介して宣言されます。
1203 Maximaの至る所で、これはアトム@code{bb}のプロパティです。
1206 @c matchdeclare (aa, integerp, bb, atom);
1207 @c tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1209 @c define_variable (bb, true, boolean);
1213 (%i1) matchdeclare (aa, integerp, bb, atom);
1215 (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
1216 (%o2) [foorule1, false]
1218 (%o3) bar(aa = 42, bb = %e)
1219 (%i4) define_variable (bb, true, boolean);
1222 Error: bb was declared mode boolean, has value: %e
1223 -- an error. Quitting. To debug this try debugmode(true);
1227 組み込みやユーザー定義の演算子に関するルール名はLisp識別子で、
1228 一方、他の関数に関する名前はMaxima識別子です。
1231 @c tellsimpafter (foo (%pi + %e), 3*%pi);
1232 @c tellsimpafter (foo (%pi * %e), 17*%e);
1233 @c tellsimpafter (foo (%i ^ %e), -42*%i);
1234 @c tellsimpafter (foo (9) + foo (13), quux (22));
1235 @c tellsimpafter (foo (9) * foo (13), blurf (22));
1236 @c tellsimpafter (foo (9) ^ foo (13), mumble (22));
1238 @c foorule_name: first (%o1);
1239 @c plusrule_name: first (%o4);
1240 @c remrule (foo, foorule1);
1241 @c remrule ("^", ?\^rule1);
1245 (%i1) tellsimpafter (foo (%pi + %e), 3*%pi);
1246 (%o1) [foorule1, false]
1247 (%i2) tellsimpafter (foo (%pi * %e), 17*%e);
1248 (%o2) [foorule2, foorule1, false]
1249 (%i3) tellsimpafter (foo (%i ^ %e), -42*%i);
1250 (%o3) [foorule3, foorule2, foorule1, false]
1251 (%i4) tellsimpafter (foo (9) + foo (13), quux (22));
1252 (%o4) [+rule1, simplus]
1253 (%i5) tellsimpafter (foo (9) * foo (13), blurf (22));
1254 (%o5) [*rule1, simptimes]
1255 (%i6) tellsimpafter (foo (9) ^ foo (13), mumble (22));
1256 (%o6) [^rule1, simpexpt]
1258 (%o7) [foorule1, foorule2, foorule3, +rule1, *rule1, ^rule1]
1259 (%i8) foorule_name: first (%o1);
1261 (%i9) plusrule_name: first (%o4);
1263 (%i10) remrule (foo, foorule1);
1265 (%i11) remrule ("^", ?\^rule1);
1268 (%o12) [foorule2, foorule3, +rule1, *rule1]
1274 @c gt (i, j) := integerp(j) and i < j;
1275 @c matchdeclare (i, integerp, j, gt(i));
1276 @c tellsimpafter (s[i]^^2, 1);
1277 @c tellsimpafter (s[i] . s[j], -s[j] . s[i]);
1278 @c s[1] . (s[1] + s[2]);
1280 @c factor (expand (sum (s[i], i, 0, 9)^^5));
1283 (%i1) gt (i, j) := integerp(j) and i < j;
1284 (%o1) gt(i, j) := integerp(j) and i < j
1285 (%i2) matchdeclare (i, integerp, j, gt(i));
1287 (%i3) tellsimpafter (s[i]^^2, 1);
1288 (%o3) [^^rule1, simpncexpt]
1289 (%i4) tellsimpafter (s[i] . s[j], -s[j] . s[i]);
1290 (%o4) [.rule1, simpnct]
1291 (%i5) s[1] . (s[1] + s[2]);
1297 (%i7) factor (expand (sum (s[i], i, 0, 9)^^5));
1298 (%o7) 100 (s + s + s + s + s + s + s + s + s + s )
1303 @category{Rules and patterns}
1307 @c -----------------------------------------------------------------------------
1308 @anchor{clear_rules}
1309 @deffn {関数} clear_rules ()
1311 @code{kill (rules)}を実行し、
1312 足し算@code{+}, 掛け算@code{*}, べき@code{^}に関して
1316 @category{Rules and patterns}