Im ersten Kapitel haben wir uns mit der Eingabe ganz einfacher
Rechenausdrücke auf der AutoCAD-Kommandozeile befasst, die
an AutoLisp weitergegeben und dort evaluiert werden.
Schön und gut, aber was wir bisher kennen, leistet jeder
Taschenrechner auch, den wir beim Kauf von 3 Paar Socken im
Kaffeeladen dazugeschenkt kriegen. Also gleich noch ein paar
weitere Funktionen, die man so ab und zu gebrauchen kann:
(sqrt 2) => 1.41421
; Zieht die Wurzel und lässt sich von
; Ganzzahlen nicht beeindrucken
(abs -3) => 3
; Gibt immer den Absolutwert (positiven
; Betrag) einer Zahl zurück
(cos pi) => -1
; (cos) arbeitet immer mit dem Bogenmass.
; pi ist in LISP vordefiniert und kann
; einfach so eingegeben werden.
(sin 1.234) => 0.94318
(exp 3) => 20.0855
; berechnet e hoch 3
(expt 10 3) => 1000
; Bedeutet 10 hoch 3
(expt 7 2) => 49
; Bedeutet 7 hoch 2 (bedeutet
; 7 zum Quadrat)
Auf die mathematischen Funktionen soll hier nicht allzusehr
eingegangen werden - sie sind einfach anzuwenden, aber teilweise
von der Mathematik her nicht so ganz einfach. Da dies aber
kein Mathe-Tutorial ist, wird in dieser Hinsicht also nur das
notwendigste behandelt.
An dieser Stelle können wir ganz unauffällig auch noch eine kleine
Neuerung einflechten: Ausdrücke können in LISP verschachtelt werden.
Ein Beispiel: wir wollen die dritte Wurzel aus 10 berechnen. Es gibt
dafür keine direkte Funktion (
sqrt berechnet nur die Quadratwurzel).
Wir müssen uns also mit der Ersatzkonstruktion 10 hoch (1/3) behelfen.
Dazu verschachteln wir ganz einfach:
(expt 10(/ 1 3)) => 1
; Die dritte Wurzel aus 10 soll
; 1 sein? Wo liegt der Fehler?
(expt 10(/ 1.0 3)) => 2.15443
; Das sieht doch schon wesentlich
; besser aus - nicht wahr?
(expt(expt 10(/ 1.0 3))3) => 3.0
; (Dritte Wurzel aus 10) hoch 3 = 3,
; so muss es sein. Schön aufpassen beim
; Eingeben, nicht vertippen, keine
; Leerstellen vergessen!
Und noch ein paar weitere Funktionen, die wir gar nicht
grossartig erklären müssen:
(min 5 7 13 1 4 2 13) => 1
; kleinstes Element
(max 5 7 13 1 4 2 13) => 13
; grösstes Element
(log 100) => 4.60517
; natürlicher Logarithmus von 100
(rem 50 7) => 1
; gibt nur den Rest wieder, der bei
; einer Ganzzahldivision übrigbleibt.
Wir haben nicht alle mathematischen Funktionen abgehandelt,
es sollte aber genügen, um sich den Umgang mit den restlichen
Rechenfunktion selbst anzueignen.
Nun noch ein paar Bemerkungen zu Reihenfolge, in der Ausdrücke
von LISP abgearbeitet werden: LISP evaluiert die Elemente eines
Ausdrucks im Prinzip von links nach rechts, d.h. in der Reihenfolge,
wie sie in der Klammer stehen. Liegt eine Verschachtelung vor, wird
immer in der innersten Ebene angefangen und nach aussen gearbeitet.
Die Kombination dieser beiden Richtungen ergibt die Reihenfolge.
Dazu ein paar Beispiele:
(*(+ 2 3)(- 6 2)) => 20
Zunächst wird die linke innere Klammer aufgelöst:
(+ 2 3) => 5.
Dann folgt die rechte innere Klammer:
(- 6 2) -> 4.
Erst jetzt kann der äussere Ausdruck evaluiert werden:
(* 5 4) -> 20.
Die Reihenfolge unterscheidet sich also nicht von der, die auch
ein Mensch beim Kopfrechnen anwendet (jedenfalls meistens).
(+(*(- 9 2)3)(*(-(* 3 4)2)3))
Das Ergebnis wir hier absichtlich nicht genannt, finden Sie
es selbst (Kopfrechnen!) heraus und überprüfen Sie es dann
mit LISP. Angefangen wir auf jeden Fall mit dem ersten
Argument für die Addition (Link-vor-Rechts), und da mit der
innersten Ebene (Innen-vor-Aussen), d.h. der Ausdruck (- 9 2)
wird als erstes berechnet.
Soweit also zu Ausdrücken in LISP und ihrer Eingabe in die
Kommandozeile. Wichtig sind folgende Sachverhalte, die wir
gelernt haben:
-
Ausdrücke, die von Lisp interpretiert werden sollen,
werden geklammert eingegeben.
-
Das erste Element in der Klammer muss die Funktion sein.
-
Nach dem Funktionsname kommen die Argumente.
-
Die Anzahl der Argumente hängt von der Funktion ab.
-
Manche Funktionen erforden eine bestimmte Anzahl von
Argumenten, andere können mit beliebig vielen Argumenten
aufgerufen werden.
-
Jedes Argument einer Funktion kann durch einen weiteren
Funktionsaufruf ersetzt werden (Verschachtelung) .
-
Beim Abarbeiten (Evaluieren) von Ausdrücken gilt erstens
die Links-vor-Rechts-Regel und zweitens die
Innen-nach-Aussen-Regel.
-
Beim Arbeiten mit der Funktion (/) muss sorgfältig zwischen
Ganzzahlen und Realzahlen unterschieden werden.
Übungsaufgaben
-
Nennen Sie ein Beispiel für eine Lisp-Rechenfunktion, die
beliebig viele Argumente erhalten kann.
-
Stellen Sie sich vor, Sie haben mit einer Zeichnung zu tun, die
in 12 x 12 Planquadrate unterteilt ist, welche von 0 (links unten)
bis 143 (rechts oben) durchnummeriert sind. Welche der hier
besprochenden Rechenfunktionen benötigen Sie, um herauszubekommen,
in welcher Spalte (vertikal!) ein bestimmtes Quadrat liegt?
-
Berechnen Sie in der Kommandozeile:
die dritte Wurzel aus 100
die vierte Wurzel aus 1000
die Zahl e
den Cosinus von pi/2
den Sinus von pi/4
den Sinus von 45°
den Cosinus von 30°
-
Welche der folgenden Eingaben verursachen eine Fehlermeldung?
(+(+))
(*(+ 3 4(- 6 3))6))((- 5 9)
(cos 30 45 60)
(+ pi pi)
(exp 100)
(expt 100)
-
Nennen Sie mindestens drei Beispiele für Lisp-Rechenfunktionen,
die immer nur ein Argument erhalten. Fallen Ihnen noch weitere
Funktionen ein, die es in Lisp wohl ebenso geben wird, die Sie
aber noch nicht kennen, und die auch nur ein Argument haben
können? Nennen Sie ausserdem drei Beispiele für Funktionen, die
mindestens zwei Argumente benötigen.
-
Beschreiben sie noch einmal die Unterschiede zwischen Infix-,
Präfix- und Postfix-Notation.
-
In welcher Reihenfolge bzw. Richtung werden die Bestandteile
verschachtelter Ausdrücke in AutoLisp evaluiert?
-
Wenn wir den Ausdruck (xyz 1 2 3) auf der Kommandozeile
eingeben und keine Fehlermeldung erhalten, was muss dann
xyz sein?
Lösungen