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

5. Lineare Anzeige


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

5.1 Einführung in die lineare Anzeige

            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] [ ? ]

5.2 Externe Darstellung von Ausdrücken

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.

Optionsvariable: $powerdispflag

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.

Optionsvariable: $negsumdispflag

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.

Optionsvariable: $ratdispflag

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.

Optionsvariable: $%edispflag

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.

Optionsvariable: $exptdispflag

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.

Optionsvariable: $sqrtdispflag

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.

Funktion: nformat form

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.

Funktion: nformat-all form

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.

Funktion: nformat-mplus form

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.

Funktion: nformat-mtimes form

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.

Funktion: nformat-mexpt form

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] [ ? ]

5.3 Hilfsfunktionen der linearen Anzeige

Funktion: strsym x

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

Optionsvariable: $stringdispflag

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.

Optionsvariable: $lispdispflag

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.

Funktion: makestring

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

Funktion: makestring1 x

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] [ ? ]

5.4 Formatierung von Ausdrücken für die Anzeige

Optionsvariable: $linel
Globale Variable: *linel*

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)

Funktion: mgrind form out
Funktion: mprint form out

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

Funktion: mstring x

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

Funktion: msize x l r *lop* *rop*

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

Funktion: msize-paren x l r

Quelltext:

(defun msize-paren (x l r)
  (msize x (cons #\( l) (cons #\) r) 'mparen 'mparen))

Funktion: msize-atom x l r

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

Funktion: msz x l r

Quelltext:

(defun msz (x l r)
  (setq x (nreconc l (nconc x r))) (cons (length x) x))

Funktion: msize-array x l r

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

Funktion: msize-function x l r op

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

Funktion: msize-list x l 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))))

Funktion: msize-prefix x l r

Quelltext:

(defun msize-prefix (x l r)
  (msize (cadr x) (revappend (strsym (caar x)) l) r (caar x) *rop*))

Funktion: msize-infix x l r

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

Funktion: msize-postfix x l r

Quelltext:

(defun msize-postfix (x l r)
  (msize (cadr x) l (append (strsym (caar x)) r) *lop* (caar x)))

Funktion: msize-nofix x l r

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*))

Funktion: msize-matchfix x l r

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

Funktion: msznary x l r strsym

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

Funktion: msize-mlabel x l r

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

Funktion: msize-mtext x l r

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

Funktion: msize-mqapply x l r

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

Funktion: msize-mdef x l 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))))))

Funktion: msize-mplus x l 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))))))

Funktion: msize-mtimes x l r

Quelltext:

(defun msize-mtimes (x l r)
  (msznary x l r '(#\* )))

Funktion: msize-mexpt 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))

Funktion: msize-mcond x 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.

Funktion: msize-mdo x l r

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

Funktion: msize-mdoin x l r

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.