[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7. Operators


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1 Introduction to operators

指定された優先順位を持つ新しい演算子を定義したり、 既存の演算子を未定義にしたり、既存の演算子の優先順位を再定義することが可能です。 演算子には単項前置、単項後置、二項中置、n項中置、マッチフィックスか無項があります。 「マッチフィックス」は引数を括るシンボルの対を意味し、 「無項」は引数を取らない演算子を意味します。 異なるタイプの演算子の例として以下があります。

unary prefix

negation - a

unary postfix

factorial a!

binary infix

exponentiation a^b

n-ary infix

addition a + b

matchfix

list construction [a, b]

(組み込みの無項演算子はありません; そんな演算子の例は、nofixを参照してください。.)

新しい演算子を定義するメカニズムはわかりやすいものです。 関数を演算子として宣言することだけが必要です; 演算子関数は定義することもしないこともあります。

ユーザー定義の演算子の例は以下の通りです。 明示的な関数コール "dd" (a)dd aと同値であり、また、 "<-" (a, b)a <- bと同値であることに注意してください。 この例で、 "dd""<-"は未定義です。

 
(%i1) prefix ("dd");
(%o1)                          dd
(%i2) dd a;
(%o2)                         dd a
(%i3) "dd" (a);
(%o3)                         dd a
(%i4) infix ("<-");
(%o4)                          <-
(%i5) a <- dd b;
(%o5)                      a <- dd b
(%i6) "<-" (a, "dd" (b));
(%o6)                      a <- dd b

新しい演算子を定義するMaxima関数はこの表にまとめられます。 デフォルトの左と右の結合力(それぞれlbpとrbp)を記載します。 (結合力は演算子の優先順位を決めます。 しかしながら、左と右の結合力は異なることがあり、 結合力は優先順位より幾分複雑です。) 演算定義関数のいくつかは追加の引数を取ります; 詳細は関数記述を参照してください。

prefix

rbp=180

postfix

lbp=180

infix

lbp=180, rbp=180

nary

lbp=180, rbp=180

matchfix

(binding power not applicable)

nofix

(binding power not applicable)

比較のために、いくつかの組み込み演算子と左右結合力を上げます。

 
Operator   lbp     rbp

  :        180     20
  ::       180     20
  :=       180     20
  ::=      180     20
  !        160
  !!       160
  ^        140     139
  .        130     129
  *        120
  /        120     120
  +        100     100
  -        100     134
  =        80      80
  #        80      80
  >        80      80
  >=       80      80
  <        80      80
  <=       80      80
  not              70
  and      65
  or       60
  ,        10
  $        -1
  ;        -1

removekillは演算子プロパティをアトムから削除します。 remove ("a", op)aの演算子プロパティだけを削除します。 kill ("a")は 演算子プロパティを含むaのプロパティすべてを削除します。 演算子名はクォーテーションマークで括らないといけないことに注意してください。

 
(%i1) infix ("##");
(%o1)                          ##
(%i2) "##" (a, b) := a^b;
                                     b
(%o2)                     a ## b := a
(%i3) 5 ## 3;
(%o3)                          125
(%i4) remove ("##", op);
(%o4)                         done
(%i5) 5 ## 3;
Incorrect syntax: # is not a prefix operator
5 ##
  ^
(%i5) "##" (5, 3);
(%o5)                          125
(%i6) infix ("##");
(%o6)                          ##
(%i7) 5 ## 3;
(%o7)                          125
(%i8) kill ("##");
(%o8)                         done
(%i9) 5 ## 3;
Incorrect syntax: # is not a prefix operator
5 ##
  ^
(%i9) "##" (5, 3);
(%o9)                       ##(5, 3)

Categories:  Operators · Syntax


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.2 Arithmetic operators

演算子: +
演算子: -
演算子: *
演算子: /
演算子: ^

シンボル + * / ^はそれぞれ、 足し算、かけ算、割り算、べき乗を表します。 これらの演算子の名前は "+" "*" "/" "^"です。 これらは関数や演算子の名前が求められるところで使います。

シンボル +-はそれぞれ、プラスとマイナスの単項演算子を示し、 それらの名前はそれぞれ "+""-"です。

引き算 a - bはMaximaの中では足し算 a + (- b)として表されます。 a + (- b)のような式は引き算として表示されます。 Maximaは "-"を足し算の単項逆元演算子の名前としてのみ認識して、 二項引き算演算子としては認識しません。

Maximaの中では割り算a / bをかけ算a * b^(- 1)として表現します。 a * b^(- 1)のような式は割り算として表示されます。 Maximaは"/"を割り算演算子の名前として認識します。

足し算とかけ算はn項可換演算子です。 割り算とべき乗は二項の非可換演算子です。

Maximaは正準表現を構成するために可換演算子のオペランド(訳注:引数)を並べ替えます。 順序は内部的には orderlesspで決定します。 表示のためには、足し算の順序は ordergreatpで決定し、 かけ算は内部的な順序と同じです。

算術計算は数リテラル(整数、有理数、通常の浮動小数点、多倍長浮動小数点)上で実行されます。 べき乗を除いて、数に対するすべての算術演算子は数に整理されます。 べき乗は、オペランドが通常の浮動小数点か多倍長浮動小数点の時か結果が厳密に整数もしくは有理数の時、数に整理されます; そうでなければ、べき乗は sqrtか他のべき乗に整理されるかそのまま残されます。

浮動小数点の伝搬が算術計算に適用されます: もしどれか1つでもオペランドが多倍長浮動小数点なら、結果は多倍長浮動小数点です; そうでなければ、もしどれか1つでもオペランドが通常の浮動小数点なら、結果は通常の浮動小数点です; そうでなければオペランドは有理数か整数であり、結果は有理数か整数です。

算術計算は式整理であって評価ではありません。 従って、クォートされた(しかし整理される)式の中で算術計算は実行されます。

算術演算は、 グローバルフラグ listarithtrueの時 リストに対して要素毎に適用され、 行列に対しては常に要素毎に適用されます。 オペランドの1つがリストか行列であり、もう1つのオペランドが別のタイプの時、 他のオペランドはリストか行列の要素のそれぞれに組み合わされます。

例:

足し算とかけ算はn項可換演算子です。 Maximaは、正準表現を構成するために可換演算子のオペランドを並べ替えます。 それらの名前はそれぞれ "+""*"です。

 
(%i1) c + g + d + a + b + e + f;
(%o1)               g + f + e + d + c + b + a
(%i2) [op (%), args (%)];
(%o2)              [+, [g, f, e, d, c, b, a]]
(%i3) c * g * d * a * b * e * f;
(%o3)                     a b c d e f g
(%i4) [op (%), args (%)];
(%o4)              [*, [a, b, c, d, e, f, g]]
(%i5) apply ("+", [a, 8, x, 2, 9, x, x, a]);
(%o5)                    3 x + 2 a + 19
(%i6) apply ("*", [a, 8, x, 2, 9, x, x, a]);
                                 2  3
(%o6)                       144 a  x

割り算とべき乗は、二項の非可換演算子です。 それらの名前はそれぞれ "/""^"です。

 
(%i1) [a / b, a ^ b];
                              a   b
(%o1)                        [-, a ]
                              b
(%i2) [map (op, %), map (args, %)];
(%o2)              [[/, ^], [[a, b], [a, b]]]
(%i3) [apply ("/", [a, b]), apply ("^", [a, b])];
                              a   b
(%o3)                        [-, a ]
                              b

引き算と割り算は内部的にはそれぞれ、足し算とかけ算を使って表現されます。

 
(%i1) [inpart (a - b, 0), inpart (a - b, 1), inpart (a - b, 2)];
(%o1)                      [+, a, - b]
(%i2) [inpart (a / b, 0), inpart (a / b, 1), inpart (a / b, 2)];
                                   1
(%o2)                       [*, a, -]
                                   b

計算は数リテラルに対して実行されます。 浮動小数点伝搬が適用されます。

 
(%i1) 17 + b - (1/2)*29 + 11^(2/4);
                                       5
(%o1)                   b + sqrt(11) + -
                                       2
(%i2) [17 + 29, 17 + 29.0, 17 + 29b0];
(%o2)                   [46, 46.0, 4.6b1]

算術計算は式整理であって、評価ではありません。

 
(%i1) simp : false;
(%o1)                         false
(%i2) '(17 + 29*11/7 - 5^3);
                              29 11    3
(%o2)                    17 + ----- - 5
                                7
(%i3) simp : true;
(%o3)                         true
(%i4) '(17 + 29*11/7 - 5^3);
                                437
(%o4)                         - ---
                                 7

算術計算は(listarithに依存して)リストや行列に対して要素毎に実行されます。

 
(%i1) matrix ([a, x], [h, u]) - matrix ([1, 2], [3, 4]);
                        [ a - 1  x - 2 ]
(%o1)                   [              ]
                        [ h - 3  u - 4 ]
(%i2) 5 * matrix ([a, x], [h, u]);

                          [ 5 a  5 x ]
(%o2)                     [          ]
                          [ 5 h  5 u ]
(%i3) listarith : false;
(%o3)                         false
(%i4) [a, c, m, t] / [1, 7, 2, 9];
                          [a, c, m, t]
(%o4)                     ------------
                          [1, 7, 2, 9]
(%i5) [a, c, m, t] ^ x;
                                      x
(%o5)                     [a, c, m, t]
(%i6) listarith : true;
(%o6)                         true
(%i7) [a, c, m, t] / [1, 7, 2, 9];
                              c  m  t
(%o7)                     [a, -, -, -]
                              7  2  9
(%i8) [a, c, m, t] ^ x;
                          x   x   x   x
(%o8)                   [a , c , m , t ]

Categories:  Operators

演算子: **

べき乗演算子。 Maximaは入力の中で **^と同じ演算子と認識し、 1次元出力の中では ^として表示し、 また、2次元出力の中では指数を上付き添字として配置します。

fortran関数は、入力が **でも ^でも べき乗演算子を **として表示します。

例:

 
(%i1) is (a**b = a^b);
(%o1)                         true
(%i2) x**y + x^z;
                              z    y
(%o2)                        x  + x
(%i3) string (x**y + x^z);
(%o3)                        x^z+x^y
(%i4) fortran (x**y + x^z);
      x**z+x**y
(%o4)                         done

Categories:  Operators

演算子: ^^

非可換べき乗演算子。 ちょうど可換なかけ算 *に通常のべき乗演算子 ^が対応するように、 ^^は非可換かけ算 .に対応するべき乗演算子です。

非可換べき乗演算子は、1次元出力では ^^で表示され、 2次元出力では指数をかっこ < >で囲まれた上付き添字として置きます。

例:

 
(%i1) a . a . b . b . b + a * a * a * b * b;
                        3  2    <2>    <3>
(%o1)                  a  b  + a    . b
(%i2) string (a . a . b . b . b + a * a * a * b * b);
(%o2)                  a^3*b^2+a^^2 . b^^3

Categories:  Operators

演算子: .

行列(非可換)かけ算のためのドット演算子。 "."をこの意味で用いる時、 例えば A . Bのように両側にスペースを置かなければいけません。 これで浮動小数点の小数点と区別します。

Dotdot0nscsimp, dot0simp, dot1simp, dotassoc, dotconstrules, dotdistrib, dotexptsimp, dotident, dotscrules. も参照してください。

Categories:  Operators


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3 Relational operators

演算子: <
演算子: <=
演算子: >=
演算子: >

シンボル < <= >= >はそれぞれ、小なり、以下、以上、大なり を表します。 これらの演算子の名前は、 "<""<="">="">"です。 それらは関数や演算子の名前が求められるところで使われます。

これらの関係演算子はすべて二項演算子です; a < b < cのような構成をMaximaは認識しません。

関数 ismaybe、 プログラミング構成子 if, while, unlessが 関係式をブーリアン値に評価します。 そうでなければ、関係式はブーリアン値に評価されたり整理されたりしませんが、 関係式の引数は(評価がクォーテーションによって妨げられないかぎり)評価されます。

関係式が trueもしくは falseに評価できない時、 isifの振る舞いはグローバルフラグ prederrorが決定します。 prederrortrueの時 isifはエラーをトリガーします。 prederrorfalseの時、 isunknownを返し、 ifは部分的に評価された条件式を返します。

maybeはいつも prederrorfalseであるかのように振る舞い、 whileunlessはいつも prederrortrueであるかのように振る舞います。

関係演算子はリストやほかの集合上で展開されることはありません。

=#equalnotequalも参照してください。

例:

いくつかの関数やプログラミング構成子が関係式をブーリアン値に評価します。

 
(%i1) [x, y, z] : [123, 456, 789];
(%o1)                    [123, 456, 789]
(%i2) is (x < y);
(%o2)                         true
(%i3) maybe (y > z);
(%o3)                         false
(%i4) if x >= z then 1 else 0;
(%o4)                           0
(%i5) block ([S], S : 0, for i:1 while i <= 100 do S : S + i,
             return (S));
(%o5)                         5050

そうでなければ関係式はブーリアン値に評価されたり整理されたりしませんが、 関係式の引数は評価されます。

 
(%o1)                    [123, 456, 789]
(%i2) [x < y, y <= z, z >= y, y > z];
(%o2)    [123 < 456, 456 <= 789, 789 >= 456, 456 > 789]
(%i3) map (is, %);
(%o3)               [true, true, true, false]

Categories:  Operators


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.4 Logical operators

演算子: and

論理積演算子。 andは、n項中置演算子です; オペランドはブーリアン値で、結果もブーリアン値です。

andは( isのように)1つ以上のオペランドの評価を強制し、 すべてのオペランドの評価を強制するかもしれません。

オペランドは出現順に評価されます。 andは結果を決定するのに必要なだけオペランドを評価します。 もし任意のオペランドがfalseなら、結果はfalseであり、 ほかのオペランドは評価されません。

グローバルフラグprederrorは、 評価されたオペランドがtruefalseに決定できない時のandの振る舞いを決定します。 prederrortrueの時、andはエラーメッセージを出力します。 そうでなければ、 truefalseに評価されないオペランドを受け付け、 結果はブーリアン式になります。

andは可換ではありません: a and bは、不定のオペランドの扱いのため、b and aと同値ではないかもしれません。

Categories:  Operators

演算子: not

論理否定演算子。 notは、接頭演算子です; オペランドはブーリアン値で、結果もブーリアン値です。

orは( isのように)オペランドの評価を強制します。

グローバルフラグ prederrorは、 評価されたオペランドが truefalseに決定できない時の notの振る舞いを決定します。 prederrortrueの時、notはエラーメッセージを出力します。 そうでなければ、truefalseに評価されないオペランドを受け付け、 結果はブーリアン式になります。

Categories:  Operators

演算子: or

論理和演算子。 orは、n項中置演算子です; オペランドはブーリアン値で、結果もブーリアン値です。

orは、(isのように)1以上のオペランドの評価を強制し、 すべてのオペランドの評価を強制するかもしれません。

オペランドは、出現順に評価されます。 andは、結果を決定するのに必要なだけオペランドを評価します。 もし任意のオペランドがtrueなら、結果はtrueであり、 ほかのオペランドは評価されません。

グローバルフラグprederrorは、 評価されたオペランドがtruefalseに決定できない時のorの振る舞いを決定します。 prederrortrueの時、orは、エラーメッセージを出力します。 そうでなければ、truefalseに評価されないオペランドを受け付け、 結果はブーリアン式になります。

orは可換ではありません: a or bは、不定のオペランドの扱いのため、b or aと同値ではないかもしれません。

Categories:  Operators


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.5 Operators for Equations

演算子: #

構文的等号=の否定を表します。

述語論理式の評価のルールのため (特に not exprexprの評価を伴うので)、 not a = ba # bではなく、 is(a # b)と同値です。

例:

 
(%i1) a = b;
(%o1)                         a = b
(%i2) is (a = b);
(%o2)                         false
(%i3) a # b;
(%o3)                         a # b
(%i4) not a = b;
(%o4)                         true
(%i5) is (a # b);
(%o5)                         true
(%i6) is (not a = b);
(%o6)                         true

Categories:  Operators

演算子: =

等式演算子。

a = bはそれ自身未評価の等式を表します。 等式は成り立つかもしれませんし、成り立たないかもしれません。 未評価の等式は solvealgsysや他の関数の引数として用いられます。

関数is=をブーリアン値に評価します。 abが同一の時、is(a = b)a = btrueに評価します。 すなわち、abが同一のアトムであるか、もしくは、それらはアトムではなく、 それらの演算子が同一で、演算子の引数が同一です。 そうでなければ、is(a = b)falseに評価されます; 決して unknownには評価されません。 is(a = b)trueの時、 abは、同値の式と対照的に、構文法的に等しいと言われます。 同値の式は is(equal(a, b))trueの式です。 式は 同値だが構文法的に等しくないことが起こりえます。

=の否定は #で表されます。 =と同様、式a # bは、それ自身評価されません。 is(a # b)a # btruefalseに評価します。

isに加えて、if, and, or, not=#truefalseに評価します。

述語論理式の評価規則のため (特に、not exprexprの評価を起こすため)、 not a = bは、a # bではなく、 is(a # b)と同値になります。

rhslhsはそれぞれ、等式、不等式の右辺と左辺を返します。

equalnotequalも参照してください。

例:

a = bはそれ自身未評価の等式であり、 成り立つことも成り立たないこともあります。

 
(%i1) eq_1 : a * x - 5 * y = 17;
(%o1)                    a x - 5 y = 17
(%i2) eq_2 : b * x + 3 * y = 29;
(%o2)                    3 y + b x = 29
(%i3) solve ([eq_1, eq_2], [x, y]);
                        196         29 a - 17 b
(%o3)          [[x = ---------, y = -----------]]
                     5 b + 3 a       5 b + 3 a
(%i4) subst (%, [eq_1, eq_2]);
         196 a     5 (29 a - 17 b)
(%o4) [--------- - --------------- = 17,
       5 b + 3 a      5 b + 3 a
                                  196 b     3 (29 a - 17 b)
                                --------- + --------------- = 29]
                                5 b + 3 a      5 b + 3 a
(%i5) ratsimp (%);
(%o5)                  [17 = 17, 29 = 29]

abが構文法的に等しい(すなわち、同一の)時 is(a = b)a = btrueに評価します。 式は同値だけれども構文法的に等しくないことがありえます。

 
(%i1) a : (x + 1) * (x - 1);
(%o1)                    (x - 1) (x + 1)
(%i2) b : x^2 - 1;
                              2
(%o2)                        x  - 1
(%i3) [is (a = b), is (a # b)];
(%o3)                     [false, true]
(%i4) [is (equal (a, b)), is (notequal (a, b))];
(%o4)                     [true, false]

いくつかの演算子は =#truefalseに評価します。

 
(%i1) if expand ((x + y)^2) = x^2 + 2 * x * y + y^2 then FOO else
      BAR;
(%o1)                          FOO
(%i2) eq_3 : 2 * x = 3 * x;
(%o2)                       2 x = 3 x
(%i3) eq_4 : exp (2) = %e^2;
                              2     2
(%o3)                       %e  = %e
(%i4) [eq_3 and eq_4, eq_3 or eq_4, not eq_3];
(%o4)                  [false, true, true]

not exprexprの評価をするので、 not a = bis(a # b)と同値です。

 
(%i1) [2 * x # 3 * x, not (2 * x = 3 * x)];
(%o1)                   [2 x # 3 x, true]
(%i2) is (2 * x # 3 * x);
(%o2)                         true

Categories:  Operators


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6 Assignment operators

演算子: :

割り当て演算子。

左辺が(添字のない)単純変数の時、 :は右辺を評価しその値を左辺に関連づけます。

左辺がリストや行列、宣言されたMaxima配列、Lisp配列の添字指定された要素の時、 右辺がその要素に割り当てられます。 添字は存在している要素を示していなければなりません; 先に列挙した対象は存在していない要素を名付けることで拡張することはできません。

左辺が未宣言のMaxima配列の添字指定された要素の時、 もし既に存在しているなら右辺はその要素に割り当てられ、 もしまだ存在していなければ新しい要素が確保されます。

左辺が単純変数や添字あり変数のリストの時、 右辺はリストに評価されなければなりません。 そして右辺の要素が左辺の要素に平行に割り当てられます。

killremvalueも参照してください。 それらは左辺とその値の関連を取り消します。

例:

単純変数への割り当て

 
(%i1) a;
(%o1)                           a
(%i2) a : 123;
(%o2)                          123
(%i3) a;
(%o3)                          123

リストの要素への割り当て

 
(%i1) b : [1, 2, 3];
(%o1)                       [1, 2, 3]
(%i2) b[3] : 456;
(%o2)                          456
(%i3) b;
(%o3)                      [1, 2, 456]

割り当ては未宣言配列を生成する。

 
(%i1) c[99] : 789;
(%o1)                          789
(%i2) c[99];
(%o2)                          789
(%i3) c;
(%o3)                           c
(%i4) arrayinfo (c);
(%o4)                   [hashed, 1, [99]]
(%i5) listarray (c);
(%o5)                         [789]

多重割り当て

 
(%i1) [a, b, c] : [45, 67, 89];
(%o1)                     [45, 67, 89]
(%i2) a;
(%o2)                          45
(%i3) b;
(%o3)                          67
(%i4) c;
(%o4)                          89

多重割り当ては平行に実行されます。 この例ではabの値が置換されます。

 
(%i1) [a, b] : [33, 55];
(%o1)                       [33, 55]
(%i2) [a, b] : [b, a];
(%o2)                       [55, 33]
(%i3) a;
(%o3)                          55
(%i4) b;
(%o4)                          33

Categories:  Evaluation · Operators

演算子: ::

割り当て演算子。

::は、右辺はもちろん左辺も評価することを除いて :と同じです。

例:

 
(%i1) x : 'foo;
(%o1)                          foo
(%i2) x :: 123;
(%o2)                          123
(%i3) foo;
(%o3)                          123
(%i4) x : '[a, b, c];
(%o4)                       [a, b, c]
(%i5) x :: [11, 22, 33];
(%o5)                     [11, 22, 33]
(%i6) a;
(%o6)                          11
(%i7) b;
(%o7)                          22
(%i8) c;
(%o8)                          33

Categories:  Evaluation · Operators

演算子: ::=

マクロ関数定義の演算子。 ::=は、引数をクォートする関数(歴史的理由によりマクロと呼ばれる)を定義します。 そして、それが返す式(マクロ展開と呼ばれる)はマクロが呼ばれた文脈の中で評価されます。 それ以外はマクロ関数は通常の関数と同じです。

macroexpandは(評価せずに)マクロ展開を返します。 fooがマクロ関数の時、 macroexpand (foo (x))に続けて ``%を実行すると、 それは foo (x)と同値です。

::=は新しいマクロ関数の名前をグローバルリスト macrosに追加します。 killremove, remfunctionはマクロ関数定義をアンバインドし、 macrosから名前を削除します。

fundefdispfunはそれぞれマクロ関数定義を返し、 それをラベルに割り当てます。

評価対象となる式を構成するために、 マクロ関数は一般的にbuildq, splice式を含みます。

マクロ関数は引数をクォートします。 だから、メッセージ(1)は y - zの値ではなく、 y - zを示します。 マクロ展開(クォートされた式 '(print ("(2) x is equal to", x))は、 マクロが呼ばれた文脈(表示メッセージ(2))の中で評価されます。

 
(%i1) x: %pi$
(%i2) y: 1234$
(%i3) z: 1729 * w$
(%i4) printq1 (x) ::= block (print ("(1) x is equal to", x),
      '(print ("(2) x is equal to", x)))$
(%i5) printq1 (y - z);
(1) x is equal to y - z
(2) x is equal to %pi
(%o5)                                 %pi

通常の関数は引数を評価します。だから、メッセージ(1)は y - zの値を示します。 戻り値は評価されず、従って、メッセージ(2)は ``%で陽に評価されるまで出力されません。

 
(%i1) x: %pi$
(%i2) y: 1234$
(%i3) z: 1729 * w$
(%i4) printe1 (x) := block (print ("(1) x is equal to", x),
      '(print ("(2) x is equal to", x)))$
(%i5) printe1 (y - z);
(1) x is equal to 1234 - 1729 w
(%o5)                     print((2) x is equal to, x)
(%i6) ''%;
(2) x is equal to %pi
(%o6)                                 %pi

macroexpandはマクロ展開を返します。 fooがマクロ関数の時、 macroexpand (foo (x))の後 ``%を実行すると、foo (x)と同値です。

 
(%i1) x: %pi$
(%i2) y: 1234$
(%i3) z: 1729 * w$
(%i4) g (x) ::= buildq ([x], print ("x is equal to", x))$
(%i5) macroexpand (g (y - z));
(%o5)                     print(x is equal to, y - z)
(%i6) ''%;
x is equal to 1234 - 1729 w
(%o6)                            1234 - 1729 w
(%i7) g (y - z);
x is equal to 1234 - 1729 w
(%o7)                            1234 - 1729 w

Categories:  Function definition · Operators

演算子: :=

関数定義の演算子。

f(x_1, .., x_n) := exprは、 引数がx_1, ..., x_nで関数本体がexprの、fという名前の関数を定義します。 :=は(クォートクォート``で陽に評価されない限り)関数本体は評価しません。 関数本体は関数がコールされる度に評価されます。

f[x_1, ..., x_n] := exprは配列関数と呼ばれるものを定義します。 その関数本体はそれぞれ別個の引数に関して一度だけ評価されます。 そして引数が再度それらの値をとる時にはいつでも関数本体は評価されることなく値が返されます。 (この種の関数は一般に「メモ化関数」として知られています。)

f[x_1, ..., x_n](y_1, ..., y_m) := expr は配列関数の特殊ケースです。 f[x_1, ..., x_n]は、引数y_1, ..., y_mを伴ったラムダ式を返す配列関数です。 関数本体は x_1, ..., x_nのそれぞれ別個の値に関して一度だけ評価されて、 ラムダ式の本体はその値です。

最後の引数x_nが要素1つのリストの時、:=で定義された関数は可変の数の引数をとります。 実際の引数は、形式的な引数x_1, …, x_(n - 1)に一対一に割り当てられ、 さらに引数があれば、x_nにリストとして割り当てられます。

関数定義すべては、同じ名前空間を使います; 別の関数gの中で関数fを定義することは、fのスコープをgに限定しません。 しかし、local(f)は、関数fの定義をlocalが現れたブロックや他の合成式内に限定します。

もしある形式引数x_kがクォートされたシンボルなら、:=で定義された関数は対応する実際の引数を評価しません。 それ以外の場合、実際の引数はすべて評価されます。

define::=も参照してください。

例:

:=は(クォートクォートで陽に評価されない限り)関数本体を評価しません。

 
(%i1) expr : cos(y) - sin(x);
(%o1)                    cos(y) - sin(x)
(%i2) F1 (x, y) := expr;
(%o2)                   F1(x, y) := expr
(%i3) F1 (a, b);
(%o3)                    cos(y) - sin(x)
(%i4) F2 (x, y) := ''expr;
(%o4)              F2(x, y) := cos(y) - sin(x)
(%i5) F2 (a, b);
(%o5)                    cos(b) - sin(a)

f(x_1, ..., x_n) := ... は通常の関数を定義します。

 
(%i1) G1(x, y) := (print ("Evaluating G1 for x=", x, "and y=", y), x.y - y.x);
(%o1) G1(x, y) := (print("Evaluating G1 for x=", x, "and y=",
                                               y), x . y - y . x)
(%i2) G1([1, a], [2, b]);
Evaluating G1 for x= [1, a] and y= [2, b]
(%o2)                           0
(%i3) G1([1, a], [2, b]);
Evaluating G1 for x= [1, a] and y= [2, b]
(%o3)                           0

f[x_1, ..., x_n] := ... は配列関数を定義します。

 
(%i1) G2[a] := (print ("Evaluating G2 for a=", a), a^2);
                                                     2
(%o1)     G2  := (print("Evaluating G2 for a=", a), a )
            a
(%i2) G2[1234];
Evaluating G2 for a= 1234
(%o2)                        1522756
(%i3) G2[1234];
(%o3)                        1522756
(%i4) G2[2345];
Evaluating G2 for a= 2345
(%o4)                        5499025
(%i5) arrayinfo (G2);
(%o5)              [hashed, 1, [1234], [2345]]
(%i6) listarray (G2);
(%o6)                  [1522756, 5499025]

f[x_1, ..., x_n](y_1, ..., y_m) := expr は配列関数の特殊ケースです。

 
(%i1) G3[n](x) := (print ("Evaluating G3 for n=", n), diff (sin(x)^2, x, n));
(%o1) G3 (x) := (print("Evaluating G3 for n=", n),
        n
                                                     2
                                             diff(sin (x), x, n))
(%i2) G3[2];
Evaluating G3 for n= 2
                                2           2
(%o2)          lambda([x], 2 cos (x) - 2 sin (x))
(%i3) G3[2];
                                2           2
(%o3)          lambda([x], 2 cos (x) - 2 sin (x))
(%i4) G3[2](1);
                           2           2
(%o4)                 2 cos (1) - 2 sin (1)
(%i5) arrayinfo (G3);
(%o5)                   [hashed, 1, [2]]
(%i6) listarray (G3);
                                2           2
(%o6)         [lambda([x], 2 cos (x) - 2 sin (x))]

最後の引数x_nが要素1つのリストの時、 :=で定義された関数は可変の数の引数を取ります。

 
(%i1) H ([L]) := apply ("+", L);
(%o1)                H([L]) := apply("+", L)
(%i2) H (a, b, c);
(%o2)                       c + b + a

localはローカル関数定義を可能にします。

 
(%i1) foo (x) := 1 - x;
(%o1)                    foo(x) := 1 - x
(%i2) foo (100);
(%o2)                         - 99
(%i3) block (local (foo), foo (x) := 2 * x, foo (100));
(%o3)                          200
(%i4) foo (100);
(%o4)                         - 99

Categories:  Function definition · Operators


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.7 User defined operators

関数: infix  
    infix (op)  
    infix (op, lbp, rbp)  
    infix (op, lbp, rbp, lpos, rpos, pos)

opを中置演算子に宣言します。 中置演算子は2つの引数の関数で、引数の間に関数名が来ます。 例えば、引き算演算子-は中置演算子です。

infix (op)は、デフォルトの結合力(左右両方とも180)と品詞 (左右両方ともany)に等しい)でopを中置演算子に宣言します。

infix (op, lbp, rbp)は、 記述された左右の結合力 とデフォルトの品詞(左右両方ともany)に等しい)で、 opを中置演算子に宣言します。

infix (op, lbp, rbp, lpos, rpos, pos)は、 記述された左右の結合力と、 左オペランド、右オペランド、演算子結果それぞれについて、 品詞をlpos, rpos, posに設定して、 opを中置演算子に宣言します。

(演算子宣言に関係して)「品詞」は、式のタイプを意味します。 3つのタイプが認識されます; expr, clause, any。それぞれは、 代数式、ブーリアン式、任意の種類の式を示します。 Maximaは、宣言された品詞を実際の式に比較することで、 いくつかの構文法エラーを検出します。

他の演算子に関するopの優先順位は、問題となっている演算子の左右結合力から演繹されます。 もしopの左右結合力のどちらもある他の演算子の左右結合力より大きいなら、 opは、他の演算子より高い優先順位をとります。 もし結合力がどちらも大きくも、どちらも小さくもなければ、 あるもっと複雑な関係が成り立ちます。

opの結合性は結合力に依存します。 より大きな左結合力(lbp)は、opのインスタンスが 式の中で左にある他の演算子の前に評価されることを示し、 より大きな右結合力(rbp)は、opのインスタンスが 式の中で右にある他の演算子の前に評価されることを示します。 このように、より大きなlbpopを右結合にし、 より大きなrbpopを左結合にします。 もしlbprbpと等しいなら、 opは左結合です。

Syntaxも参照してください。

例:

もしop左右結合力それぞれが、他の演算子のそれより大きいなら、 opは他の演算子より高い優先順位をとります。

 
(%i1) :lisp (get '$+ 'lbp)
100
(%i1) :lisp (get '$+ 'rbp)
100
(%i1) infix ("##", 101, 101);
(%o1)                          ##
(%i2) "##"(a, b) := sconcat("(", a, ",", b, ")");
(%o2)       (a ## b) := sconcat("(", a, ",", b, ")")
(%i3) 1 + a ## b + 2;
(%o3)                       (a,b) + 3
(%i4) infix ("##", 99, 99);
(%o4)                          ##
(%i5) 1 + a ## b + 2;
(%o5)                       (a+1,b+2)

より大きなlbpopを右結合にし、 より大きなrbpopを左結合にします。

 
(%i1) infix ("##", 100, 99);
(%o1)                          ##
(%i2) "##"(a, b) := sconcat("(", a, ",", b, ")")$
(%i3) foo ## bar ## baz;
(%o3)                    (foo,(bar,baz))
(%i4) infix ("##", 100, 101);
(%o4)                          ##
(%i5) foo ## bar ## baz;
(%o5)                    ((foo,bar),baz)

Maximaは、宣言された品詞を実際の式と比較することで、 いくつかの構文法エラーを検出します。

 
(%i1) infix ("##", 100, 99, expr, expr, expr);
(%o1)                          ##
(%i2) if x ## y then 1 else 0;
Incorrect syntax: Found algebraic expression where logical
expression expected
if x ## y then
             ^
(%i2) infix ("##", 100, 99, expr, expr, clause);
(%o2)                          ##
(%i3) if x ## y then 1 else 0;
(%o3)                if x ## y then 1 else 0

関数: matchfix  
    matchfix (ldelimiter, rdelimiter)  
    matchfix (ldelimiter, rdelimiter, arg_pos, pos)

左と右の区切り記号ldelimiterrdelimiterを持つ matchfix演算子を宣言します 区切り記号は文字列として指定されます。

"matchfix"演算子は、 任意の数の引数の関数で、引数は左と右の区切り記号をマッチする間で現れます。 パーサがオペランドや他の式や演算子から区切り記号を区別できる限り 区切り記号は任意の文字列を取り得ます。 実際には、これは、%, ,, $, ;のような パースできない区切り記号を除外し、空白を持つ区切り記号を分離することを要求するかもしれません。 右区切り記号は、左区切り記号と同じかもしれませんし、違うかもしれません。

左区切り記号は、たった1つの右区切り記号と関連づけられることができます; 2つの異なるmatchfix演算子は同じ左区切り記号を持つことはできません。

存在する演算子は、 他のプロパティを変えることなく、 matchfix演算子として再宣言することができます。 特に、足し算+のような組み込み演算子が matchfixに宣言されることが可能ですが、 演算子関数は組み込み演算子に関して定義できません。

コマンドmatchfix (ldelimiter, rdelimiter, arg_pos, pos) は、 引数品詞arg_posと結果品詞pos、区切り記号 ldelimiterrdelimiterを宣言します。

演算子宣言に関して、「品詞」は式のタイプを意味します。 3つのタイプが認識されます: それぞれ、代数式、ブーリアン式、任意の種類の式を示す、 expr, clause, any。 Maximaは、 宣言された品詞を実際の式と比較することで、 いくつかの構文法エラーを検知します。

matchfix演算を実行する関数は通常のユーザー定義関数です。 演算子関数は、 関数定義演算子:=defineを使って 普通の方法で定義されます。 引数は、区切り記号の間に書かれるか、 クォートされた文字列としての左区切り記号と括弧の中で続く引数を使って書かれます。 dispfun (ldelimiter)は関数定義を表示します。

唯一の組み込みmatchfix演算子はリスト構成子[ ]です。 括弧( )とダブルクォート" "はmatchfix演算子のように振る舞いますが、 Maximaパーサによってそのようには扱われません。

matchfixは引数を評価します。 matchfixは最初の引数ldelimiterを返します。

例:

区切り記号はほとんど任意の文字列を取り得ます。

 
(%i1) matchfix ("@@", "~");
(%o1)                          @@
(%i2) @@ a, b, c ~;
(%o2)                      @@a, b, c~
(%i3) matchfix (">>", "<<");
(%o3)                          >>
(%i4) >> a, b, c <<;
(%o4)                      >>a, b, c<<
(%i5) matchfix ("foo", "oof");
(%o5)                          foo
(%i6) foo a, b, c oof;
(%o6)                     fooa, b, coof
(%i7) >> w + foo x, y oof + z << / @@ p, q ~;
                     >>z + foox, yoof + w<<
(%o7)                ----------------------
                            @@p, q~

Matchfix演算子は通常のユーザー定義関数です。

 
(%i1) matchfix ("!-", "-!");
(%o1)                         "!-"
(%i2) !- x, y -! := x/y - y/x;
                                    x   y
(%o2)                   !-x, y-! := - - -
                                    y   x
(%i3) define (!-x, y-!, x/y - y/x);
                                    x   y
(%o3)                   !-x, y-! := - - -
                                    y   x
(%i4) define ("!-" (x, y), x/y - y/x);
                                    x   y
(%o4)                   !-x, y-! := - - -
                                    y   x
(%i5) dispfun ("!-");
                                    x   y
(%t5)                   !-x, y-! := - - -
                                    y   x

(%o5)                         done
(%i6) !-3, 5-!;
                                16
(%o6)                         - --
                                15
(%i7) "!-" (3, 5);
                                16
(%o7)                         - --
                                15

Categories:  Syntax · Operators

関数: nary  
    nary (op)  
    nary (op, bp, arg_pos, pos)

nary演算子は 任意の数の引数の関数を示すのに使われます。 引数それぞれは、例えば、A+BやA+B+Cように演算子の出現で分離されます。 nary("x")関数は xnary演算子に宣言する構文拡張関数です。 関数は naryであると宣言されるかもしれません。 もし declare(j,nary);が実行されたら、 これは整理器に 例えば、j(j(a,b),j(c,d))j(a, b, c, d)に整理するよう指示します。

Introduction to operatorsも参照してください。

Categories:  Operators · Syntax

関数: nofix  
    nofix (op)  
    nofix (op, pos)

nofix演算子は引数のない関数を示すのに使われます。 コマンドにそんな演算子が存在すると、 対応する関数が評価されるだけです。 例えば、Maximaブレイクから抜けるために"exit;"とタイプする時、 "exit"はnofix演算子と似たように振る舞います。 関数 nofix("x")xnofix演算子に宣言する構文拡張関数です。

Introduction to operatorsも参照してください。

Categories:  Operators · Syntax

関数: postfix  
    postfix (op)  
    postfix (op, lbp, lpos, pos)

prefix変種のようなpostfix演算子は引数一つの関数を示しますが、 この場合、例えば3!のように、入力文字列の中で引数が演算子に先行します。 postfix("x")関数は xpostfix演算子に宣言する構文拡張関数です。

Introduction to operatorsも参照してください。

Categories:  Operators · Syntax

関数: prefix  
    prefix (op)  
    prefix (op, rbp, rpos, pos)

prefix演算子は引数一つの関数であり、 その引数は演算子のすぐ後ろに置かれます。 prefix("x")xprefix演算子に宣言する構文拡張関数です。

Introduction to operatorsも参照してください。

Categories:  Operators · Syntax


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by 市川雄二 on June, 21 2016 using texi2html 1.76.