[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
5.1 Einführung in die lineare Anzeige | ||
5.2 Externe Darstellung von Ausdrücken | ||
5.3 Hilfsfunktionen der linearen Anzeige | ||
5.4 Formatierung von Ausdrücken für die Anzeige |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
grind strsym lbp rbp mparen -1 -1 mprogn msize-matchfix ((#\( ) #\)) mlist msize-matchfix ((#\[ ) #\]) mlabel msize-mlabel mtext msize-mtext mqapply msize-mqapply mquote msize-prefix msetq msize-infix (#\:) 180 20 mset msize-infix (#\: #\:) 180 20 mdefine msize-mdef (#\: #\=) 180 20 mdefmacro msize-mdef (#\: #\: #\=) 180 20 mplus msize-mplus 100 100 mminus msize-prefix (#\-) 100 100 mtimes msize-mtimes 120 120 mnctimes msize-nary 130 129 mexpt msize-mexpt 140 139 mncexpt msize-infix (#\^ #\^) 140 139 mquotient msize-infix (#\/) 120 120 rat msize-infix (#\/) 120 120 mfactorial msize-postfix 160 mequal msize-infix (#\=) 80 80 mnotequal msize-infix 80 80 mgreaterp msize-infix 80 80 mgeqp msize-infix 80 80 mlessp msize-infix 80 80 mleqp msize-infix 80 80 mnot msize-prefix 70 mand msize-nary 65 65 mor msize-nary 60 60 mcond msize-mcond 45 45 mdo msize-mdo 25 25 mdoin msize-mdoin 30 30
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
kMaxima unterscheidet Ausdrücke in einer internen Darstellung von Ausdrücken
in einer externen Darstellung, wie sie für die Ausgabe von Ausdrücke auf der
Anzeige verwendet wird. In der externen Darstellung wird zum Beispiel die
Wurzelfunktion als (%sqrt) $x)
dargestellt. Die interne Darstellung
ist dagegen ((mexpt) $x ((rat) 1 2))
. Die Formatierung in die externe
Darstellung wird von der Funktion nformat
geleistet. nformat
führt spezielle Formatierungen für negative Zahlen, Summen, Produkte und
Exponentiationen aus. Verschiedene Optionsvariablen kontrollieren die Art der
Formatierung.
Standardwert: nil
Die Optionsvariable $powerdispflag
kontrolliert die Formatierung von
mplus
-Ausdrücken, die von der Funktion nformat-mplus
ausgeführt wird. Die Terme einer Summe liegen intern in einer alphabetisch
aufsteigenden Ordnung vor. Für die externe Darstellung wird die Ordnung
umgekehrt. Ein interner Ausdruck ((mplus) $a $b $c
wird daher als
c + b + a
ausgegeben. Hat die Optionsvariable $powerdispflag
den
Wert true
, dann wird die Reihenfolge der Terme nicht umgekehrt.
Siehe auch die Funktionen nformat
und nformat-all
für die
Formatierung von kMaxima-Ausdrücken sowie die Optionsvariable
$negsumdispflag
,
die die Formatierung von Differenzen für die
externe Darstellung kontrolliert.
Bemerkung:
Im Original Maxima hat diese Optionsvariable den Namen $powerdisp
. Um
eine konsistente Bezeichnung der Optionsvariablen für die Formatierung zu
erhalten, ist die Variable zu $powerdispflag
umbenannt.
Standardwert: t
Die Optionsvariable $negsumdispflag
kontrolliert die Darstellung der
Differenz von zwei Termen durch die Funktion nformat-mplus
.
Hat die
Optionsvariable $negsumdispflag
den Wert t
, dann wird eine
Differenz immer als a - b
angezeigt und nicht, wie es die Ordnung der
Terme einer Summe vorsehen würde, als -b + a
.
Siehe auch die Funktionen nformat
und nformat-all
für die
Formatierung von kMaxima-Ausdrücken sowie die Optionsvariable
$powerdispflag
,
die die Reihenfolge der Terme einer Summe
in der externen Darstellung kontrolliert.
Standardwert: nil
Mit der Optionsvariablen $ratdispflag
wird die Formatierung von
rationalen Zahlen durch die Funktion nformat-mtimes
kontrolliert, die in
einem Produkt auftreten. Hat $ratdispflag
den Wert t
, werden
rationale Zahlen vor das Produkt gezogen.
Für ein Beispiel siehe die Funktion nformat-mtimes
.
Bemerkung:
Im Original Maxima hat diese Optionsvariable den Namen $pfeformat
. Um
eine konsistente Bezeichnung der Optionsvariablen für die Formatierung zu
erhalten, ist die Variable zu $ratdispflag
umbenannt.
Standardwert: nil
Die Optionsvariable $%edispflag
kontrolliert die Formatierung der
Exponentialfunktion durch die Funktion nformat-mexpt
.
Hat
%edispflag
den Wert t
, wird die Exponentialfunktion mit einem
negativen Exponenten als Quotient formatiert.
Standardwert: t
Die Optionsvariable $exptdispflag
kontrolliert die Formatierung der
Exponentiation durch die Funktion nformat-mexpt
.
Hat
$exptdispflag
den Wert t
, wird die Exponentiation mit einem
negativen Exponenten als Quotient formatiert.
Standardwert: t
Die Optionsvariable $sqrtdispflag
kontrolliert die Formatierung der
Wurzel durch die Funktion nformat-mexpt
.
Hat $sqrtdispflag
den
Wert t
, dann wird ein Ausdruck mit der Wurzelfunktion wie zum Beispiel
((mexpt) $a ((rat) 1 2))
für die externe Darstellung als
((%sqrt) $a)
formatiert.
Das Argument form
ist ein kMaxima-Ausdruck, dessen Hauptoperator mit
seinen Argumenten in einer internen Darstellung vorliegt. Die Rückgabe ist
ein ein kMaxima-Ausdruck, wobei der Hauptoperator und seine Argumente in eine
externe Darstellung für die Anzeige formatiert sind. Die Formatierung wird
für nur dann ausgeführt, wenn der Hauptoperator ein Attribut, insbesondere
den simp
-Schalter aufweist. Bei der Formatierung in die externe
Darstellung werden bis auf wenige Ausnahmen die Attribute von einem Operator
entfernt.
Die Formatierung von negativen Zahlen wird direkt in der Funktion
nformat
vorgenommen. Für die Formatierung
von Summen, Produkten und der Exponentiation werden die Funktionen
nformat-mplus
,
nformat-mtimes
und nformat-mexpt
aufgerufen.
Die Formatierung in die externe Darstellung wird für eine Summe von den
Optionsvariablen $powerdispflag
und $negsumdispflag
,
für ein Produkt von der Optionsvariablen $ratdispflag
und für die
Exponentiation von den Optionsvariablen $%edispflag
,
$exptdispflag
und $sqrtdispflag
kontrolliert. Siehe dazu die
jeweiligen oben genannten Funktionen sowie die Dokumentation der
Optionsvariablen.
Die Funktion nformat
formatiert nur den Hauptoperator und seine
Argumente. Für die Formatierung aller Teilausdrücke eines kMaxima-Ausdrucks
siehe die Funktion nformat-all
,
die die Funktion nformat
rekursiv auf die Teilausdrücke eines Ausdrucks anwendet.
Beispiele:
* (nformat '((mtimes simp) -2 $x)) ((MMINUS) ((MTIMES) 2 $X)) * (nformat '((mexpt simp) $x ((rat) 1 2))) ((%SQRT) $X) * (nformat '((mexpt) $x ((rat) 1 2))) ((MEXPT) $X ((RAT) 1 2)) * (nformat '((mexpt simp) ((mtimes simp) -2 $x) ((rat simp) 1 2))) ((%SQRT) ((MTIMES SIMP) -2 $X)) * (nformat-all '((mexpt simp) ((mtimes simp) -2 $x) ((rat simp) 1 2))) ((%SQRT) ((MMINUS) ((MTIMES) 2 $X)))
Quelltext:
(defun nformat (form) (cond ((atom form) (cond ((and (numberp form) (minusp form)) (list '(mminus) (- form))) (t form))) ((atom (car form)) form) ((eq 'rat (caar form)) (cond ((minusp (cadr form)) (list '(mminus) (list '(rat) (- (cadr form)) (caddr form)))) (t (cons '(rat) (cdr form))))) ((null (cdar form)) form) ((eq 'mplus (caar form)) (nformat-mplus form)) ((eq 'mtimes (caar form)) (nformat-mtimes form)) ((eq 'mexpt (caar form)) (nformat-mexpt form)) (t form)))
Bemerkungen:
Im Unterschied zum Original Maxima werden die booleschen Konstanten t
und nil
nicht von nformat
formatiert. Die Formatierung
zu den Symbolen $true
und $false
wird in den Funktionen
msize-atom
für die lineare Anzeige und dimension-atom
für die
2D-Anzeige vorgenommen. Auf diese Weise wird die Einführung einer globalen
Variablen vermieden, die gebraucht wird, um diese Formatierung auszuschalten.
Die Funktion ist gegenüber dem Original vereinfacht. Nicht enthalten ist
die Formatierung von mrat-
, mpois-
und
bigfloat
-Ausdrücken, deren Implementation in kMaxima noch nicht
ausgeführt ist.
Weiterhin ist die Formatierung von Atomen in Abhängigkeit von der globalen
Variablen displayp
nicht in kMaxima implementiert. Die mit dieser
Variablen im Zusammenhang stehende Funktionalität ist nicht vollständig im
Original Maxima implementiert und nicht dokumentiert.
Wendet die Funktion nformat
zunächst auf den Ausdruck form und
dann rekursiv auf die Argumente und Teilausdrücke an. Im Unterschied zu der
Funktion nformat
wird der Ausdruck form vollständig formatiert.
Die Rückgabe ist ein Ausdruck in der externen Darstellung.
Quelltext:
(defun nformat-all (form) (setq form (nformat form)) (if (atom form) form (cons (delete 'simp (copy-list (car form)) :count 1 :test #'eq) (mapcar #'nformat-all (cdr form)))))
Bemerkung:
Gegenüber dem Original in Maxima ist der Test auf einen
bigfloat
-Ausdruck entfernt. Da nformat
im Unterschied zum
Original die booleschen Variablen t
und nil
nicht formatiert,
kann der Test auf einen mdo-
oder mdoin
-Ausdruck entfallen,
wodurch die hier gezeigte Funktion einfacher wird.
Die Funktion nformat-mplus
formatiert eine Summe in eine externe
Darstellung.
Die Formatierung wird von den Optionsvariablen $powerdispflag
und
$negsumdispflag
kontrolliert. Die Terme einer Summe liegen intern in
einer alphabetisch aufsteigenden Ordnung vor. Für die externe Darstellung
wird die Ordnung umgekehrt. Ein interner Ausdruck ((mplus) $a $b $c
wird daher als c + b + a
ausgegeben. Hat die Optionsvariable
$powerdispflag
den Wert true
, dann wird die Reihenfolge der Terme
nicht umgekehrt.
Die Optionsvariable $negsumdispflag
kontrolliert die Darstellung der
Differenz von zwei Termen. Hat die Optionsvariable $negsumdispflag
den
Wert true
, dann wird eine Differenz immer als a - b
angezeigt
und nicht, wie es die Ordnung der Terme einer Summe vorsehen würde, als
-b + a
. Dies trifft jedoch nicht zu, wenn die Optionsvariable
$powerdispflag
ebenfalls den Wert true
hat. In diesem Fall werden
die Terme immer in einer aufsteigenden Ordnung angezeigt.
Die Funktion wird von der Funktion nformat
aufgerufen, um einen
mplus
-Ausdruck in die externe Darstellung zu formatieren. Siehe auch
die Funktion nformat-all
,
, um einen Ausdruck einschließlich
seiner Teilausdrücke in die externe Darstellung zu formatieren.
Beispiele:
Die Ordnung der Termine wird für die Ausgabe umgekehrt.
* (nformat-mplus '((mplus simp) $a $b $c)) ((MPLUS) $C $B $A)
Die Optionsvariable $powerdisp
kontrolliert die Ordnung der Terme.
* (let (($powerdisp t)) (nformat-mplus '((mplus simp) $a $b $c))) ((MPLUS) $A $B $C) * (let (($powerdisp nil)) (nformat-mplus '((mplus simp) $a $b $c))) ((MPLUS) $C $B $A)
Mit der Optionsvariablen $negsumdispflag
wird die Ausgabe von
Differenzen a - b
kontrolliert.
* (nformat-mplus '((mplus simp) $a ((mminus simp) $b))) ((MPLUS) $A ((MMINUS) $B)) * (let (($negsumdispflag nil)) (nformat-mplus '((mplus simp) $a ((mminus simp) $b)))) ((MPLUS) ((MMINUS) $B) $A)
Quelltext:
(defun nformat-mplus (form &aux args) (setq args (mapcar #'nformat (cdr form))) (cons '(mplus) (cond ($powerdispflag args) ((and $negsumdispflag (null (cdddr form))) (if (and (not (mminusp (car args))) (mminusp (cadr args))) args (nreverse args))) (t (nreverse args)))))
Bemerkung:
Im Original Maxima hat diese Funktion den Namen form-mplus
. Die Funktion
ist umbenannt, um eine einheitliche Bezeichnung der Funktionen für die
Formatierung in eine externe Darstellung zu erhalten. Weiterhin ist die
Funktion gegenüber dem Original stark vereinfacht. So werden Ausdrücke
mit den Attributen trunc
, cf
oder oder ratsimp
nicht
besonders behandelt.
Das Argument form ist ein mtimes
-Ausdruck, der in die externe
Darstellung formatiert wird.
Im Unterschied zur Addition wird bei Multiplikation die Ordnung der Terme nicht umgekehrt. Die Faktoren werden gegebenenfalls so formatiert, dass sie über einem gemeinsamen Nenner dargestellt werden. Weiterhin wird beim mehrfachen Auftreten von negativen Vorzeichen, das gemeinsame Vorzeichen des Produkts ermittelt.
Mit der Optionsvariablen $ratdispflag
wird die Formatierung von
rationalen Zahlen kontrolliert, die in einem Produkt auftreten. Hat
$ratdispflag
den Wert t
, werden rationale Zahlen vor das
Produkt gezogen.
Die Funktion wird von der Funktion nformat
aufgerufen, um einen
mtimes
-Ausdruck in die externe Darstellung zu formatieren. Siehe auch
die Funktion nformat-all
,
, um einen Ausdruck einschließlich
seiner Teilausdrücke in die externe Darstellung zu formatieren.
Beispiele:
Die Reihenfolge der Faktoren wird nicht umgekehrt.
* (nformat-mtimes '((mtimes simp) $a $b $c)) ((MTIMES) $A $B $C)
Mehrfache negative Vorzeichen werden zusammengefasst.
* (nformat-mtimes '((mtimes simp) ((mminus simp) $a) $b $c)) ((MMINUS) ((MTIMES) $A $B $C)) * (nformat-mtimes '((mtimes simp) ((mminus simp) $a) ((mminus simp) $b) $c)) ((MTIMES) $A $B $C)
Die Faktoren werden über einen gemeinsamen Nenner dargestellt.
* (nformat-mtimes '((mtimes simp) $a ((mquotient) 1 $b) $c)) ((MQUOTIENT) ((MTIMES) $A $C) $B)
Hat die Optionsvariable $ratdispflag
den Wert t
, wird eine
rationale Zahl vor die Faktoren gezogen.
* (nformat-mtimes '((mtimes simp) ((rat simp) 1 3) $a ((mquotient) 1 $b) $c)) ((MQUOTIENT) ((MTIMES) $A $C) ((MTIMES) 3 $B)) * (setq $ratdispflag t) T * (nformat-mtimes '((mtimes simp) ((rat simp) 1 3) $a ((mquotient) 1 $b) $c)) ((MQUOTIENT) ((MTIMES) ((RAT) 1 3) $A $C) $B)
Quelltext:
(defun nformat-mtimes (form) (cond ((null (cdr form)) '((mtimes))) ((equal -1 (cadr form)) (list '(mminus) (nformat-mtimes (cdr form)))) (t (prog (num den minus flag) (do ((l (cdr form) (cdr l)) (fact)) ((null l)) (setq fact (nformat (car l))) (cond ((atom fact) (setq num (cons fact num))) ((eq 'mminus (caar fact)) (setq minus (not minus) l (append fact (cdr l)))) ((or (eq 'mquotient (caar fact)) (and (not $ratdispflag) (eq 'rat (caar fact)))) (cond ((not (equal 1 (cadr fact))) (setq num (cons (cadr fact) num)))) (setq den (cons (caddr fact) den))) (t (setq num (cons fact num))))) (setq num (cond ((null num) 1) ((null (cdr num)) (car num)) (t (cons '(mtimes) (nreverse num)))) den (cond ((null den) (setq flag t) nil) ((null (cdr den)) (car den)) (t (cons '(mtimes) (nreverse den))))) (if (not flag) (setq num (list '(mquotient) num den))) (return (if minus (list '(mminus) num) num))))))
Bemerkung:
Im Original Maxima hat diese Funktion den Namen form-mtimes
. Die
Funktion ist umbenannt, um eine einheitliche Bezeichnung der Funktionen für
die Formatierung in eine externe Darstellung zu erhalten.
Das Argument form ist ein mexpt
-Ausdruck. Die Rückgabe ist
ein mexpt
-Ausdruck in einer externen Formatierung für die Anzeige. Es
wird nur der Hauptoperator und seine Argumente formatiert. Bei der Formatierung
wird das Attribut 'simp
vom mexpt
-Operator entfernt. Das Ergebnis
kann die Operatoren mquotient
für einen Bruch oder den Operator
%sqrt
für die Wurzelfunktion enthalten. Die Operatoren werden ohne das
Attribut 'simp
in den Ausdruck eingefügt.
Die Formatierung von mexpt
-Ausdrücken wird von den
Optionsvariablen $sqrtdispflag
,
$%edispflag
und
$exptdispflag
kontrolliert. Hat die Variable $sqrtdispflag
den
Wert t
, dann wird ein Ausdruck mit der Wurzelfunktion wie zum Beispiel
((mexpt) $a ((rat) 1 2))
für die externe Darstellung als
((%sqrt) $a)
formatiert. Die Optionsvariable %edispflag
kontrolliert die Formatierung der Exponentialfunktion. Hat %edispflag
den Wert t
, wird die Exponentialfunktion mit einem negativen Exponenten
als Quotient formatiert. Entsprechend kontrolliert die Optionsvariable
$exptdispflag
die Formatierung der Exponentiation mit einer Basis die
verschieden von %e
ist.
Die Funktion wird von der Funktion nformat
aufgerufen, wenn ein
mexpt
-Ausdruck für die externe Darstellung zu formatieren ist.
Siehe auch die Funktion nformat-all
,
um einen Ausdruck
einschließlich aller Teilausdrücke zu formatieren.
Beispiele:
* (let (($sqrtdispflag nil)) (nformat-mexpt '((mexpt simp) $a ((rat simp) 1 2)))) ((MEXPT) $A ((RAT SIMP) 1 2)) * (let (($sqrtdispflag t)) (nformat-mexpt '((mexpt simp) $a ((rat simp) 1 2)))) ((%SQRT) $A) * (let (($%edispflag nil)) (nformat-mexpt '((mexpt simp) $%e -2))) ((MEXPT) $%E -2) * (let (($%edispflag t)) (nformat-mexpt '((mexpt simp) $%e -2))) ((MQUOTIENT) 1 ((MEXPT) $%E 2)) * (let (($exptdispflag nil)) (nformat-mexpt '((mexpt simp) $a -2))) ((MEXPT) $A -2) * (let (($exptdispflag t)) (nformat-mexpt '((mexpt simp) $a -2))) ((MQUOTIENT) 1 ((MEXPT) $A 2))
Quelltext:
(defun nformat-mexpt (form &aux expr) (cond ((and $sqrtdispflag (alike1 '((rat) 1 2) (caddr form))) (list '(%sqrt) (cadr form))) ((and $sqrtdispflag (alike1 '((rat) -1 2) (caddr form))) (list '(mquotient) 1 (list '(%sqrt) (cadr form)))) ((and (or (and $%edispflag (eq '$%e (cadr form))) (and $exptdispflag (not (eq '$%e (cadr form))))) (not (atom (setq expr (nformat (caddr form))))) (eq 'mminus (caar expr))) (list '(mquotient) 1 (if (equal 1 (cadr expr)) (cadr form) (list '(mexpt) (cadr form) (cadr expr))))) (t (cons '(mexpt) (cdr form)))))
Bemerkung:
Im Original Maxima hat diese Funktion den Namen form-mexpt
. Die
Funktion ist umbenannt, um eine einheitliche Bezeichnung der Funktionen für
die Formatierung in eine externe Darstellung zu erhalten.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Die Funktion strsym
ist eine kleine Hilfsfunktion, um das Zeichen für
die Anzeige eines Operators von der Eigenschaftsliste zu lesen. Die Funktionen
für die lineare Anzeige legen die Zeichen zum Symbol 'strsym
auf der
Eigenschaftsliste ab. Weiterhin prüft die Funktion, ob ein Zeichen zum Symbol
'dissym
auf der Eigenschaftsliste abgelegt ist. Die Routinen für die
zweidimensionale Anzeige nutzen dieses Symbol.
Beispiele:
Im folgenden werden einige Beispiele für die Operatoren mequal
,
rat
und msetq
gezeigt.
* (strsym 'mequal) (#\=) * (strsym 'rat) (#\/) * (strsym 'msetq) (#\:) * (strsym 'mset) (#\: #\:)
Quelltext:
(defun strsym (x) (or (getprop x 'strsym) (getprop x 'dissym)))
Standardwert: nil
Hat $stringdispflag
den Wert t
wird eine Zeichenkette von der
Funktion makestring
in Anführungszeichen gesetzt. Die Funktion
makestring1
bindet $stringdispflag
an den Wert nil
.
Bemerkung:
Im Original Maxima hat diese Variable den Namen $stringdisp
.
Hat die Optionsvariable $lispdispflag
den Wert t
, erhalten
Lisp-Symbole beim Aufruf der Funktion makestring
ein führendes
Fragezeichen ?
. Die Funktion makestring1
bindet
$lispdispflag
an den Wert nil
.
Bemerkung:
Im Original Maxima hat diese Variable den Namen $lispdisp
.
Die Funktion makestring
wandelt Zahlen, Zeichenketten, Symbole und
Ausdrücke in eine Liste aus Zeichen um. Ist das Argument ein Symbol, wird ein
eventuell vorhandener Reverse-Alias-Name beachtet. Für Operatoren wird
der Name des Operators als eine Zeichenkette dargestellt. Die Zeichen %
und $
, die einen Verb- und Substantiv-Bezeichner vorangestellt sind,
werden entfernt.
makestring
wird von den Optionsvariablen $stringdispflag
und
$lispdispflag
kontrolliert. Hat $stringdispflag
den Wert t
wird eine Zeichenkette in Anführungszeichen gesetzt. Hat $lispdispflag
den Wert t
, erhalten Lisp-Symbole ein führendes Fragezeichen ?
.
Siehe auch die Funktion makestring1
.
Diese Funktion bindet die
Optionsvariablen $stringdispflag
und $lispdispflag
an den Wert
nil
.
Beispiele:
* (makestring 'mplus) (#\+) * (makestring 'mequal) (#\=) * (makestring '100) (#\1 #\0 #\0) * (makestring "string") (#\s #\t #\r #\i #\n #\g) * (makestring '$symbol) (#\s #\y #\m #\b #\o #\l)
Zum Symbol $sqrt
wird der Alias-Name $mysqrt
mit der Funktion
alias
definiert. Die Funktion makestring
gibt in diesem Fall
für das Symbol $sqrt
den Alias-Namen als eine Liste der Zeichen
zurück.
* (alias '$mysqrt '$sqrt) $SQRT * (makestring '$sqrt) (#\m #\y #\s #\q #\r #\t)
Quelltext:
(defun makestring (x) (declare (special $aliases)) (let (y) (cond ((numberp x) (exploden x)) ((stringp x) (setq y (coerce x 'list)) (if $stringdispflag (cons #\" (nconc y (list #\"))) y)) ((not (symbolp x)) (exploden x)) ((and (setq y (getprop x 'reversealias)) (not (and (member x $aliases :test #'eq) (getprop x 'noun)))) (exploden (stripdollar y))) ((not (eq (getop x) x)) (makestring (getop x))) ((null (setq y (exploden x)))) ((or (char= #\$ (car y)) (char= #\% (car y))) (cdr y)) ($lispdispflag (cons #\? y)) (t y))))
Entspricht der Funktion makestring
mit dem Unterschied, dass die
Optionsvariablen $stringdispflag
und $lispdispflag
an den Wert
nil
gebunden werden.
Quelltext:
(defun makestring1 (x) (let (($stringdispflag nil) ($lispdispflag nil)) (makestring x)))
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Standardwert: 79
Die globalen Variablen *linel*
und $linel
enthalten die Anzahl
der Zeichen einer Ausgabezeile für die Formatierung der Ausgabe durch die
Funktion mprint
.
Die Variable $linel
ist eine Optionsvariable,
die vom Nutzer gesetzt werden kann. Die Variable hat die Eigenschaft
shadowvar
. Immer wenn $linel
vom Nutzer einen neuen Wert
erhält, wird auch die globale Variable *linel*
auf den Wert gesetzt.
Quelltext:
(defvar *linel* 79) (defmvar $linel 79) (defprop $linel shadowset assign) (defprop $linel *linel* shadowvar)
Die Funktion mgrind
gibt einen kMaxima-Ausdruck auf dem Stream out
aus. Dazu wird der Ausdruck mit der Funktion msize
für die Ausgabe
formatiert und mit der Funktion mprint
ausgegeben. Die zu den Funktionen
lokale Zustandsvariable chrps
enthält die aktuelle Position des
Cursors. Die Anzahl der Zeichen einer Ausgabezeile ist in der globalen
Variablen *linel*
enthalten.
Quelltext:
(let ((chrps 0)) (defun mgrind (form out) (setq chrps 0) (mprint (msize form nil nil 'mparen 'mparen) out)) (defun mprint (form out) (labels ((mtyotbsp (n out) (declare (fixnum n)) (incf chrps n) (dotimes (i n) (write-char #\space out))) (charpos () (- *linel* chrps))) (cond ((characterp form) (incf chrps) (write-char form out)) ((< (car form) (charpos)) (mapc #'(lambda (l) (mprint l out)) (cdr form))) (t (prog ((i chrps)) (mprint (cadr form) out) (cond ((null (cddr form)) (return nil)) ((and (or (atom (cadr form)) (< (caadr form) (charpos))) (or (> (charpos) (truncate *linel* 2)) (atom (caddr form)) (< (caaddr form) (charpos)))) (setq i chrps) (mprint (caddr form) out)) (t (incf i) (setq chrps 0) (terpri out) (mtyotbsp i out) (mprint (caddr form) out))) (do ((l (cdddr form) (cdr l))) ((null l)) (cond ((or (atom (car l)) (< (caar l) (charpos))) nil) (t (setq chrps 0) (terpri out) (mtyotbsp i out))) (mprint (car l) out))))))))
Die Funktion mstring
arbeitet ähnlich wie die Funktion mgrind
mit dem Unterschied, dass die Funktion mstring
eine Zeichenkette als
Ergebnis hat.
Quelltext:
(defun mstring (x) (labels ((string1 (x l) (cond ((atom x) (cons x l)) (t (do ((x (cdr x) (cdr x))) ((null x) l) (setq l (string1 (car x) l))))))) (nreverse (string1 (msize x nil nil 'mparen 'mparen) nil))))
Die Funktion msize
ist die Hauptfunktion für die Formatierung eines
kMaxima-Ausdrucks für die lineare Anzeige. Das Argument x enthält
den Ausdruck, der formatiert werden soll. Die Argumente l und r
enthalten den links bzw. rechts vom Ausdruck x formatierten Ausdruck.
Die globalen Variablen *lop* und *rop* enthalten den aktuellen
linksseitigen bzw. rechtsseitigen Operator. Für die Formatierung eines
Ausdrucks wird die Funktion msize
rekursiv für jeden Teilausdruck des
Argumentes x aufgerufen. Von den Funktionen mgrind und mstring
wird msize
mit den Werten nil
für die Argumente l und
r sowie mparen
für die Argumente *lop* und *rop*
aufgerufen.
Als erstes wird das Argument x mit der Funktion nformat
für die
externe Darstellung formatiert. Dann werden ...
Quelltext:
(defun msize (x l r *lop* *rop*) (setq x (nformat x)) (cond ((atom x) (msize-atom x l r)) ((and (atom (car x)) (setq x (cons '(mprogn) x)) nil)) ((or (<= (lbp (caar x)) (rbp *lop*)) (> (lbp *rop*) (rbp (caar x)))) (msize-paren x l r)) ((member 'array (cdar x) :test #'eq) (msize-array x l r)) ((getprop (caar x) 'grind) (the (values t) (funcall (get (caar x) 'grind) x l r))) (t (msize-function x l r nil))))
Quelltext:
(defun msize-paren (x l r) (msize x (cons #\( l) (cons #\) r) 'mparen 'mparen))
Quelltext:
(defun msize-atom (x l r) (declare (special $aliases)) (labels ((slash (x) (do ((l (cdr x) (cdr l))) ((null l)) (if (or (digit-char-p (car l)) (alphabetp (car l))) nil (progn (rplacd l (cons (car l) (cdr l))) (rplaca l #\\ ) (setq l (cdr l))))) (if (alphabetp (car x)) x (cons #\\ x)))) (prog (y) (cond ((numberp x) (setq y (exploden x))) ((stringp x) (setq y (coerce x 'list)) (do ((l y (cdr l))) ((null l)) (cond ((member (car l) '(#\" #\\ ) :test #'equal) (rplacd l (cons (car l) (cdr l))) (rplaca l #\\ ) (setq l (cdr l))))) (setq y (cons #\" (nconc y (list #\"))))) ((and (setq y (getprop x 'reversealias)) (not (and (member x $aliases :test #'eq) (getprop x 'noun)))) (setq y (exploden (stripdollar y)))) ((null (setq y (exploden x)))) ((getprop x 'noun) (return (msize-atom (getprop x 'noun) l r))) ((char= #\$ (car y)) (setq y (slash (cdr y)))) (t (setq y (cons #\? (slash y))))) (return (msz y l r)))))
Quelltext:
(defun msz (x l r) (setq x (nreconc l (nconc x r))) (cons (length x) x))
Die Funktion msize-array
formatiert einen Ausdruck wie f[a]
oder
f[a](x)
für die lineare Anzeige. Das Argument x ist der zu
formatierende Ausdruck und die Argumente l und r sind jeweils die
bisher formatierte linke und rechte Seite des Ausdrucks.
Beispiele:
* (msize-array '(($f array simp) $x) nil nil) (4 (2 #\f #\[) (2 #\x #\])) * (msize-array '((mqapply simp) (($F simp array) $a $b) $x) nil nil) (11 (9 (3 #\( #\f #\[) (2 #\a #\,) (4 #\b #\] #\) #\[)) (2 #\x #\]))
Quelltext:
(defun msize-array (x l r &aux f) (declare (special $aliases)) (if (eq (caar x) 'mqapply) (setq f (cadr x) x (cdr x)) (setq f (caar x))) (cond ((and (getprop (caar x) 'verb) (getprop (caar x) 'alias)) (setq l (revappend '(#\' #\' ) l))) ((and (getprop (caar x) 'noun) (not (member (caar x) (cdr $aliases) :test #'eq)) (not (get (caar x) 'reversealias))) (setq l (cons #\' l)))) (setq l (msize f l (list #\[ ) *lop* 'mfunction) r (msize-list (cdr x) nil (cons #\] r))) (cons (+ (car l) (car r)) (cons l (cdr r))))
Quelltext:
(defun msize-function (x l r op) (declare (special $aliases)) (cond ((not (symbolp (caar x)))) ((and (getprop (caar x) 'verb) (getprop (caar x) 'alias)) (setq l (revappend '(#\' #\' ) l))) ((and (getprop (caar x) 'noun) (not (member (caar x) (cdr $aliases) :test #'eq)) (not (getprop (caar x) 'reversealias))) (setq l (cons #\' l)))) (setq l (msize (if op (getop (caar x)) (caar x)) l (list #\( ) 'mparen 'mparen) r (msize-list (cdr x) nil (cons #\) r))) (cons (+ (car l) (car r)) (cons l (cdr r))))
Quelltext:
(defun msize-list (x l r) (if (null x) (msz nil l r) (do ((nl) (w 0)) ((null (cdr x)) (setq nl (cons (msize (car x) l r 'mparen 'mparen) nl)) (cons (+ w (caar nl)) (nreverse nl))) (setq nl (cons (msize (car x) l (list #\, ) 'mparen 'mparen) nl) w (+ w (caar nl)) x (cdr x) l nil))))
Quelltext:
(defun msize-prefix (x l r) (msize (cadr x) (revappend (strsym (caar x)) l) r (caar x) *rop*))
Quelltext:
(defun msize-infix (x l r) (if (not (= (length (cdr x)) 2)) (return-from msize-infix (msize-function x l r t))) (setq l (msize (cadr x) l nil *lop* (caar x)) r (msize (caddr x) (reverse (strsym (caar x))) r (caar x) *rop*)) (list (+ (car l) (car r)) l r))
Quelltext:
(defun msize-postfix (x l r) (msize (cadr x) l (append (strsym (caar x)) r) *lop* (caar x)))
Das Argument x ist ein Ausdruck mit einem Nofix-Operator. Die Argumente l und r sind jeweils die bisher auf der linken und der rechten Seite formatierten Ausdrücke.
msize-nofix
ruft rekursiv die Funktion msize
auf, wobei das
interne Symbol des Nofix-Operators als erstes Argument zur Formatierung
übergeben wird. Die weiteren Argumente sind l und r. Die
nächsten Argumente sind die aktuell links und rechts vorliegenden Operatoren.
Der linksseitige Operator wird zum Nofix-Operator.
Siehe auch die Funktion $nofix
,
um einen Nofix-Operator zu
definieren.
Beispiel:
kMaxima kennt keinen Nofix-Operator. Daher wird zunächst ein Nofix-Operator
new
definiert.
(%i1) nofix(new); (%o1) new (%i2) quit(); 0
Jetzt wird ein Ausdruck mit dem Nofix-Operator new
formatiert.
* (msize-nofix '(($new)) nil nil) (3 #\n #\e #\w)
Quelltext:
(defun msize-nofix (x l r) (msize (caar x) l r (caar x) *rop*))
Quelltext:
(defun msize-matchfix (x l r) (setq l (nreconc l (car (strsym (caar x)))) l (cons (length l) l) r (append (cdr (strsym (caar x))) r) x (msize-list (cdr x) nil r)) (cons (+ (car l) (car x)) (cons l (cdr x)))) (defun msize-nary (x l r) (msznary x l r (strsym (caar x))))
Quelltext:
(defun msznary (x l r strsym) (cond ((null (cddr x)) (msize-function x l r t)) (t (setq l (msize (cadr x) l nil *lop* (caar x))) (do ((ol (cddr x) (cdr ol)) (nl (list l)) (w (car l))) ((null (cdr ol)) (setq r (msize (car ol) (reverse strsym) r (caar x) *rop*)) (cons (+ (car r) w) (nreverse (cons r nl)))) (declare (fixnum w)) (setq nl (cons (msize (car ol) (reverse strsym) nil (caar x) (caar x)) nl) w (+ (caar nl) w))))))
Quelltext:
(defun msize-mlabel (x l r) (declare (special *display-labels-p*)) (cond (*display-labels-p* (setq l (msize (cadr x) (list #\( ) (list #\) #\ ) nil nil) r (msize (caddr x) nil r 'mparen 'mparen)) (cons (+ (car l) (car r)) (cons l (cons r nil)))) (t (msize (caddr x) l r 'mparen 'mparen))))
Quelltext:
(defun msize-mtext (x l r) (setq x (cdr x)) (if (null x) (msz nil l r) (do ((nl) (w 0)) ((null (cdr x)) (setq nl (cons (if (atom (car x)) (msz (makestring (car x)) l r) (msize (car x) l r *lop* *rop*)) nl)) (cons (+ w (caar nl)) (nreverse nl))) (setq nl (cons (if (atom (car x)) (msz (makestring (car x)) l r) (msize (car x) l nil *lop* *rop*)) nl) w (+ w (caar nl)) x (cdr x) l nil))))
Quelltext:
(defun msize-mqapply (x l r) (setq l (msize (cadr x) l (list #\( ) *lop* 'mfunction) r (msize-list (cddr x) nil (cons #\) r))) (cons (+ (car l) (car r)) (cons l (cdr r))))
Quelltext:
(defun msize-mdef (x l r) (setq l (msize (cadr x) l (copy-list (strsym (caar x))) *lop* (caar x)) r (msize (caddr x) nil r (caar x) *rop*)) (cond ((not (atom (cadr l))) (setq x (cons (- (car l) (caadr l)) (cddr l))) (if (and (not (atom (cadr r))) (not (atom (caddr r))) (< (+ (car l) (caadr r) (caaddr r)) *linel*)) (setq x (nconc x (list (cadr r) (caddr r))) r (cons (car r) (cdddr r)))) (cons (+ (car l) (car r)) (cons (cadr l) (cons x (cdr r))))) (t (cons (+ (car l) (car r)) (cons l (ncons r))))))
Quelltext:
(defun msize-mplus (x l r) (cond ((null (cddr x)) (if (null (cdr x)) (msize-function x l r t) (msize (cadr x) (append (list #\+ ) l) r 'mplus *rop*))) (t (setq l (msize (cadr x) l nil *lop* 'mplus) x (cddr x)) (do ((nl (list l)) (w (car l)) (dissym)) ((null (cdr x)) (if (mminusp (car x)) (setq l (cadar x) dissym (list #\- )) (setq l (car x) dissym (list #\+ ))) (setq r (msize l dissym r 'mplus *rop*)) (cons (+ (car r) w) (nreverse (cons r nl)))) (declare (fixnum w)) (if (mminusp (car x)) (setq l (cadar x) dissym (list #\-)) (setq l (car x) dissym (list #\+))) (setq nl (cons (msize l dissym nil 'mplus 'mplus) nl) w (+ (caar nl) w) x (cdr x))))))
Quelltext:
(defun msize-mtimes (x l r) (msznary x l r '(#\* )))
Quelltext:
(defun msize-mexpt (x l r) (setq l (msize (cadr x) l nil *lop* 'mexpt) r (if (mminusp (setq x (nformat (caddr x)))) (msize (cadr x) (reverse '(#\^ #\-)) r 'mexpt *rop*) (msize x (list #\^) r 'mexpt *rop*))) (list (+ (car l) (car r)) l r))
Quelltext:
(defun msize-mcond (x l r) (labels ((strmcond (x) (let ((l (reverse (cdr x)))) (if (and (or (eq (car l) nil) (eq (car l) '$false)) (eq (cadr l) t)) (setq l (reverse (cddr l))) (setq l (reverse l))) (append `($if) (do ((l l (cddr l)) (sym nil '$elseif) (res nil)) ((null (cddr l)) (if (and sym (not (eq t (car l)))) (append res `(,sym ,(car l) $then ,(cadr l))) (if (eq t (car l)) (append res `($else ,(cadr l))) (append res `(,(car l) $then ,(cadr l)))))) (setq res (append res (if sym `(,sym ,(car l)) `(,(car l))) `($then ,(cadr l))))))))) (msznary (cons '(mcond) (strmcond x)) l r '(#\space))))
Bemerkung:
Gegenüber dem Original Maxima ist die Funktion deutlich kompakter. Für die
Formatierung wird die Funktion msznary
aufgerufen. Das hat den Vorteil,
dass die Formatierung insgesamt flexibler ist. Weiterhin ist die Formatierung
nun vergleichbar mit der der Funktionen msize-mdo
und
msize-mdoin
.
Quelltext:
(defun msize-mdo (x l r) (labels ((strmdo (x) (nconc (cond ((second x) `($for ,(second x)))) (cond ((equal 1 (third x)) nil) ((third x) `($from ,(third x)))) (cond ((equal 1 (fourth x)) nil) ((fourth x) `($step ,(fourth x))) ((fifth x) `($next ,(fifth x)))) (cond ((sixth x) `($thru ,(sixth x)))) (cond ((null (seventh x)) nil) ((and (consp (seventh x)) (eq 'mnot (caar (seventh x)))) `($while ,(cadr (seventh x)))) (t `($unless ,(seventh x)))) `($do ,(eighth x))))) (msznary (cons '(mdo) (strmdo x)) l r '(#\space))))
Quelltext:
(defun msize-mdoin (x l r) (labels ((strmdoin (x) (nconc `($for ,(second x) $in ,(third x)) (cond ((null (seventh x)) nil) ((and (consp (seventh x)) (eq 'mnot (caar (seventh x)))) `($while ,(cadr (seventh x)))) (t `($unless ,(seventh x)))) `($do ,(eighth x))))) (msznary (cons '(mdo) (strmdoin x)) l r '(#\space))))
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Dieter Kaiser on Dezember, 13 2011 using texi2html 1.76.