Operatoren (Maxima Manual)

## 7 Operatoren

### 7.1 Einführung in Operatoren

Maxima kennt die üblichen arithmetischen, relationalen und logischen Operatoren der Mathematik. Weiterhin kennt Maxima Operatoren für die Zuweisung von Werten an Variablen und die Definition von Funktionen. Die folgende Tabelle zeigt die in diesem Kapitel beschriebenen Operatoren. Angegeben sind der Name des Operators, der linksseitige Vorrang `lbp` und der rechtsseitige Vorrang `rbp`, der Typ des Operators und ein Beispiel einschließlich der internen Darstellung, wie sie vom Parser von der Eingabe gelesen wird.

    Operator  lbp rbp  Typ     Beispiel

       +      100 134  nary     a+b      ((mplus) $A $B)
       -      100 134  prefix   -a       ((mminus) $A)
       *      120      nary     a*b      ((mtimes) $A $B)
       /      120 120  infix    a/b      ((mquotient) $A $B)
       ^      140 139  infix    a^b      ((mexpt) $A $B)
       **     140 139  infix    a**b     ((mexpt) $A $B)
       ^^     140 139  infix    a^^b     ((mncexpt) $A $B)
       .      130 129  infix    a.b      ((mnctimes) $A $B)

       <       80  80  infix    a<b      ((mlessp) $A $B)
       <=      80  80  infix    a<=b     ((mleqp) $A $B)
       >       80  80  infix    a>b      ((mqreaterp) $A $B)
       >=      80  80  infix    a>=b     ((mgeqp) $A $B)

       not         70  prefix   not a    ((mnot) $A)
       and     65      nary     a and b  ((mand) $A $B)
       or      60      nary     a or b   ((mor) $A $B)

       #       80  80  infix    a#b      ((mnotequal) $A $B)
       =       80  80  infix    a=b      ((mequal) $A $B)

       :      180  20  infix    a:b      ((msetq) $A $B)
       ::     180  20  infix    a::b     ((mset) $A $B)
       :=     180  20  infix    a:=b     ((mdefine) $A $B)
       ::=    180  20  infix    a::=b    ((mdefmacro) $A $B)

Mit dem Vorrang der Operatoren werden die bekannten Rechenregeln der einzelnen Operatoren definiert. So wird zum Beispiel `a + b * c` vom Parser als `a + (b * c)` interpretiert, da der linksseitige Vorrang der Multiplikation größer als der linksseitige Vorrang der Addition ist.

Maxima unterscheidet die folgenden Operatoren:

Prefix

  Prefix-Operatoren sind unäre Operatoren, die einen Operanden haben, der dem Operator nachfolgt. Beispiele sind die Operatoren `-` und `not`.

Postfix

  Postfix-Operatoren sind unäre Operatoren, die einen Operanden haben, der dem Operator vorangestellt ist. Ein Beispiel ist der Operator `!` für die Fakultät.

Infix

  Infix-Operatoren, sind binäre Operatoren, die zwei Operanden haben. Der Operator steht zwischen diesen Operanden. Hierzu zählen zum Beispiel der Operator für die Exponentiation `^` oder der Operator für die Zuweisung `:`.

N-ary

  N-ary-Operatoren fassen eine beliebige Anzahl an Operanden zu einem Ausdruck zusammen. Hierzu zählen die Multiplikation `*` oder die Addition `+`.

Matchfix

  Matchfix-Operatoren sind Begrenzungszeichen, die eine beliebige Anzahl an Operanden einschließen. Ein Beispiel sind die Operatoren `[` und `]`, die eine Liste `[a, b, ...]` definieren.

Nofix

  Ein Nofix-Operator ist ein Operator, der keinen Operanden hat. Maxima kennt keinen internen Nofix-Operator. Zum Beispiel kann mit `nofix(quit)` ein Nofix-Operator definiert werden. Dann ist es möglich, Maxima allein mit `quit` anstatt dem Funktionsaufruf `quit()` zu beenden.

Maxima unterscheidet das Symbol eines Operators, wie zum Beispiel `+` für die Addition, von dem Namen eines Operators, der eine Zeichenkette ist. Der Additionsoperator hat den Namen `"+"`. Mit dem Namen des Operators kann der Operator als eine Funktion eingegeben werden. Im folgenden wird ein Beispiel für den binären Infix-Operator der Exponentiation gezeigt:

    (%i1) a^b;
                                    b
    (%o1)                          a
    (%i2) "^"(a,b);
                                    b
    (%o2)                          a

Der Name des Operators kann immer dann verwendet werden, wenn eine Funktion als Argument benötigt wird. Beispiele sind die Funktionen `map`, `apply` oder auch die Substitution mit `subst`.

    (%i3) apply("+", [a,b,c]);
    (%o3)                       c + b + a
    (%i4) map("^", [a,b,c],[1,2,3]);
                                    2   3
    (%o4)                      [a, b , c ]
    (%i5) subst("*"="+", 10*a*b*c);
    (%o5)                    c + b + a + 10

