Maxima Manual: 27. Programmierung

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

# 27. Programmierung

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

## 27.1 Lisp und Maxima

### Lisp- und Maxima-Bezeichner

Maxima ist in Lisp programmiert. Es ist einfach, Lisp-Funktionen und Lisp-Variable in Maxima zu verwenden. Umgekehrt können Maxima-Funktionen und Maxima-Variablen in Lisp verwendet werden. Ein Lisp-Symbol, das mit einem Dollarzeichen `$` beginnt, entspricht einem Maxima-Symbol ohne einem Dollarzeichen. Umgekehrt entspricht einem Maxima-Symbol, das mit einem Fragezeichen `?` beginnt, ein Lisp-Symbol ohne das Fragezeichen. Zum Beispiel entspricht dem Maxima-Symbol `foo` das Lisp-Symbol `$foo` und dem Maxima-Symbol `?foo` entspricht das Lisp-Symbol `foo`.

Speziellen Zeichen wie einem Trennstrich `-` oder einem Stern `*` in Lisp-Symbolen muss ein Backslash `\` vorangestellt werden, um diese in Maxima zu verwenden. Zum Beispiel entspricht dem Lisp-Symbol `*foo-bar*` das Maxima-Symbol `?\*foo\-bar\*`.

Im Gegensatz zu Lisp unterscheidet Maxima Groß- und Kleinschreibung. Es gibt einige Regeln, die eine Übersetzung von Namen zwischen Lisp und Maxima betreffen:

1. Ein Lisp-Bezeichner, der nicht von senkrechten Strichen eingeschlossen ist, entspricht einem klein geschriebenen Maxima-Bezeichner. Die Schreibweise des Lisp-Bezeichners wird dabei ignoriert. Zum Beispiel entspricht den folgenden Lisp-Bezeichnern `$foo`, `$FOO` und `$Foo` jeweils der Maxima-Bezeichner `foo`.
2. Ein Lisp-Bezeichner, der vollständig groß oder klein geschrieben ist und von senkrechten Strichen eingeschlossen wird, entspricht einem Maxima-Bezeichner in der umgekehrten Schreibweise. Ein klein geschriebener Lisp-Bezeichner wird also zu einem großgeschriebenen Maxima-Bezeichner und umgekehrt. Zum Beispiel entsprechen den Lisp-Bezeichnern `|$FOO|` und `|$foo|` die Maxima-Bezeichner `foo` und `FOO`.
3. Ein Lisp-Bezeichner in gemischter Schreibweise, der von senkrechten Strichen eingeschlossen ist, entspricht einem Maxima-Bezeichner in der gleichen Schreibweise. Zum Beispiel entspricht dem Lisp-Bezeichner `|$Foo|` der Maxima-Bezeichner `Foo`.

Für die Syntax von Maxima-Bezeichnern siehe auch Bezeichner.

### Ausführung von Lisp-Code in Maxima

Lisp-Code kann mit dem Unterbrechungskommando `:lisp` von einer Maxima-Kommandozeile ausgeführt werden. Siehe Debugger-Kommandos für weitere Unterbrechungskommandos und deren Beschreibung.

Beispiele:

Addiere die Werte der Maxima-Variablen `x` und `y` mit dem Lisp-Operator `+`.

    (%i1) x:10$ y:5$
    (%i3) :lisp (+ $x $y)
    15

Addiere die Symbole `a` und `b` mit der Lisp-Funktion `ADD`. Das Ergebnis wird der Variablen `$RES` zugewiesen. Die Variable hat in Maxima den Namen `res`.

    (%i3) :lisp (setq $res (add '$a '$b))
    ((MPLUS SIMP) $A $B)
    (%i3) res;
    (%o3)                         b + a

Das `:lisp`-Kommando ist nützlich, um zum Beispiel Lisp-Eigenschaften von Maxima-Symbolen anzuzeigen, globale Lisp-Variablen wie `*PRINT-CIRCLE*` zu setzen oder wie im letzten Beispiel die interne Form von Maxima-Ausdrücken anzuzeigen.

    (%i4) :lisp (symbol-plist 'mabs)
    (TEXSYM ((\left| ) \right| ) TEX TEX-MATCHFIX REAL-VALUED T
            MAPS-INTEGERS-TO-INTEGERS T DIMENSION DIM-MABS TRANSLATE
            #<FUNCTION (LAMBDA #) {972D045}> FLOATPROG MABSBIGFLOAT INTEGRAL
            ((X) #<FUNCTION ABS-INTEGRAL>) OPERATORS SIMPABS DISTRIBUTE_OVER
            (MLIST $MATRIX MEQUAL) NOUN $ABS REVERSEALIAS $ABS GRAD
            ((X) ((MTIMES) X ((MEXPT) ((MABS) X) -1))))

    (%i4) :lisp (setq *print-circle* nil)
    NIL

    (%i4) 'integrate(t*sin(t), t);
                              /
                              [
    (%o4)                     I t sin(t) dt
                              ]
                              /
    (%i5) :lisp $%
    ((%INTEGRATE SIMP) ((MTIMES SIMP) $T ((%SIN SIMP) $T)) $T)

Das Kommando `:lisp` kann in einer Kommandozeile und in Dateien verwendet werden, die mit den Funktionen `batch` oder `demo` geladen werden. Dagegen kann das Kommando `:lisp` nicht in Dateien verwendet werden, die mit den Funktionen `load`, `batchload`, `translate_file` oder `compile_file` geladen werden.

### Ausführung von Maxima-Code in Lisp

Das Lisp-Makro `#$` erlaubt die Nutzung von Maxima-Ausdrücken in Lisp-Code. `#$expr$` wird zu einem Lisp-Ausdruck expandiert, der dem Maxima-Ausdruck expr entspricht.

