1.6 演算子
1.6.4 演算子の属性を宣言する函数
ここでは最初に演算子の属性を宣言する函数から述べましょう. Maximaでは利用者が函数やア トムを演算子として利用する事が可能です.特に,適当な文字列を演算子の属性を宣言する函数を 用いて属性を与えてしまえば,それだけで演算子として利用が出来ます.更に,値もきちんと函数と して定義しなくても, atvalueの様な属性で与える事も可能です.以下に組合せを計算する演算子C の定義の様子を示します.
(%i62) nary("C");
(%o62) C
(%i63) m C n:= m!/(n!*(m-n)!);
m!
(%o63) m C n :=
---n! (m - n)!
(%i64) 5 C 3;
(%o64) 10
演算子の属性を宣言する函数には以下のものがあります.
演算子の属性を宣言する函数
¶ ³
infix infix(a) 文字列aを内挿表現の演算子として宣言
infix infix(a,lbp,rbp) 内挿表現の演算子aに左右の束縛力を含めて宣
言
infix infix(a,lbp,rbp,lpos,rpos,pos) 内挿表現の演算子aに左右の束縛力と型を含め て宣言
nary nary(a) 文字列aを内挿表現の演算子として宣言
nary nary(a,bp) 内挿表現の演算子aに束縛力を含めて宣言
nary nary(a,bp,argpos,pos) 内挿表現の演算子aに束縛力と型を含めて宣言
nofix nofix(a) 文字列aを無引数の演算子として宣言
nofix nofix(a,pos) 無引数の演算子aに出力の型を含めて宣言
postfix postfix(a) 文字列aを後置表現の演算子として宣言
postfix postfix(a,lbp) 後置表現の演算子aに左束縛力を含めて宣言
postfix postfix(a,lbp,rpos,pos) 後置表現の演算子aに左束縛力と型を含めて宣
言
prefix prefix(a) 文字列aを前置表現の演算子として宣言
prefix prefix(a,rbp) 前置表現の演算子aに右束縛力を含めて宣言
prefix prefix(a,rbp,rpos,pos) 前置表現の演算子aに右束縛力と型を含めて宣
言
matchfix matchfix(a,b) 変数を文字列aと文字列bで挟む演算子を宣言
matchfix matchfix(a,b,argpos,pos) 引数の型と結果の型を含めて宣言
µ ´
この表で,lbpとrbpが左束縛力と右束縛力,lposとrposが左右の被演算子の型,posが返却値の 型です.又,matchfix函数とinfix函数では左右に分けずに演算子の束縛力をbp,被演算子の型を argposとしています.
最初のinfixは内挿(infix)表現の演算子の宣言を行います.内挿表現の演算子は二つの引数を持
つ函数で,a+b の和の演算子+の様に引数が演算子の前後に置かれるものです.nary函数も内挿 表現の演算子の宣言を行います.
nary函数も,函数を内挿表現演算子として宣言する事が出来ます.このnary函数で宣言可能な演 算子は左右の束縛力が同じでも構わないものに限定されます.とは言え, デフォルトでは全て180 が設定されるので,左右の束縛力を調整する必要が無ければ, nary函数の方が変数が少ないので使 い易いかもしれません.
nofix函数は無引数演算子の宣言を行います.無引数演算子は演算子が何等の引数を持たない事 を明示する為に使われます.
postfix函数は後置表記演算子の宣言を行います.後置表記の演算子は一つの引数のみを持ち, 3!
の様にその引数は演算子の前に置かれます.
prefix函数は前置表記演算子の宣言を行います.前置表記の演算子は一個の引数のみを持ち,その
引数は演算子の直後に置かれるものです.
matchfix函数は任意個数の引数を二つの文字列で囲む演算子を宣言します.
%i5) matchfix("@-","-@");
(%o5)
@-(%i6) @- a,b,c,d,e,f -@:=a*b*c+d*e^f;
f (%o6) @-a, b, c, d, e, f-@ := a b c + d e (%i7) @- 1,2,3,4,5,6 -@;
(%o7) 62506
(%i8) dispfun("@-");
f (%t8) @-a, b, c, d, e, f-@ := a b c + d e
(%o8) done
尚,dispfun函数を使ってmatchfixで定義した演算子に割当てた利用者定義函数の内容を見る場 合,演算子の先頭の文字列だけを二重引用符で括ったものをdispfun函数の引数とします.
上記の函数で設定した属性はkill函数やremove函数で削除する事が可能です.尚,removeの場合 は属性のみを削除しますが,kill函数の場合は演算子として定義した文字列そのものを削除してしま います.
(%i10) nary("tama");
(%o10) tama
(%i11) a tama b:=a+b^2;
2
(%o11) a tama b := a + b
(%i12) properties("tama");
(%o12) [function, operator, noun]
(%i13) remove("tama",op);
(%o13) done
(%i14) properties("tama");
(%o14) []
(%i15) prefix("mike");
(%o15) mike
(%i16) mike x:=x!+1;
(%o16) mike x := x! + 1
(%i17) kill("mike");
(%o17) done
(%i18) properties("mike");
(%o18) []
この例では,中置演算子tamaを定義し,属性を削除するremove函数で演算子tamaを削除して います.ここで,tamaの属性はproperties函数を用いて調べられます. 演算子の属性をremoveを実 行された時点でtamaの属性全てが削除されています. 又,演算子mikeに対してはkill函数を使っ て演算子mike全てを削除しています. この様にremove函数とkill函数で削除する事が可能です.
尚,この例ではremove函数は演算子の属性を指定した為,副作用として演算子全体が削除されて しまいましたが,propertiesで調べた特定の属性だけを削除する函数です.
(%i19) nary("tama");
(%o19) tama
(%i20) a tama b:=a+b^2;
2
(%o20) a tama b := a + b
(%i21) remove("tama",function);
(%o21) done
(%i22) properties("tama");
(%o22) [operator, noun]
(%i23) 3 tama 4;
(%o23) 3 tama 4
この例では,函数を削除しただけで演算子としての属性は残しています.その為, 3 tama 4;と 入力してもエラーにはなりません.
演算子定義函数で定められる属性
¶ ³
演算子 左束縛力 右束縛力 左変数型 右変数型 返却値型
postfix 180 any any
prefix 180 any any
infix 180 180 any any
nofix any
nary any any any
matchfix any any any
µ ´
基本的に,変数型と返却型は$anyに設定されます.尚,nary函数とmatchfix函数で宣言された演 算子の被演算子型は他の函数と異なり,左右の変数型属性lposやrposではなく,argpos属性で指定 し,その属性値は$anyです.