In Nutzerdefinierte Operatoren wird beschrieben, wie interne Maxima-Operatoren umdefiniert oder neue Operatoren definiert werden.

Die obige Tabelle enthält nicht alle von Maxima definierten Operatoren. Weitere Operatoren sind zum Beispiel `!` für die Fakultät, die Operatoren `for`, `do`, `while`, um eine Programmschleife zu programmieren, oder `if`, `then`, `else`, um eine Bedingung zu definieren.

### 7.2 Arithmetische Operatoren

Operator: + ¶
Operator: - ¶
Operator: * ¶
Operator: / ¶
Operator: ^ ¶

  Sind die Operatoren der Addition, Multiplikation, Division und Exponentiation. Wird der Name eines Operators in einem Ausdruck benötigt, können die Bezeichnungen `"+"`, `"*"`, `"/"` und `"^"` verwendet werden.

  In Ausdrücken wie `(+a)*(-a)` oder `exp(-a)` repräsentieren die Operatoren `+` und `-` die unäre Addition und Negation. Die Namen der Operatoren sind `"+"` und `"-"`.

  Die Subtraktion `a - b` wird von Maxima intern als Addition `a + (- b)` dargestellt. In der Ausgabe wird der Ausdruck `a + (- b)` als Subtraktion `a - b` angezeigt.

  Die Division `a / b` wird von Maxima intern als Multiplikation `a * b^(- 1)` dargestellt. In der Ausgabe wird der Ausdruck `a * b^(- 1)` als Division `a / b` angezeigt. Der Name des Operators für die Division ist `"/"`.

  Die Operatoren der Addition und Multiplikation sind kommutative N-ary-Operatoren. Die Operatoren der Division und Exponentiation sind nicht-kommutative binäre Operatoren.

  Maxima sortiert die Operanden eines kommutativen Operators und konstruiert eine kanonische Darstellung. Maxima unterscheidet die interne Sortierung von der externen Sortierung für die Anzeige. Die interne Sortierung wird von der Aussagefunktion `orderlessp` bestimmt. Die externe Sortierung für die Anzeige wird von der Aussagefunktion `ordergreatp` festgelegt. Ausnahme ist die Multiplikation. Für diese sind die interne und die externe Sortierung identisch.

  Arithmetische Rechnungen mit Zahlen (ganzen Zahlen, rationale Zahlen, Gleitkommazahlen und großen Gleitkommazahlen) werden als eine Vereinfachung und nicht als Auswertung ausgeführt. Mit Ausnahme der Exponentiation werden alle arithmetischen Operationen mit Zahlen zu Zahlen vereinfacht. Exponentiationen von Zahlen wie zum Beispiel `(1/3)^(1/2)` werden nicht notwendigerweise zu Zahlen vereinfacht. In diesem Beispiel ist das Ergebnis der Vereinfachung `1/sqrt(3)`.

  Bei einer arithmetischen Rechnung kann es zur Umwandlung in Gleitkommazahlen kommen. Ist eines der Argumente eine große Gleitkommazahl, so ist auch das Ergebnis eine große Gleitkommazahl. Entsprechend ist das Ergebnis eine einfache Gleitkommazahl, sofern mindestens einer der Operanden eine einfache Gleitkommazahl ist. Treten nur ganze oder rationale Zahlen auf, ist das Ergebnis wieder eine ganze oder rationale Zahl.

  Da arithmetische Rechnungen Vereinfachungen und keine Auswertungen sind, werden arithmetische Rechnungen auch dann ausgeführt, wenn die Auswertung des Ausdrucks zum Beispiel mit dem `Quote-Operator` `'` unterdrückt ist.

  Arithmetische Operatoren werden elementweise auf Listen angewendet, wenn die Optionsvariable `listarith` den Wert `true` hat. Auf Matrizen werden die arithmetischen Operatoren immer elementweise angewendet. Ist einer der Operanden eine Liste oder Matrix und der andere Operand hat einen anderen Typ, dann wird dieses Argument mit jedem Element der Liste oder Matrix kombiniert.

  Beispiele:

  Addition und Multiplikation sind kommutative N-ary-Operatoren. Maxima sortiert die Operanden und konstruiert eine kanonische Darstellung. Die Namen der Operatoren sind `"+"` und `"*"`.

      (%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

  Division und Exponentiation sind nicht-kommutative binäre Operatoren. Die Namen der Operatoren sind `"/"` und `"^"`.

      (%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

  Subtraktion und Division werden intern als Addition und Multiplikation dargestellt.

      (%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

  Sind die Operanden Zahlen, werden die Rechnungen ausgeführt. Ist einer der Operanden eine Gleitkommazahl, ist das Ergebnis ebenfalls eine Gleitkommazahl.

      (%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]

  Arithmetische Rechnungen sind Vereinfachungen und keine Auswertung.

      (%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

  Arithmetische Rechnungen werden elementweise für Listen und Matrizen ausgeführt. Bei Listen wird dies mit der Optionsvariablen `listarith` kontrolliert.

      (%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 ]

Operator: ** ¶

  Ist eine alternative Schreibweise für den Operator `^` der Exponentiation. In der Ausgabe wird entweder `^` angezeigt oder der Exponent hochgestellt. Siehe den Operator der Exponentiation `^`.

  Die Funktion `fortran` zeigt den Operator der Exponentiation immer als `**` an, unabhängig davon, ob `**` oder `^` eingegeben wird.

  Beispiele:

      (%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

Operator: ^^ ¶

  Ist der Operator der nicht-kommutativen Exponentiation von Matrizen. In der linearen Ausgabe wird der nicht-kommutative Operator als `^^` angezeigt. In der zweidimensionalen Ausgabe wird der hochgestellte Exponent von spitzen Klammern `< >` eingeschlossen.

  Beispiele:

      (%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

Operator: . ¶

  Ist der Operator der nicht-kommutativen Multiplikation von Matrizen. Siehe für Erläuterungen Nicht-kommutative Multiplikation.

### 7.3 Relationale Operatoren

Operator: < ¶
Operator: <= ¶
Operator: >= ¶
Operator: > ¶

  Die Symbole `<`, `<=`, `>=` und `>` sind die relationalen Operatoren "kleiner als", "kleiner als oder gleich", "größer als oder gleich" und "größer als". Die Namen dieser Operatoren sind jeweils: `"<"`, `"<="`, `">="` und `">"`. Diese können dort eingesetzt werden, wo der Name des Operators benötigt wird.

  Die relationalen Operatoren sind binäre Operatoren. Ausdrücke wie `a < b < c` werden von Maxima nicht erkannt und generieren eine Fehlermeldung.

  Relationale Ausdrücke werden von den Funktionen `is` und `maybe` sowie den Funktionen `if`, `while` und `unless` zu booleschen Werten ausgewertet. Relationale Ausdrücke werden ansonsten nicht zu booleschen Werten ausgewertet oder vereinfacht. Jedoch werden die Operanden eines booleschen Ausdruckes ausgewertet, wenn die Auswertung nicht mit dem `Quote-Operator` `'` unterdrückt ist.

  Wenn ein relationaler Ausdruck mit den Funktionen `is` oder `if` nicht zu `true` oder `false` ausgewertet werden kann, wird das Verhalten der Funktionen von der Optionsvariablen `prederror` kontrolliert. Hat `prederror` den Wert `true`, wird von `is` und `if` ein Fehler erzeugt. Hat `prederror` den Wert `false`, hat `is` den Rückgabewert `unknown` und `if` gibt einen konditionalen Ausdruck zurück, der teilweise ausgewertet ist.

  Die Funktion `maybe` verhält sich immer so, als ob `prederror` den Wert `false` hat, und die Schleifenanweisungen `while` sowie `unless` verhalten sich immer so, als ob `prederror` den Wert `true` hat.

  Relationale Operatoren werden nicht auf die Elemente von Listen oder Matrizen sowie auf die beiden Seiten einer Gleichung angewendet.

  Siehe auch die Operatoren `=` und `#` sowie die Funktionen `equal` und `notequal`.

  Beispiele:

  Relationale Ausdrücke werden von einigen Funktionen zu booleschen Werten ausgewertet.

      (%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

  Relationale Ausdrücke werden ansonsten nicht zu booleschen Werten ausgewertet oder vereinfacht, jedoch werden die Operanden eines relationalen Ausdruckes ausgewertet.

      (%i1) [x, y, z] : [123, 456, 789];
      (%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]

### 7.4 Logische Operatoren

Operator: and ¶

  Ist der logische Operator der Konjunktion. `and` ist ein N-ary-Operator. Die Operanden sind boolesche Ausdrücke und das Ergebnis ist ein boolescher Wert.

  Der Operator `and` erzwingt die Auswertung aller oder einen Teil der Operanden. Die Operanden werden in der Reihenfolge ausgewertet, in der sie auftreten. `and` wertet nur so viele Operanden aus, wie nötig sind, um das Ergebnis des Ausdrucks zu bestimmen. Hat irgendein Argument den Wert `false`, ist das Ergebnis `false` und die weiteren Argumente werden nicht ausgewertet.

  Die Optionsvariable `prederror` kontrolliert das Verhalten von `and` für den Fall, dass ein Operand nicht zu `true` oder `false` ausgewertet werden kann. `and` gibt eine Fehlermeldung aus, wenn `prederror` den Wert `true` hat. Andernfalls werden Operanden akzeptiert, die nicht zu `true` oder `false` ausgewertet werden können und das Ergebnis ist ein boolescher Ausdruck.

  `and` ist nicht kommutativ, da aufgrund von nicht ausgewerteten Operanden die Ausdrücke `a and b` und `b and a` ein unterschiedliches Ergebnis haben können.

  Beispiele:

      (%i1) n:2;
      (%o1)                           2
      (%i2) integerp(n) and evenp(n);
      (%o2)                         true
      (%i3) not(a=b) and 1=1 and integerp(2);
      (%o3)                         true
      (%i4) not(a=b) and 1=1 and oddp(2);
      (%o4)                         false
      (%i5) a and b;
      (%o5)                        a and b
      (%i6) prederror:true$
      (%i7) a and b;

      Unable to evaluate predicate a
       -- an error. To debug this try: debugmode(true);

  Da `and` nur so viele Operanden auswertet wie notwendig sind, um das Ergebnis festzustellen, führt der syntaktische Fehler im zweiten Operanden nicht zu einer Fehlermeldung, das das Ergebnis bereits mit dem ersten Operanden feststeht.

      (%i8) a=b and sin(2,2);
      (%o8)                         false

Operator: or ¶

  Ist der logische Operator der Disjunktion. `or` ist ein N-ary-Operator. Die Operanden sind boolesche Ausdrücke und das Ergebnis ist ein boolescher Wert.

  Der Operator `or` erzwingt die Auswertung aller oder einen Teil der Operanden. Die Operanden werden in der Reihenfolge ausgewertet, in der sie auftreten. `or` wertet nur so viele Operanden aus wie nötig sind, um das Ergebnis des Ausdrucks zu bestimmen. Hat irgendein Operand den Wert `true`, ist das Ergebnis `true` und die weiteren Operanden werden nicht ausgewertet.

  Die Optionsvariable `prederror` kontrolliert das Verhalten von `or` für den Fall, dass ein Operand nicht zu `true` oder `false` ausgewertet werden kann. `or` gibt eine Fehlermeldung, wenn `prederror` den Wert `true` hat. Andernfalls werden Operanden akzeptiert, die nicht zu `true` oder `false` ausgewertet werden können und das Ergebnis ist ein boolescher Ausdruck.

  `or` ist nicht kommutativ, da aufgrund von nicht ausgewerteten Operanden die Ausdrücke `a or b` und `b or a` ein unterschiedliches Ergebnis haben können.

  Beispiele:

      (%i1) n:2;
      (%o1)                           2
      (%i2) oddp(n) or evenp(n);
      (%o2)                         true
      (%i3) a=b or not(1=1) or integerp(2);
      (%o3)                         true
      (%i4) a or b;
      (%o4)                        a or b
      (%i5) prederror:true$
      (%i6) a or b;

      Unable to evaluate predicate a
       -- an error. To debug this try: debugmode(true);

  Da `or` nur so viele Operanden auswertet wie notwendig sind, um das Ergebnis festzustellen, führt der syntaktische Fehler im zweiten Operanden nicht zu einer Fehlermeldung, da das Ergebnis bereits mit dem ersten Operanden feststeht.

      (%i7) integerp(2) or sin(2,2);
      (%o7)                         true

Operator: not ¶

  Ist die logische Negation. `not` ist ein Prefix-Operator. Der Operand ist ein boolescher Ausdruck und das Ergebnis ein boolescher Wert.

  Der Operator `not` erzwingt die Auswertung des Operanden. Die Optionsvariable `prederror` kontrolliert das Verhalten von `not` für den Fall, dass der Operand nicht zu `true` oder `false` ausgewertet werden kann. `not` gibt eine Fehlermeldung, wenn `prederror` den Wert `true` hat. Andernfalls wird ein Operand akzeptiert, der nicht zu `true` oder `false` ausgewertet werden kann, und das Ergebnis ist ein boolescher Ausdruck.

  Beispiele:

      (%i1) not integerp(2);
      (%o1)                         false
      (%i2) not (a=b);
      (%o2)                         true
      (%i3) not a;
      (%o3)                         not a
      (%i4) prederror:true$
      (%i5) not a;

      Unable to evaluate predicate a
       -- an error. To debug this try: debugmode(true);

### 7.5 Operatoren für Gleichungen

Operator: # ¶

  Ist der Operator für eine Ungleichung. `#` ist ein Infix-Operator mit zwei Operanden.

  Mit dem Operator `#` wird eine Ungleichung `a # b` formuliert, wobei die Operanden `a` und `b` jeweils die linke und die rechte Seite der Ungleichung sind und beliebige Ausdrücke sein können. Die Operanden werden ausgewertet, nicht jedoch die Ungleichung selbst.

  Die Funktionen `is`, `maybe`, die logischen Operatoren `and`, `or` und `not` sowie die Funktionen für die Definition von Programmanweisungen wie `if`, `while` oder `unless` erzwingen die Auswertung einer Ungleichung.

  Wegen der Regeln für die Auswertung von Aussagen und weil `not expr` die Auswertung des Argumentes `expr` bewirkt, ist der Ausdruck `not (a = b)` äquivalent zu `is(a # b)` und nicht zu `a # b`.

  Die Funktionen `rhs` und `lhs` geben die rechte und die linke Seite einer Gleichung oder Ungleichung zurück.

  Siehe auch den Operator `=`, um eine Gleichung zu formulieren, sowie die Funktionen `equal` und `notequal`.

  Beispiele:

      (%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

Operator: = ¶

  Ist der Operator für eine Gleichung. `=` ist ein Infix-Operator mit zwei Operanden.

  Mit dem Operator `=` wird eine Gleichung `a = b` formuliert, wobei die Operanden `a` und `b` jeweils die linke und die rechte Seite der Gleichung sind und beliebige Ausdrücke sein können. Die Operanden werden ausgewertet, nicht jedoch die Gleichung selbst. Nicht ausgewertete Gleichungen können als Argument von Funktionen wie zum Beispiel den Funktionen `solve`, `algsys` oder `ev` auftreten.

  Die Funktion `is` wertet eine Gleichung `=` zu einem booleschen Wert aus. `is(a = b)` wertet die Gleichung `a = b` zum Wert `true` aus, wenn `a` und `b` identische Ausdrücke sind. Das trifft zu, wenn `a` und `b` identische Atome sind oder wenn ihre Operatoren sowie die Operanden identisch sind. In jedem anderen Fall ist das Ergebnis `false`. Das Ergebnis der Auswertung ist nie `unkown`. Hat `is(a = b)` das Ergebnis `true`, werden `a` und `b` als syntaktisch gleich bezeichnet. Im Unterschied dazu gilt für äquivalente Ausdrücke, dass `is(equal(a, b))` den Wert `true` hat. Ausdrücke können äquivalent aber syntaktisch verschieden sein.

  Eine Ungleichung wird mit dem Operator `#` formuliert. Wie für den Operator `=` für eine Gleichung wird eine Ungleichung `a # b` nicht ausgewertet. Eine Auswertung erfolgt mit `is(a # b)`, welche die Werte `true` oder `false` als Ergebnis hat.

  Neben `is` werten auch die Operatoren `if`, `and`, `or` und `not` Gleichungen mit dem Operator `=` oder Ungleichungen mit dem Operator `#` zu den Werten `true` oder `false` aus.

  Wegen der Regeln für die Auswertung von Aussagen und weil im Ausdruck `not expr` der Operand `expr` ausgewertet wird, ist `not a = b` äquivalent zu `is(a # b)` und nicht zu `a # b`.

  Die Funktionen `rhs` und `lhs` geben die rechte und die linke Seite einer Gleichung oder Ungleichung zurück.

  Siehe auch den Operator `#` für Ungleichungen sowie die Funktionen `equal` und `notequal`.

  Beispiele:

  Ein Ausdruck `a = b` repräsentiert eine nicht ausgewertete Gleichung.

      (%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]

  `is(a = b)` wertet die Gleichung `a = b` zu `true` aus, wenn `a` und `b` syntaktisch gleich sind. Ausdrücke können äquivalent sein, ohne syntaktisch gleich zu sein.

      (%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]

  Einige Operatoren werten `=` und `#` zu `true` oder `false` aus.

      (%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]

  Da `not expr` die Auswertung des Ausdrucks `expr` bewirkt, ist `not (a = b)` äquivalent zu `is(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

### 7.6 Zuweisungsoperatoren

Operator: : ¶

  Ist der Operator für die Zuweisung eines Wertes an eine Variable.

  Ist die linke Seite eine Variable (ohne Index), wertet der Operator `:` die rechte Seite aus und weist den Wert der Variablen auf der linken Seite zu.

  Ist die linke Seite ein Element einer Liste, Matrix oder ein deklariertes Maxima- oder Lisp-Array, wird die rechte Seite diesem Element zugewiesen. Der Index muss ein existierendes Element bezeichnen.

  Ist die linke Seite ein Element eines nicht deklarierten Arrays, dann wird die rechte Seite diesem Element zugewiesen, falls dieses existiert. Existiert das Element noch nicht, wird ein neues Element erzeugt.

  Ist die linke Seite eine Liste mit Variablen (ohne Index), muss die rechte Seite zu einer Liste auswerten. Die Elemente der Liste auf der rechten Seite werden den Elementen auf der linken Seite parallel zugewiesen.

  Siehe auch `kill` und `remvalue` für die Aufhebung der Zuweisung eines Wertes an ein Symbol.

  Beispiele:

  Zuweisung an eine einfache Variable.

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

  Zuweisung an ein Element einer Liste.

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

  Die Zuweisung erzeugt ein nicht deklariertes Array.

      (%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]

  Mehrfache Zuweisung.

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

  Die mehrfache Zuweisung wird parallel ausgeführt. Die Werte von `a` und `b` werden in diesem Beispiel ausgetauscht.

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

Operator: :: ¶

  Ist der Operator für die Zuweisung eines Wertes an eine Variable.

  Der Operator `::` ist vergleichbar mit dem Operator `:` mit dem Unterschied, dass `::` sowohl die rechte als auch die linke Seite auswertet.

  Beispiele:

      (%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

Operator: ::= ¶

  Ist der Operator für die Definition von Makro-Funktionen.

  Der Operator `::=` definiert eine Makro-Funktion, das ist eine Funktion, die ihre Argumente nicht auswertet. Der Ausdruck, der die Makro-Funktion definiert, wird in dem Kontext ausgewertet, in dem das Makro aufgerufen wird. Ansonsten verhält sich eine Makro-Funktion wie eine gewöhnliche Funktion.

  Die Funktion `macroexpand` expandiert eine Makro-Funktion, ohne sie auszuwerten. `macroexpand(foo(x))` dem `''%` folgt, ist äquivalent zu `foo(x)`, wenn `foo` eine Makro-Funktion ist.

  Der Operator `::=` fügt den Namen der neuen Makro-Funktion der Informationsliste `macros` hinzu. Die Funktionen `kill`, `remove` und `remfunction` heben die Zuweisung der Makro-Funktion an ein Symbol auf und entfernen die Makro-Funktion von der Informationsliste `macros`.

  Die Funktionen `fundef` oder `dispfun` geben die Definition einer Makro-Funktion zurück oder weisen die Makro-Funktion einer Marke zu.

  Makro-Funktionen enthalten häufig Ausdrücke mit den Funktionen `buildq` und `splice`. Mit diesen werden Ausdrücke konstruiert, die dann ausgewertet werden.

  Beispiele:

  Eine Makro-Funktion wertet ihre Argumente nicht aus. Daher zeigt Beispiel (1) `y - z` und nicht den Wert von `y - z`. Das Makro wird in dem Kontext ausgewertet, in dem das Makro aufgerufen wird. Dies zeigt (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

  Eine gewöhnliche Funktion wertet ihre Argumente aus. Daher zeigt (1) den Wert von `y - z`. Der Rückgabewert wird nicht ausgewertet und gibt (2). Mit `''%` wird die Auswertung erzwungen.

      (%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` gibt die Expansion des Makros zurück. `macroexpand(foo(x))` dem `''%` folgt, ist äquivalent zu `foo(x)`, wenn `foo` eine Makro-Funktion ist.

      (%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

Operator: := ¶

  Ist der Operator für Funktionsdefinitionen.

  `f(x_1, ..., x_n)` := expr definiert eine Funktion mit dem Namen f, den Argumenten x_1, …, x_n und der Funktionsdefinition expr. Der Operator `:=` wertet die Funktionsdefinition nicht aus. Die Auswertung kann mit dem Quote-Quote-Operator `''` erzwungen werden. Die definierte Funktion kann eine gewöhnliche Maxima-Funktion `f(x)` sein oder eine Array-Funktion `f[i](x)`.

  Ist das letzte oder das einzige Argument der Funktion x_n eine Liste mit einem Element, dann akzeptiert die mit `:=` definierte Funktion eine variable Anzahl an Argumenten. Die Argumente werden zunächst nacheinander den Argumenten x_1, …, x_(n - 1) zugewiesen. Sind weitere Argumente vorhanden, werden diese x_n als Liste zugewiesen.

  Funktionsdefinitionen erscheinen im globalen Namensraum. Wird eine Funktion `f` innerhalb einer Funktion `g` definiert, wird die Reichweite der Funktion nicht automatisch auf `g` beschränkt. Dagegen führt `local(f)` zu einer Definition, die nur innerhalb eines Blockes oder einem anderen zusammengesetzten Ausdrück erscheint. Siehe auch `local`.

  Ist eines der Argumente ein Symbol auf das der Quote-Operator `'` angewendet wurde, wird dieses Argument nicht ausgewertet. Ansonsten werden alle Argumente ausgewertet.

  Siehe auch `define` und `::=`.

  Beispiele:

  `:=` wertet die Funktionsdefinition nie aus, außer wenn der Quote-Quote-Operator angewendet wird.

      (%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)

  Mit dem Operator `:=` definierte Funktionen können eine gewöhnliche Maxima-Funktion oder eine Array-Funktion sein.

      (%i1) G1 (x, y) := x.y - y.x;
      (%o1)               G1(x, y) := x . y - y . x
      (%i2) G2 [x, y] := x.y - y.x;
      (%o2)                G2     := x . y - y . x
                             x, y

  Ist das letzte oder einzige Argument x_n eine Liste mit einem Element, dann akzeptiert die Funktion eine variable Anzahl an Argumenten.

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

  `local` erzeugt eine lokale Funktionsdefinition.

      (%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

### 7.7 Nutzerdefinierte Operatoren

#### 7.7.1 Einführung in nutzerdefinierte Operatoren

Es ist möglich neue Operatoren zu definieren, vorhandene Operatoren zu entfernen oder deren Eigenschaften zu ändern. Jede Funktion kann als ein Operator definiert werden, die Funktion kann, muss aber nicht definiert sein.

Im Folgenden werden die Operatoren `dd` und `"<-"` definiert. Nach der Definition als Operatoren ist `dd a` gleichbedeutend mit `"dd"(a)` und `a <- b` entspricht dem Funktionsaufruf `"<-"(a,b)`. In diesem Beispiel sind die Funktionen `"dd"` und `"<-"` nicht definiert.

    (%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 kennt die folgenden Funktionen, um Operatoren zu definieren: `prefix`, `postfix`, `infix`, `nary`, `matchfix` und `nofix`.

Der Vorrang eines Operators op vor anderen Operatoren leitet sich aus dem links- und rechtsseitigen Vorrang des Operators ab. Sind die links- und rechtsseitigen Vorränge von op beide größer als der links- und rechtsseitige Vorrang eines anderen Operators, dann hat op Vorrang vor diesem Operator. Sind die Vorränge nicht beide größer oder kleiner, werden weitere Regeln zur Bestimmung des Vorrangs herangezogen.

Maxima kennt die Wortart eines Operanden und des Ergebnisses eines Operanden. Wortart bedeutet hier, den Typ eines Operanden. Maxima kennt die drei Typen `expr`, `clause` und `any`. Diese stehen für einen algebraischen Ausdruck, einen logischen Ausdruck und einen beliebigen Ausdruck. Mit Hilfe der für einen Operator definierten Wortart kann der Parser beim Einlesen eines Ausdrucks Syntaxfehler feststellen.

Die Assoziativität eines Operators op hängt ab von seinem Vorrang. Ein größerer linksseitiger Vorrang hat zur Folge, dass der Operator op vor einem anderen Operator auf seiner linken Seite ausgewertet wird. Während ein größerer rechtsseitiger Vorrang zur Folge hat, dass der Operator vor anderen Operatoren auf der rechten Seite ausgewertet wird. Daraus folgt, dass ein größerer linksseitiger Vorrang lbp einen Operator op rechts-assoziativ und eine größerer rechtsseitiger Vorrang rbp den Operator links-assoziativ macht. Sind der links- und rechtsseitige Vorrang gleich groß, ist der Operator op links-assoziativ.

Mit den Befehlen `remove` und `kill` können Operatoreigenschaften von einem Symbol entfernt werden. `remove("a", op)` entfernt die Operatoreigenschaften des Symbols a. `kill("a")` entfernt alle Eigenschaften einschließich der Operator-Eigenschaften des Symbols a. In diesem Fall steht der Name des Symbols in Anführungszeichen.

    (%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)

#### 7.7.2 Funktionen und Variablen für nutzerdefinierte Operatoren

Funktion: infix (op) ¶
Funktion: infix (op, lbp, rbp) ¶
Funktion: infix (op, lbp, rbp, lpos, rpos, pos) ¶

  Deklariert op als einen Infix-Operator. Ein Infix-Operator hat eine Funktionsdefinition mit zwei Argumenten. Der Infix-Operator steht zwischen den Operanden. Zum Beispiel ist die Subtraktion `-` ein Infix-Operator.

  `infix(op)` deklariert op als einen Infix-Operator mit einem links- und rechtsseitigen Vorrang von jeweils 180.

  `infix(op, lbp, rbp)` deklariert op als einen Infix-Operator mit den angegebenen Werten für den links- und rechtsseitigen Vorrang.

  `infix(op, lbp, rbp, lpos, rpos, pos)` deklariert op als einen Infix-Operator mit den angegebenen Vorrängen sowie den Wortarten lpos, rpos und pos für den linken und den rechten Operanden sowie das Ergebnis des Operators.

  Beispiele:

  Sind die rechtsseitigen und linksseitigen Vorränge eines Operators op größer als die entsprechenden Vorränge eines anderen Operators, dann hat der Operator op Vorrang.

      (%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)

  Ein größerer linksseitige Vorrang lbp bewirkt, dass der Operator op rechts-assoziativ ist. Ein größerer rechtsseitiger Vorrang macht dagegen den Operator op links-assoziativ.

      (%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 kann Syntaxfehler beim Einlesen eines Ausdrucks feststellen, wenn der eingelesene Operand nicht die für den Operator definierte Wortart hat.

      (%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

Funktion: matchfix (ldelimiter, rdelimiter) ¶
Funktion: matchfix (ldelimiter, rdelimiter, arg_pos, pos) ¶

  Deklariert einen Matchfix-Operator mit dem linksseitigen Begrenzungszeichen ldelimiter und dem rechtsseitigen Begrenzungszeichen rdelimiter.

  Ein Matchfix-Operator hat eine beliebige Anzahl an Argumenten, die zwischen dem linksseitigen und dem rechtsseitigen Begrenzungszeichen stehen. Das Begrenzungszeichen kann eine beliebige Zeichenkette sein. Einige Zeichen wie `%`, `,`, `$` und `;` können nicht als Begrenzungszeichen definiert werden.

  Ein linksseitiges Begrenzungszeichen kann nicht verschiedene rechtsseitige Begrenzungszeichen haben.

  Maxima-Operatoren können als Matchfix-Operatoren definiert werden, ohne dass sich die sonstigen Operatoreigenschaften ändern. So kann zum Beispiel der Operator `+` als Matchfix-Operator definiert werden.

  `matchfix(ldelimiter, rdelimiter, arg_pos, pos)` definiert die Wortarten für die Argumente arg_pos und das Ergebnis pos sowie das linksseitige ldelimiter und rechtsseitige rdelimiter Begrenzungszeichen.

  Die zu einem Matchfix-Operator zugehörige Funktion kann jede nutzerdefinierte Funktion sein, die mit `:=` oder `define` definiert wird. Die Definition der Funktion kann mit `dispfun(ldelimiter)` ausgegeben werden.

  Maxima kennt nur den Operator für Listen `[ ]` als Matchfix-Operator. Klammern `( )` und Anführungszeichen `" "` arbeiten wie Matchfix-Operatoren, werden aber vom Parser nicht als Matchfix-Operatoren behandelt.

  `matchfix` wertet die Argumente aus. `matchfix` gibt das erste Argument ldelimiter als Ergebnis zurück.

  Beispiele:

  Begrenzungszeichen können eine beliebige Zeichenkette sein.

      (%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-Operatoren können für nutzerdefinierte Funktionen definiert werden.

      (%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

Funktion: nary (op) ¶
Funktion: nary (op, bp, arg_pos, pos) ¶

  `nary(op)` definiert einen `N-ary`-Operator op mit einem linksseitigen Vorrang von 180. Der rechtsseitige Vorrang wird nicht benötigt.

  `nary(op, bp, arg_pos, pos)` definiert einen `N-ary`-Operator op mit einem rechtsseitigen Vorrang von bp und der Wortart arg_pos für den Operanden und der Wortart pos für das Ergebnis.

  Ein `N-ary`-Operator ist ein Operator, der eine beliebige Anzahl an Argumenten haben kann. Die Argumente werden durch den Operator voneinander getrennt, so ist zum Beispiel `+` ein `N-ary`-Operator und `A+B+C`.

  Im Unterschied zur Definition eines Operators kann eine Funktion `f` auch als `nary` mit der Funktion `declare` deklariert werden. Die Deklaration hat Auswirkung auf die Vereinfachung der Funktion. Zum Beispiel wird ein Ausdruck `j(j(a,b),j(c,d)` zu `j(a,b,c,d)` vereinfacht.

Funktion: nofix (op) ¶
Funktion: nofix (op, pos) ¶

  `nofix(op)` definiert den Operator op als einen Nofix-Operator.

  `nofix(op, pos)` definiert einen Nofix-Operator mit der Wortart pos für das Ergebnis.

  Nofix-Operatoren sind Operatoren, die kein Argument haben. Tritt ein solcher Operator allein auf, wird die dazugehörige Funktion ausgewertet. Zum Beispiel beendet die Funktion `quit()` eine Maxima-Sitzung. Wird diese Funktion mit `nofix("quit")` als ein Nofix-Operator definiert, genügt die Eingabe von `quit`, um eine Maxima-Sitzung zu beenden.

Funktion: postfix (op) ¶
Funktion: postfix (op, lbp, lpos, pos) ¶

  `postfix (op)` definiert einen Postfix-Operator op.

  `postfix (op, lbp, lpos, pos)` definiert einen Postfix-Operator op mit einem linksseitigem Vorrang von lbp sowie den Wortarten lpos für den Operanden und pos für das Ergebnis.

  Ein Postfix-Operator hat einen Operanden, der dem Operator vorangestellt ist. Ein Beispiel ist der `!`-Operator mit `3!`. Die Funktion `postfix("x")` erweitert die Maxima-Syntax um den Postfix-Operator `x`.

Funktion: prefix (op) ¶
Funktion: prefix (op, rbp, rpos, pos) ¶

  `prefix (op)` definiert einen Prefix-Operator op.

  `prefix (op, lbp, lpos, pos)` definiert einen Prefix-Operator op mit einem rechtsseitigem Vorrang von rbp sowie den Wortarten rpos für den Operanden und pos für das Ergebnis.

  Ein Prefix-Operator hat einen Operanden, der dem Operator nachfolgt. Mit `prefix("x")` wird die Maxima-Syntax um einen Prefix-Operator `x` erweitert.