Beispiele:

Die beiden folgenden Beispiele zeigen die Zuweisung an eine Variable `var`. Im ersten Beispiel werden Lisp- und Maxima-Code gemischt. Für die Zuweisung an die Variable wird die Lisp-Funktion `MSETQ` aufgerufen. Das Makro `#$` transformiert den Maxima Ausdruck `sin(x) + a^2` in die Lisp-Form `((MPLUS SIMP) ((MEXPT SIMP) $A 2) ((%SIN SIMP) $X))`. Dies entspricht dem im zweiten Beispiel gezeigten Maxima-Kommando.

    (%i1) :lisp (msetq $var #$sin(x)+a^2$)
    ((MPLUS SIMP) ((MEXPT SIMP) $A 2) ((%SIN SIMP) $X))

    (%i1) var: sin(x)+a^2;
                                         2
    (%o1)                      sin(x) + a

In diesem Beispiel wird zunächst ein Maxima-Ausdruck der Variablen `$VAR` zugewiesen und dann mit der Lisp-Funktion `DISPLA` ausgegeben.

    (%i1) :lisp (setq $var #$'integrate(f(x), x)$)
    ((%INTEGRATE SIMP) (($F SIMP) $X) $X)
    (%i1) :lisp (displa $var)
    /
    [
    I f(x) dx
    ]
    /
    NIL

Maxima-Funktionen sind keine Lisp-Funktionen. Um eine Maxima-Funktion in Lisp-Code aufzurufen, kann die Lisp-Funktion `MFUNCALL` aufgerufen werden.

    (%i1) f(x,y) := x^2 + sin(y)$
    (%i2) :lisp (mfuncall '$f '$a 10)
    ((MPLUS SIMP) ((%SIN SIMP) 10) ((MEXPT SIMP) $A 2))

### Öffnen einer Lisp-Sitzung

Mit dem Kommando `to_lisp()` kann von einer Maxima-Kommandozeile eine Lisp-Sitzung geöffnet werden. Mit dem Kommando `(TO-MAXIMA)` wird die Lisp-Sitzung beendet und nach Maxima zurückgekehrt. Siehe auch `to_lisp` für ein Beispiel.

Die folgenden Lisp-Funktionen können in Maxima nicht verwendet werden:

`complement`, `continue`, `/`, `float`, `functionp`, `array`, `exp`, `listen`, `signum`, `atan`, `asin`, `acos`, `asinh`, `acosh`, `atanh`, `tanh`, `cosh`, `sinh`, `tan`, `break`, und `gcd`.

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

## 27.2 Einführung in die Programmierung

In Maxima können Programme geschrieben werden. Alle Maxima-Funktionen und Maxima-Variablen können in Programmen verwendet werden. Maxima hat einen Übersetzer, um Maxima-Programme in Lisp-Programme zu übersetzen, und einen Compiler, um die übersetzten Programme zu kompilieren. Siehe dazu das Kapitel Übersetzer.

Maxima-Programme bestehen aus Funktionen und Makros, die im Kapitel Funktionsdefinitionen beschrieben sind. Die Funktionen werden aus Ausdrücken der Form `(expr_1, expr_2, ..., expr_n)` oder `block`-Anweisungen zusammengesetzt. Mit der Anweisung `local` werden Variablen definiert, deren Werte und Eigenschaften lokal zu einem Block sind.

Konditionale Verzweigen werden mit der Anweisung `if` definiert und haben die Form `if ... then ... else`.

Maxima kennt die sehr allgemeine Anweisung `for`, um Schleifen zu programmieren. Schlüsselworte für die Programmierung von Schleifen sind `while`, `unless`, `do` sowie `thru`, `step`, `in`.

Mit der Sprunganweisung `return` kann ein Block verlassen werden und mit der Sprunganweisung `go` wird innerhalb eines Blockes zu eine Marke verzweigt. Nicht-lokale Rücksprünge aus Funktionen werden mit den Anweisungen `catch` und `throw` programmiert.

Die Anweisung `errcatch` fängt Fehler ab, so dass die Ausführung eines Programms nicht abgebrochen wird. Mit der Anweisungen `error` und `break` wird ein Programm abgebrochen. Im ersten Fall kann eine Fehlermelung ausgegeben werden und das Programm kehrt zur Maxima-Kommandozeile zurück. Mit `break` wird der Maxima-Debugger gestartet.

Maxima kennt die folgenden Anweisungen und Variablen um Programme zu definieren:

       backtrace    block        break
       catch        do           eval_when
       errcatch     error        error_size
       error_syms   errormsg     for
       go           if           local
       return       throw        unless
       while

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

## 27.3 Funktionen und Variablen der Programmierung

Funktion: backtrace ()
Funktion: backtrace (n)

  Gibt den Aufruf-Stack der Funktion zurück, die ausgeführt wird.

  Das Kommando `backtrace()` zeigt den gesamten Stack. `backtrace(n)` zeigt die letzten n Funktionen einschließlich der Funktion, die ausgeführt wird.

  `backtrace` kann in einer Batch-Datei, die zum Beispiel mit der Funktion `batch` geladen wird, in einer Funktion oder von einer Kommandozeile aufgerufen werden.

  Beispiele:

  `backtrace()` gibt den gesamten Stack aus.

      (%i1) h(x) := g(x/7)$
      (%i2) g(x) := f(x-11)$
      (%i3) f(x) := e(x^2)$
      (%i4) e(x) := (backtrace(), 2*x + 13)$
      (%i5) h(10);
      #0: e(x=4489/49)
      #1: f(x=-67/7)
      #2: g(x=10/7)
      #3: h(x=10)
                                    9615
      (%o5)                         ----
                                     49

  `backtrace(n)` gibt die letzten n Funktionen aus.

      (%i1) h(x) := (backtrace(1), g(x/7))$
      (%i2) g(x) := (backtrace(1), f(x-11))$
      (%i3) f(x) := (backtrace(1), e(x^2))$
      (%i4) e(x) := (backtrace(1), 2*x + 13)$
      (%i5) h(10);
      #0: h(x=10)
      #0: g(x=10/7)
      #0: f(x=-67/7)
      #0: e(x=4489/49)
                                    9615
      (%o5)                         ----
                                     49

Funktion: block ([v_1, …, v_m], expr_1, …, expr_n)
Funktion: block (expr_1, …, expr_n)

  Mit der Anweisung `block` werden Ausdrücke in einer lokalen Umgebung zusammengefasst. `block` wertet die Argument expr_1, expr_2, …, expr_n nacheinander aus und gibt das Ergebnis des letzten ausgewerteten Ausdrucks zurück. Die Liste `[v_1, ..., v_m]` am Anfang der `block`-Anweisung bezeichnet Variablen, die innerhalb der `block`-Anweisung lokal sind. Alle anderen Variablen, die in einem Block verwendet werden, beziehen sich auf globale Variablen, die auÃerhalb des Block definiert sind. Dies kann ein weiterer Block oder die globale Maxima-Umgebung sein. `block` sichert die aktuellen Werte der Variablen v_1, …, v_m. Wird `block` verlassen, werden diese Werte wiederhergestellt.

  Die Deklaration `local(v_1, ..., v_m)` innerhalb der `block`-Anweisung sichert nicht nur die Werte, sondern auch die Eigenschaften der Variablen wie sie zum Beispiel mit den Funktionen `declare` oder `depends` definiert werden. Erhalten die mit `local` deklarierten Variablen innerhalb der `block`-Anweisung Eigenschaften, wirken sich diese nur lokal aus. Beim Verlassen der `block`-Anweisung werden die globalen Eigenschaften wiederhergestellt. Siehe auch `local`.

  Die `block`-Anweisung kann verschachtelt werden. Jeder Block kann eigene lokale Variablen definieren. Diese sind global zu jedem anderen Block der sich innerhalb des Blockes befindet. Ein Variable die nicht als lokal definiert ist, hat den globalen Wert eines umgebenden Blocks oder den Wert der globalen Maxima-Umgebung.

  Der Rückgabewert eines Blocks ist der Wert des letzten Ausdrucks oder der Wert, der mit den `return`-Anweisung zurückgegeben wird. Mit der `go`-Anweisung kann innerhalb eines Blocks zu einer Marke gesprungen werden. Weiterhin kann mit der `throw`-Anweisung ein nicht-lokaler Rücksprung zu einer entsprechenden `catch`-Anweisung erfolgen.

  Blöcke erscheinen typischerweise auf der rechten Seite einer Funktionsdefinitionen. Sie können aber auch an anderen Stellen verwendet werden.

  Beispiel:

  Das Beispiel zeigt eine einfache Implementation des Newton-Algorithmus. Der Block definiert die lokalen Variablen `xn`, `s` und numer. `numer` ist eine Optionsvariable, die im Block einen lokalen Wert erhält. Im Block ist das Tag `loop` definiert. Zu diesem Tag wird mit der Anweisung `go(loop)` gesprungen. Der Block und damit die Funktion wird mit der Anweisung `return(xn)` verlassen. Der Wert der Variablen `xn` ist das Ergebnis der Funktion `newton`.

      newton(exp,var,x0,eps):=
         block([xn,s,numer],
            numer:true,
            s:diff(exp,var),
            xn:x0,
         loop,
            if abs(subst(xn,var,exp))<eps then return(xn),
            xn:xn-subst(xn,var,exp)/subst(xn,var,s),
            go(loop) )$

Funktion: break (expr_1, …, expr_n)

  Wertet die Ausdrücke expr_1, …, expr_n aus, zeigt die Ergebnisse an und führt dann eine Unterbrechung aus. Mit dem Kommando `exit;` wird Maxima fortgesetzt. Siehe das Kapitel

  Beispiel:

  Der Variablen `a` wird der Wert 2 zugewiesen. Dann wird die Unterbrechung ausgeführt. Mit dem Kommando `exit;` wird Maxima fortgesetzt.

      (%i1) break(a:2);
      2

      Entering a Maxima break point. Type 'exit;' to resume.
      _a;
      2
      _exit;
      (%o1)                           2

Funktion: catch (expr_1, …, expr_n)

  Wertet die Ausdrücke expr_1, …, expr_n nacheinander aus. Wertet irgendeiner der Ausdrücke zu `throw(arg)` aus, dann ist das Ergebnis der Wert von `throw(arg)` und es werden keine weiteren Ausdrücke ausgewertet. Diese nicht-lokale Rückgabe kehrt zu dem nächsten `catch` in einer beliebigen Verschachtelungstiefe zurück. Wird kein `catch` gefunden gibt Maxima eine Fehlermeldung aus.

  Führt die Auswertung der Argumente nicht zu einem `throw`, dann ist die Rückgabe das Ergebnis des letzten Ausdrucks `expr_n`.

  Beispiel:

  Die Funktion `g` gibt eine Liste mit den Werten des Lambda-Ausdrucks zurück. Tritt ein negativer Wert auf, bricht die Funktion ab, in diesem Beispiel mit `throw(-3)`.

      (%i1) lambda ([x], if x < 0 then throw(x) else f(x))$
      (%i2) g(l) := catch (map (''%, l))$
      (%i3) g ([1, 2, 3, 7]);
      (%o3)               [f(1), f(2), f(3), f(7)]
      (%i4) g ([1, 2, -3, 7]);
      (%o4)                          - 3

Spezieller Operator: do

  Die `do`-Anweisung erlaubt die Definition von Iterationen. Aufgrund der großen Allgemeinheit der `do`-Anweisung folgt die Beschreibung in zwei Teilen. Zunächst werden die bekannteren Formen beschrieben, wie sie auch in anderen Programmiersprachen vorhanden sind. Dann folgen die weiteren Möglichkeiten.

  Es gibt drei Varianten der `do`-Anweisung, die sich nur durch die Abbruchbedingung voneinander unterscheiden. Diese sind:

      for variable: initial_value step increment
            thru limit do body

      for variable: initial_value step increment
            while condition do body

      for variable: initial_value step increment
            unless condition do body

  initial_value, increment, limit und body können beliebige Ausdrücke sein. Ist das Inkrement 1, kann `step` entfallen.

  Die Ausführung der `do`-Anweisung beginnt mit der Zuweisung von `initial_value` an die Kontrollvariable variable. Dann folgen die Schritte: (1) Hat die Kontrollvariable den Wert einer `thru`-Anweisung überschritten oder hat die Bedingung einer `unless`-Anweisung den Wert `true` oder hat die Bedingung einer `while`-Anweisung den Wert `false`, dann endet die Ausführung der `do`-Anweisung. (2) Die Ausdrücke in body werden ausgewertet. (3) Das Inkrement wird zu der Kontrollvariablen hinzuaddiert. Die Schritte (1) bis (3) werden solange ausgeführt, bis eine der Bedingungen für die Beendigung der `do`-Anweisung zutrifft.

  Im Allgemeinen ist der `thru`-Test erfüllt, wenn die Kontrollvariable größer als limit ist, falls increment nicht negativ ist. Oder wenn die Kontrollvariable kleiner als `limit` ist, für den Fall, dass das Inkrement negativ ist. increment und limit können Ausdrücke sein, sofern die Bedingung zum Abbruch der `do`-Anweisung ausgewertet werden kann. Soll `increment` zu einem negativen Wert auswerten und kann dies jedoch bei Eintritt in die Schleife von Maxima nicht festgestellt werden, so wird das Inkrement als positiv angenommen. Dies kann dazu führen, dass die Schleife nicht korrekt ausgeführt wird.

  limit, increment und die Bedingung für den Abbruch der Schleife werden für jeden Durchgang durch die Schleife ausgewertet. Ändern diese ihren Wert nicht, kann es daher effizienter sein, die Werte diese Ausdrücke vor Eintritt in die Schleife zu berechnen und in Variablen abzulegen, die anstatt der Ausdrücke in der Schleife verwendet werden.

  Die `do`-Anweisung hat den Rückgabewert `done`. Um einen anderen Wert zurückzugeben, kann die `return`-Anweisung innerhalb von `body` genutzt werden. Befindet sich die `do`-Anweisung innerhalb eines Blockes, so wird dieser nicht mit einer `return`-Anweisung verlassen, die sich innerhalb der `do`-Anweisung befindet. Auch kann nicht mit der `go`-Anweisung in einen umgebenen Block gesprungen werden.

  Die Kontrollvariable ist immer lokal zur `do`-Anweisung. Nach dem Verlassen der `do`-Anweisung kann auf die Kontrollvariable nicht mehr zugegriffen werden.

      (%i1) for a:-3 thru 26 step 7 do display(a)$
                                   a = - 3

                                    a = 4

                                   a = 11

                                   a = 18

                                   a = 25

  Die Bedingung `while i <= 10` ist äquivalent zu den Bedingungen `unless i > 10` und `thru 10` ist.

      (%i1) s: 0$
      (%i2) for i: 1 while i <= 10 do s: s+i;
      (%o2)                         done
      (%i3) s;
      (%o3)                          55

  Berechne die ersten acht Terme einer Taylorreihe in einer `do`-Schleife.

      (%i1) series: 1$
      (%i2) term: exp (sin (x))$
      (%i3) for p: 1 unless p > 7 do
                (term: diff (term, x)/p,
                 series: series + subst (x=0, term)*x^p)$
      (%i4) series;
                        7    6     5    4    2
                       x    x     x    x    x
      (%o4)            -- - --- - -- - -- + -- + x + 1
                       90   240   15   8    2

  In diesem Beispiel wird die negative Wurzel von 10 mit einem Newton-Raphson-Algorithmus berechnet.

      (%i1) poly: 0$
      (%i2) for i: 1 thru 5 do
                for j: i step -1 thru 1 do
                    poly: poly + i*x^j$
      (%i3) poly;
                        5      4       3       2
      (%o3)          5 x  + 9 x  + 12 x  + 14 x  + 15 x
      (%i4) guess: -3.0$
      (%i5) for i: 1 thru 10 do
                (guess: subst (guess, x, 0.5*(x + 10/x)),
                 if abs (guess^2 - 10) < 0.00005 then return (guess));
      (%o5)                  - 3.162280701754386

  Anstatt eines festes Inkrements mit `step` kann die Kontrollvariable auch mit `next` für jeden Schleifendurchgang berechnet werden.

      (%i6) for count: 2 next 3*count thru 20 do display (count)$
                                  count = 2

                                  count = 6

                                 count = 18

  Anstatt mit der Syntax `for variable: value ...` kann die Kontrollvariable auch mit `for variable from value ...do...` initialisiert werden. Wird auch `from value` fortgelassen, wird die Kontrollvariable mit dem Wert 1 initialisiert.

  Manchmal kann es von Interesse sein, in einer Schleife keine Kontrollvariable zu nutzen. In diesem Fall genügt es allein die Bedingung für den Abbruch der Schleife anzugeben. Im folgenden wird die Wurzel aus 5 mit dem Heron-Verfahren bestimmt.

      (%i1) x: 1000$
      (%i2) thru 20 do x: 0.5*(x + 5.0/x)$
      (%i3) x;
      (%o3)                   2.23606797749979
      (%i4) sqrt(5), numer;
      (%o4)                   2.23606797749979

  Auch die Abbruchbedingung kann fortgelassen werden. Wird allein `do body` angegeben, wird die Schleife unendlich oft ausgeführt. Die Schleife kann mit der `return`-Anweisung verlassen werden. Das folgende Beispiel zeigt eine Implementierung des Newton-Algorithmus.

      (%i1) newton (f, x):= ([y, df, dfx], df: diff (f ('x), 'x),
                do (y: ev(df), x: x - f(x)/y,
                    if abs (f (x)) < 5e-6 then return (x)))$
      (%i2) sqr (x) := x^2 - 5.0$
      (%i3) newton (sqr, 1000);
      (%o3)                   2.236068027062195

  Eine weitere Syntax ist die folgende:

      for variable in list end_tests do body

  Die Elemente der Liste list können beliebige Ausdrücke sein, die nacheinander der Kontrollvariablen zugewiesen werden. Die Schleife bricht ab, wenn die optionale Abbruchbedingung `end_test` zutrifft, wenn die Liste list keine weiteren Elemente enthält oder wenn die Schleife zum Beispiel mit der Funktion `return` verlassen wird.

      (%i1)  for f in [log, rho, atan] do ldisp(f(1))$
      (%t1)                                  0
      (%t2)                                rho(1)
                                           %pi
      (%t3)                                 ---
                                            4
      (%i4) ev(%t3,numer);
      (%o4)                             0.78539816

Funktion: eval_when (keyword, expr_1, …, expr_n)
Funktion: eval_when ([keyword_1, keyword_2, …], expr_1, …, expr_n)

  Ein Ausdruck mit der Funktion `eval_when` wird an oberster Stelle in einer Datei definiert und erlaubt die bedingte Auswertung von Ausdrücken beim Laden, Übersetzen oder Kompilieren einer Datei. Das Argument keyword ist eines der Schlüsselworte `batch`, `translate`, `compile` oder `loadfile`. Das erste Argument kann ein einzelnes Schlüsselwort oder ein Liste mit mehreren Schlüsselworten sein. Trifft die mit dem Schlüsselwort angegebene Bedingung zu, wird eine oder mehrere der folgenden Aktionen ausgeführt:

  `batch`

    Wird die Datei mit einer der Funktionen `load`, `batch`, `batchload` oder `demo` geladen und ist `batch` in der Liste der Schlüsselworte enthalten, dann werden die Ausdrücke expr1, …, expr_n genau einmal beim Laden der Datei ausgewertet. Die Rückgabe der Funktion `eval_when` ist ein Ausdruck `evaluated_when(result)`, wobei result das Ergebnis der Auswertung ist. Ist das Schlüsselwort `batch` nicht vorhanden, ist die Rückgabe das Symbol `not_evaluated_when`.

  `translate`

    Wird die Datei mit dem Kommando `translate_file` oder `compile_file` geladen und ist `translate` unter den Schlüsselworten, dann werden die Ausdrücke expr_1, …, expr_n sofort ausgewertet. Seiteneffekte wie Zuweisungen von Werten an Optionsvariablen oder Deklarationen sind für die folgende Übersetzung der Datei nach Lisp wirksam. Die Ausdrücke sind jedoch nicht Teil des übersetzten Programms.

  `loadfile`

    Wird die Datei mit dem Kommando `translate_file` oder dem Kommando `compile_file` geladen und ist `loadfile` unter den Schlüsselworten, dann werden die Ausdrücke expr_1, …, expr_n nach Lisp übersetzt und als Block der Form `(PROGN EXPR_1 ... EXPR_N)` in das Lisp Programm eingesetzt. Hier sind die Anweisungen EXPR_I die nach Lisp übersetzten Maxima-Ausdrücke expr_i.

  `compile`

    Wird die Datei mit dem Kommando `translate_file` oder `compile_file` geladen und ist `compile` unter den Schlüsselworten, dann werden die Ausdrücke expr_1, …, expr_n nach Lisp übersetzt und als eine Lisp-Anweisung in das Lisp-Programm eingesetzt, die die Form `(EVAL-WHEN (:COMPILE-TOPLEVEL) (EXPR_1 ... EXPR_N))` hat. Das Schlüsselwort `compile` kann nicht mit dem Schlüsselwort `loadfile` in einem `eval_when`-Ausdruck kombiniert werden. In diesem Fall wird das Schlüsselwort `compile` ignoriert.

  Beispiele:

  Für die folgende Beispiele ist eine Datei mit den Namen `eval_when.mac` definiert, die verschiedene `eval_when`-Anweisungen enthält.

      (%i1) file: file_search("eval_when.mac");
      (%o1)        /home/dieter/.maxima/eval_when.mac
      (%i2) printfile(file);

      eval_when(batch,     print("called in mode BATCH"));
      eval_when(loadfile,  print("called in mode LOADFILE"));
      eval_when(compile,   print("called in mode COMPILE"));
      eval_when(translate, print("called in mode TRANSLATE"));

      (%o2)        /home/dieter/.maxima/eval_when.mac

  Die Datei wird mit dem Kommando `load` geladen. Die Anweisung mit dem Schlüsselwort `batch` wird beim Laden einmal ausgeführt.

      (%i1) file: file_search("eval_when.mac");
      (%o1)        /home/dieter/.maxima/eval_when.mac
      (%i2) load(file);
      called in mode BATCH
      (%o2)        /home/dieter/.maxima/eval_when.mac

  In diesem Fall wird die Datei mit dem Befehl `batch` geladen. Die Anweisung mit dem Schlüsselwort `batch` wird einmal ausgeführt. Die anderen `eval_when`-Anweisungen werten jeweils zum Ergebnis `not_evaluated_when` aus.

      (%i3) batch(file);

      read and interpret file: /home/dieter/.maxima/eval_when.mac
      (%i4)     eval_when(batch, print(called in mode BATCH))
      called in mode BATCH
      (%o4)         evaluated_when(called in mode BATCH)
      (%i5)  eval_when(loadfile, print(called in mode LOADFILE))
      (%o5)                  not_evaluated_when
      (%i6)   eval_when(compile, print(called in mode COMPILE))
      (%o6)                  not_evaluated_when
      (%i7) eval_when(translate, print(called in mode TRANSLATE))
      (%o7)                  not_evaluated_when
      (%o7)        /home/dieter/.maxima/eval_when.mac

  Jetzt wird die Datei mit dem Kommando `translate_file` geladen und nach Lisp übersetzt. Der Ausdruck mit dem Schlüsselwort `translate` wird sofort ausgewertet. Das übersetzte Programm wird in die Ausgabedatei `eval_when.LISP` geschrieben. Die `eval_when`-Anweisung zum Schlüsselwort wird nicht ausgewertet.

      (%i1) file: file_search("eval_when.mac");
      (%o1)        /home/dieter/.maxima/eval_when.mac
      (%i2) translate_file(file);
      translator: begin translating /home/dieter/.maxima/eval_when.mac.
      called in mode TRANSLATE
      (%o2) [/home/dieter/.maxima/eval_when.mac,
      /home/dieter/.maxima/eval_when.LISP,
      /home/dieter/.maxima/eval_when.UNLISP]

  Dies ist der Inhalt der Ausgabedatei `eval_when.LISP`. Die Ausgabedatei enthält eine `PROGN`-Anweisung mit dem Ausdruck `($print '"called in mode LOADFILE")` für den `eval_when`-Ausdruck zum Schlüsselwort `loadfile` sowie eine `EVAL-WHEN`-Anweisung mit dem Ausdruck `($print '"called in mode COMPILE")` für den `eval_when`-Ausdruck mit dem Schlüsselwort `compile`.

      ;;; -*- Mode: Lisp; package:maxima; syntax:common-lisp ;Base: 10 -*- ;;;
      ;;; Translated on: 2011-10-02 13:35:37+02:00
      ;;; Maxima version: 5.25post
      ;;; Lisp implementation: SBCL
      ;;; Lisp version: 1.0.45
      (in-package :maxima)

      [...]

      nil
      (progn ($print '"called in mode LOADFILE"))
      (eval-when (:compile-toplevel) ($print '"called in mode COMPILE"))
      nil

Funktion: errcatch (expr_1, …, expr_n)

  Wertet die Ausdrücke expr_1, …, expr_n nacheinander aus und gibt das Ergebnis des letzten Ausdrucks als eine Liste `[expr_n]` zurück, wenn kein Fehler bei der Auswertung auftritt. Tritt ein Fehler bei der Auswertung eines der Ausdrücke auf, ist die Rückgabe eine leere Liste `[]`.

  `errcatch` ist nützlich in Batch-Dateien. Mit `errcatch` kann ein möglicher Fehler abgefangen werden, ohne das die Verarbeitung der Batch-Datei abbricht.

  Beispiele:

      (%i1) errcatch(x:2,1/x);
                                      1
      (%o1)                          [-]
                                      2
      (%i2) errcatch(x:0,1/x);

      Division by 0
      (%o2)                          []

Funktion: error (expr_1, …, expr_n)
Systemvariable: error

  Wertet die Ausdrücke expr_1, …, expr_n aus, gibt diese auf der Konsole aus und generiert einen Fehler, der zur obersten Ebene von Maxima führt oder zu dem nächsten `errcatch`.

  Der Systemvariablen `error` wird eine Liste zugewiesen, die eine Beschreibung des Fehlers enthält. Das erste Element der Liste ist eine Zeichenkette und die weiteren Elemente enthalten die Argumente die keine Zeichenkette sind.

  `errormsg()` formatiert und gibt die Fehlermeldung in `error` aus. Damit wird die letzte Fehlermeldung erneut ausgegeben.

  Beispiel:

      (%i1) f(x):= if x=0 then
                      error("Division durch", x, "ist nicht gestattet.")
                   else 1/x$
      (%i2) f(0);

      Division durch 0 ist nicht gestattet.
      #0: f(x=0)
       -- an error. To debug this try: debugmode(true);
      (%i3) errormsg();

      Division durch 0 ist nicht gestattet.
      (%o3)                         done
      (%i4) error;
      (%o4)      [Division durch ~M ist nicht gestattet., 0]

Optionsvariable: error_size

  Standardwert: 10

  `error_size` kontrolliert die Ausgabe eines Ausdrucks der zu einem Fehler geführt hat. Ist der Ausdruck größer als `error_size` wird der Ausdruck bei der Ausgabe einer Fehlermeldung durch ein Symbol ersetzt und dem Symbol wird der Ausdruck zugewiesen. Die Symbole werden aus der Liste `error_syms` ausgewählt.

  Ist der Ausdruck kleiner als `error_size` wird dieser mit der Fehlermeldung ausgegeben.

  Siehe auch `error` und `error_syms`.

  Beispiel:

  Die Größe des Ausdrucks `U` ist 24.

      (%i1) U: (C^D^E + B + A)/(cos(X-1) + 1)$

      (%i2) error_size: 20$

      (%i3) error ("Example expression is", U);

      Example expression is errexp1
       -- an error.  Quitting.  To debug this try debugmode(true);
      (%i4) errexp1;
                                  E
                                 D
                                C   + B + A
      (%o4)                    --------------
                               cos(X - 1) + 1
      (%i5) error_size: 30$

      (%i6) error ("Example expression is", U);

                               E
                              D
                             C   + B + A
      Example expression is --------------
                            cos(X - 1) + 1
       -- an error.  Quitting.  To debug this try debugmode(true);

Optionsvariable: error_syms

  Standardwert: `[errexp1, errexp2, errexp3]`

  In Fehlermeldungen werden Ausdrücke, die größer als `error_size` sind, durch Symbole ersetzt, denen der Ausdruck zugewiesen wird. Die Symbole werden nacheinander der Liste `error_syms` entnommen.

  Sind keine Symbole mehr vorhanden, werden automatisch neue Symbole mit `concat('errexp, n)` gebildet.

  Siehe auch `error` und `error_size`.

Funktion: errormsg ()

  Gibt die letzte Fehlermeldung erneut aus. Die Fehlermeldung ist in der Systemvariablen `errormsg` enthalten. Die Funktion `errormsg` formatiert diese und gibt sie aus.

Optionsvariable: errormsg

  Standardwert: `true`

  Hat die Optionsvariable `errormsg` den `false` wird die Ausgabe von Fehlermeldungen unterdrückt.

  Der Optionsvariablen `errormsg` kann in einem Block kein lokaler Wert zugewiesen werden. Der globale Wert von `errormsg` ist stets präsent.

  Beispiele:

      (%i1) errormsg;
      (%o1)                                true
      (%i2) sin(a,b);
      Wrong number of arguments to sin
       -- an error. To debug this try: debugmode(true);
      (%i3) errormsg:false;
      (%o3)                                false
      (%i4) sin(a,b);

       -- an error. To debug this try: debugmode(true);

  Der Optionsvariablen `errormsg` kann in einem Block kein lokaler Wert zugewiesen werden.

      (%i1) f(bool):=block([errormsg:bool],
                           print ("value of errormsg is",errormsg))$
      (%i2) errormsg:true;
      (%o2)                                true
      (%i3) f(false);
      value of errormsg is true
      (%o3)                                true
      (%i4) errormsg:false;
      (%o4)                                false
      (%i5) f(true);
      value of errormsg is false
      (%o5)                                false

Spezieller Operator: for

  Anweisung für Interationen. Siehe die `do`-Anweisung für eine Beschreibung der Iterationsmöglichkeiten von Maxima.

Funktion: go (tag)

  Erlaubt einen Sprung innerhalb eines Blocks zu einer Marke mit dem Namen `tag`. Um eine Anweisung mit einer Sprungmarke zu versehen, wird der Anweisung die Marke vorangestellt. Ein Beispiel ist:

      block ([x], x:1, loop, x+1, ..., go(loop), ...)

  Das Argument der Funktion `go` muss der Name einer Marke sein, die in demselben Block erscheint. Es ist nicht möglich in einen anderen Block zu springen.

Spezieller Operator: if

  Ist die bedingte Anweisung. Verschiedene Formen einer bedingten Anweisung sind möglich.

  `if cond_1 then expr_1 else expr_0` wertet zu expr_1 aus, wenn die Bedingung cond_1 den Wert `true` hat. Ansonsten wertet der Ausdruck zu expr_0 aus.

  Die zusammengesetzte bedingte Anweisung `if cond_1 then expr_1 elseif cond_2 then expr_2 elseif ... else expr_0` wertet zu expr_k aus, wenn die Bedingung cond_k den Wert `true` hat und alle vorhergehenden Bedingungen den Wert `false` haben. Trifft keine der Bedingungen zu, wertet der Ausdruck zu expr_0 aus.

  Fehlt die Anweisung `else`, wird diese zu `else false` angenommen. `if cond_1 then expr_1` ist daher äquivalent zu `if cond_1 then expr_1 else false` und `if cond_1 then expr_1 elseif ... elseif cond_n then expr_n` ist äquivalent zu `if cond_1 then expr_1 elseif ... elseif cond_n then expr_n else false`.

  Die Anweisungen expr_0, …, expr_n können beliebige Maxima-Ausdrücke einschließlich weiterer `if`-Anweisungen sein. Die Anweisungen werden nicht vereinfacht oder ausgewertet, solange die dazugehörende Bedingung nicht das Ergebnis `true` hat.

  Die Bedingungen cond_1, …, cond_n sind Ausdrücke, die zu `true` oder `false` ausgewertet werden können. Kann eine Bedingung nicht zu `true` oder `false` ausgewertet werden, hängt die Reaktion von der Optionsvariablen `prederror` ab. Hat `prederror` den Wert `true`, dann meldet Maxima einen Fehler, wenn eine Bedingung nicht zu `true` oder `false` ausgewertet werden kann. Ansonsten werden Bedingungen akzeptiert, die nicht zu `true` oder `false` ausgewertet werden können und das Ergebnis ist ein bedingter Ausdruck.

  Die Bedingungen können die folgenden Operatoren enthalten:

      Operation              Symbol      Typ

      less than              <           relational infix
      less than              <=
        or equal to                      relational infix
      equality (syntactic)   =           relational infix
      negation of =          #           relational infix
      equality (value)       equal       relational function
      negation of equal      notequal    relational function
      greater than           >=
        or equal to                      relational infix
      greater than           >           relational infix
      and                    and         logical infix
      or                     or          logical infix
      not                    not         logical prefix

Funktion: local (v_1, …, v_n)

  Speichert alle Eigenschaften der Symbole v_1, …, v_n, entfernt die Eigenschaften und stellt die abgespeicherten Eigenschaften nach dem Austritt aus einem Block oder einem zusammengesetzten Ausdruck in dem `local` auftritt wieder her.

  Einige Deklarationen sind als Eigenschaft eines Symbols implementiert. Dazu gehören Deklarationen mit `:=`, `array`, `dependencies`, `atvalue`, `matchdeclare`, `atomgrad`, `constant`, `nonscalar` oder `assume`. Der Effekt von `local` ist, dass solche Deklarationen nur lokal in dem Block wirksam sind.

  `local` kann nur in `block`-Anweisungen oder in einer Funktionsdefinition oder in einem Lambda-Ausdruck verwendet werden. Weiterhin darf `local` jeweils nur einmal auftreten.

  `local` wertet die Argumente aus. `local` hat die Rückgabe `done`.

  Beispiel:

  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

Funktion: return (value)

  Die `return`-Anweisung wird in einem Block verwendet, um den Block mit dem Ergebnis value zu verlassen. Siehe `block` für mehr Informationen.

Funktion: throw (expr)

  Wertet den Ausdruck expr aus und generiert eine Ausnahme mit dem Ergebnis der Auswertung, die von der letzten `catch`-Anweisung behandelt wird.

Spezieller Operator: while
Spezieller Operator: unless

  Siehe den Operator `do`.

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

This document was generated by Viktor T. Toth on Oktober, 3 2017 using texi2html 1.76.