[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
27.1 Lisp und Maxima | ||
27.2 Einführung in die Programmierung | ||
27.3 Funktionen und Variablen der Programmierung |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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:
$foo
, $FOO
und $Foo
jeweils der
Maxima-Bezeichner foo
.
|$FOO|
und |$foo|
die
Maxima-Bezeichner foo
und FOO
.
|$Foo|
der
Maxima-Bezeichner Foo
.
Für die Syntax von Maxima-Bezeichnern siehe auch Bezeichner.
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.
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))
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] | [ ? ] |
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] | [ ? ] |
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
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) )$
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
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
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
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
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) []
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]
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);
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
.
Gibt die letzte Fehlermeldung erneut aus. Die Fehlermeldung ist in der
Systemvariablen errormsg
enthalten. Die Funktion errormsg
formatiert diese und gibt sie aus.
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
Anweisung für Interationen. Siehe die do
-Anweisung für eine
Beschreibung der Iterationsmöglichkeiten von Maxima.
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.
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
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
Die return
-Anweisung wird in einem Block verwendet, um den Block mit dem
Ergebnis value zu verlassen. Siehe block
für mehr Informationen.
Wertet den Ausdruck expr aus und generiert eine Ausnahme mit dem Ergebnis
der Auswertung, die von der letzten catch
-Anweisung behandelt wird.
Siehe den Operator do
.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Crategus on Dezember, 12 2012 using texi2html 1.76.